package letter

import (
	"embed"
	"encoding/csv"
	"image"
	"image/color"
	"image/draw"
	"io"

	"git.niplace.ru/XoxJlopeZi4BB/imageutils"
)

type Letter string

//go:embed map.csv
var fs embed.FS
var mapFile = func() io.Reader {
	f, err := fs.Open("map.csv")
	if err != nil {
		panic(err)
	}
	return f
}()

var Letters = func(r io.Reader) (m map[string]string) {
	records, err := csv.NewReader(r).ReadAll()
	if err != nil {
		panic(err)
	}
	for _, v := range records {
		if len(v) < 2 {
			panic("csv file isn's key-value pair")
		}
		m[v[0]] = v[1]
	}
	return m
}(mapFile)

// implements image.Image interface.
func (l Letter) ColorModel() color.Model {
	return color.Alpha16Model
}

// implements image.Image interface.
func (l Letter) Bounds() image.Rectangle {
	return image.Rect(0, 0, 3, 3)
}

// implements image.Image interface.
func (l Letter) At(x, y int) color.Color {
	if len(l) != 9 {
		panic("len(Letter) != 9")
	}
	target := l[x+y*3]
	if target != '1' {
		return color.Opaque
	}
	return color.Transparent
}

func Render(l Letter) image.Image {
	img := image.NewRGBA(l.Bounds())
	draw.Draw(img, l.Bounds(), image.White, image.ZP, draw.Src)
	draw.Draw(img, l.Bounds(), l, image.ZP, draw.Over)
	return img
}

type blank struct {
	image.Image
	color.Color
	imageutils.Side
}

func (b blank) ColorModel() color.Model { return b.Image.ColorModel() }

func (b blank) Bounds() image.Rectangle {
	rect := image.Rectangle{}
	switch b.Side {
	case imageutils.Left:
		fallthrough
	case imageutils.Right:
		rect = image.Rectangle{
			image.ZP,
			image.Point{
				1, b.Image.Bounds().Dy(),
			},
		}
	case imageutils.Up:
		fallthrough
	case imageutils.Down:
		rect = image.Rectangle{
			image.ZP,
			image.Point{
				b.Image.Bounds().Dx(), 1,
			},
		}
	}
	return rect
}

func (b blank) At(x, y int) color.Color { return b.Color }

func Blank(img image.Image, clr color.Color, side imageutils.Side) image.Image {
	return imageutils.Concat(img, blank{img, clr, side}, side)
}
