package identicon

import (
	"git.mstar.dev/mstar/canvas"
	mathutils "git.mstar.dev/mstar/goutils/math"
)

type vec2 struct {
	X, Y float64
}

type block struct {
	canvas    *canvas.Canvas
	blockType int
	primary   string
	secondary string
	hash      int
	pos       vec2
	cellSize  int
	margin    int
	scale     float64
}

func (b *block) Offset() {
	b.canvas.Save()
	b.canvas.Translate(0.6*b.scale, -0.6*b.scale)
}

func (b *block) ResetOffset() {
	b.canvas.Restore()
}

func (b *block) MakePath(hash int, offset int) {
	mod := mathutils.Abs(hash+offset) % 4
	switch mod {
	case 0:
		// Top
		b.canvas.BeginPath()
		b.canvas.MoveTo(float64(b.pos.X), float64(b.pos.Y))
		b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), float64(b.pos.Y))
		b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), b.pos.Y+float64(int(b.cellSize)))
		b.canvas.ClosePath()
	case 1:
		// Right
		b.canvas.BeginPath()
		b.canvas.MoveTo(b.pos.X+float64(int(b.cellSize)), float64(b.pos.Y))
		b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), b.pos.Y+float64(int(b.cellSize)))
		b.canvas.LineTo(float64(b.pos.X), b.pos.Y+float64(int(b.cellSize)))
		b.canvas.ClosePath()
	case 2:
		// Bottom
		b.canvas.BeginPath()
		b.canvas.MoveTo(float64(b.pos.X), float64(b.pos.Y))
		b.canvas.LineTo(float64(b.pos.X), b.pos.Y+float64(int(b.cellSize)))
		b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), b.pos.Y+float64(int(b.cellSize)))
		b.canvas.ClosePath()
	case 3:
		// Left
		b.canvas.BeginPath()
		b.canvas.MoveTo(float64(b.pos.X), float64(b.pos.Y))
		b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), float64(b.pos.Y))
		b.canvas.LineTo(float64(b.pos.X), b.pos.Y+float64(int(b.cellSize)))
		b.canvas.ClosePath()
	default:
		// Top
		b.canvas.BeginPath()
		b.canvas.MoveTo(float64(b.pos.X), float64(b.pos.Y))
		b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), float64(b.pos.Y))
		b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), b.pos.Y+float64(int(b.cellSize)))
		b.canvas.ClosePath()
	}
}

func (b *block) Draw() {
	b.Offset()
	switch b.blockType {
	case 1:
		b.MakePath(b.hash, b.hash%3)
		b.canvas.SetFillStyle(b.primary)
		b.canvas.Fill()
		b.MakePath(b.hash, b.hash%5)
		b.canvas.SetFillStyle(b.secondary)
		b.canvas.Fill()
	case 2:
		b.MakePath(b.hash, b.hash%4)
		b.canvas.SetFillStyle(b.secondary)
		b.canvas.Fill()
		b.MakePath(b.hash, b.hash%3)
		b.canvas.SetFillStyle(b.primary)
		b.canvas.Fill()
	default:
		b.MakePath(b.hash, b.hash%7)
		b.canvas.SetFillStyle(b.secondary)
		b.canvas.Fill()
		b.MakePath(b.hash, b.hash%8)
		b.canvas.SetFillStyle(b.primary)
		b.canvas.Fill()
	}
	b.ResetOffset()
}
