package gfx

import (
	"image"
	"image/color"
	"image/gif"
	"io"
	"math"
	"math/rand"
)

func CreateLissajous(out io.Writer) {

	var palette = []color.Color{color.White, color.Black, color.RGBA{0xff, 0x00, 0x00, 0xff}, color.RGBA{0xff, 0x00, 0xff, 0xff}, color.RGBA{0x00, 0x00, 0xff, 0xff}}

	const (
		whiteIdx = 0
		blackIdx = 1
	)

	const (
		size      = 100 // [-size, size]
		nframes   = 32
		delay     = 5
		res       = 0.001
		cycles    = 5
		authentic = true
		colorFun  = true
	)

	if authentic { // Exercise 1.5
		palette[0] = color.RGBA{0, 0, 0, 1}
		palette[1] = color.RGBA{0, 255, 0, 1}
	}

	// Note: A LoopCount of 0 means to loop forever;
	// cf. https://pkg.go.dev/image/gif#GIF
	anim := gif.GIF{}
	phase := 0.0
	freq := rand.Float64() * 3.0 // rel freq
	for i := 0; i < nframes; i++ {
		rect := image.Rect(0, 0, 2*size+1, 2*size+1)
		img := image.NewPaletted(rect, palette)
		for t := 0.0; t <= cycles*2*math.Pi; t += res {
			x := math.Sin(t)
			y := math.Sin(t*freq + phase)
			var clrIdx uint8 = blackIdx
			if colorFun {
				dist := math.Sqrt(x*x + y*y)
				clrIdx = 1 + uint8(dist*5)%uint8(len(palette)-1)
			}
			img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), clrIdx)
		}
		phase += 0.1
		anim.Delay = append(anim.Delay, delay)
		anim.Image = append(anim.Image, img)
	}
	gif.EncodeAll(out, &anim)
}
