package types import ( "bytes" "fmt" "github.com/gammazero/deque" "lab.zaar.be/thefish/alchemyst-go/engine/ecs" "lab.zaar.be/thefish/alchemyst-go/util" ) import blt "lab.zaar.be/thefish/bearlibterminal" var crng = util.NewRNG() type ColorHolder interface { GetColor() uint32 } type cdeque struct { deque.Deque } func (c *cdeque) Next() uint8 { c.Rotate(1) return c.Front().(uint8) } type DanceColorHolder struct { A uint8 R *cdeque G *cdeque B *cdeque } func (dch DanceColorHolder) GetColor() uint32 { return blt.ColorFromARGB( dch.A, dch.R.Next(), dch.G.Next(), dch.B.Next(), ) } type PlainColorHolder struct { A uint8 R uint8 G uint8 B uint8 } func (chb PlainColorHolder) GetColor() uint32 { return blt.ColorFromARGB( chb.A, chb.R, chb.G, chb.B, ) } type TileColorSet struct { Fg ColorHolder `json:"fg"` Bg ColorHolder `json:"bg"` DarkFg ColorHolder `json:"darkfg"` DarkBg ColorHolder `json:"darkbg"` } type GlyphHolder interface { GetGlyph() string } type PlainGlyphHolder struct { Glyph string } func (pgh PlainGlyphHolder) GetGlyph() string { return pgh.Glyph } type Appearance struct { Glyph GlyphHolder `json:"glyph"` ColorSet TileColorSet `json:"colorSet"` } func SingleColorRing(colorValue uint8) *cdeque { c := &cdeque{} c.PushBack(colorValue) return c } func FillColorRing(colorValue uint8, minGlow, maxGlow, step int) *cdeque { q := make([]uint8, 0) color := int(colorValue) for color < maxGlow { q = append(q, uint8(color)) color = crng.Range(1, step) + color } color = crng.Range(0, step+minGlow) q = append(q, colorValue) //for uint8(color) < uint8(colorValue) { // q = append(q, uint8(color)) // color = crng.Range(1, step+minGlow) //} c := &cdeque{} for _, v := range q { c.PushBack(uint8(v)) } return c } func DeviatedColorRing(colorValue uint8, minGlow, maxGlow int) *cdeque { q := make([]uint8, 0) color := int(colorValue) color = crng.Range(minGlow, maxGlow) + color q = append(q, colorValue) c := &cdeque{} c.PushBack(uint8(color)) return c } func (app Appearance) Type() string { return ecs.AppearanceComponent } func (app *Appearance) MarshalJSON() ([]byte, error) { buffer := bytes.NewBufferString("{") //glyph buffer.WriteString(`"glyph":{`) if _, ok := app.Glyph.(*PlainGlyphHolder); ok { buffer.WriteString(fmt.Sprintf(`"type":"plain", "chars":"%s"`, app.Glyph.GetGlyph())) } buffer.WriteString("},") //color buffer.WriteString(`"color":{`) buffer.WriteString(getColorJson("fg", app.ColorSet.Fg) + ",") buffer.WriteString(getColorJson("bg", app.ColorSet.Bg) + ",") buffer.WriteString(getColorJson("darkfg", app.ColorSet.DarkFg) + ",") buffer.WriteString(getColorJson("darkbg", app.ColorSet.DarkBg)) buffer.WriteString("}") buffer.WriteString("}") fmt.Printf("\n\nbuffer: %s\n\n", buffer.String()) return buffer.Bytes(), nil } func (app *Appearance) UnmarshalJSON(buffer []byte) error { return nil } func getColorJson(field string, holder ColorHolder) string { result := "" if _, dch := holder.(*DanceColorHolder); dch { result = fmt.Sprintf(`{"dance":{`) result = result + detectRing("a", holder.(*DanceColorHolder).A) + "," result = result + detectRing("r", holder.(*DanceColorHolder).R) + "," result = result + detectRing("g", holder.(*DanceColorHolder).G) + "," result = result + detectRing("b", holder.(*DanceColorHolder).B) result = result + "}}" } if _, pch := holder.(*PlainColorHolder); pch { result = fmt.Sprintf(`{"plain":[%d,%d,%d,%d]}`, holder.(*PlainColorHolder).A, holder.(*PlainColorHolder).R, holder.(*PlainColorHolder).G, holder.(*PlainColorHolder).B, ) } return fmt.Sprintf(`"%s":%s`, field, result) } func detectRing(channel string, something interface{}) string { result := "" switch something.(type) { case (int),(uint8): result += fmt.Sprintf(`"%s":{"plain":%d}`, channel, something) case (*cdeque): fmt.Printf("%v", something) if something.(*cdeque).Len() == 1 { //fixme right now we can not distinct plain and deviated result += fmt.Sprintf(`"%s":{"single":[%v]}`, channel, something.(*cdeque).Front()) } else { result += fmt.Sprintf(`"%s":{"fill":[%v, %v, %v, %v]}`, channel, something.(*cdeque).Front(), something.(*cdeque).Next(), something.(*cdeque).Next(), something.(*cdeque).Next(), ) } } return result }