package systems

import (
	. "openquell/components"
	"openquell/config"

	"github.com/hajimehoshi/ebiten/v2"
	"github.com/mlange-42/arche/ecs"
	"github.com/mlange-42/arche/generic"
)

type AnimationSystem struct {
	World    *ecs.World
	Selector *generic.Filter2[Position, Renderable]
	Cellsize int
}

func NewAnimationSystem(world *ecs.World, cellsize int) System {
	system := &AnimationSystem{
		Selector: generic.NewFilter2[Position, Renderable](),
		World:    world,
		Cellsize: cellsize,
	}

	return system
}

func (system *AnimationSystem) Update() error {
	EntitiesToRemove := []ecs.Entity{}

	query := system.Selector.Query(system.World)

	for query.Next() {
		_, render := query.Get()
		if render.Animate.Active {
			if render.Animate.Timer.IsReady() {
				switch {
				// animation shows from earlier tick, animate
				case render.Animate.Index > -1 && render.Animate.Index < len(render.Animate.Tiles)-1:
					render.Animate.Index += 1
					render.Animate.Timer.Start(config.ANIMATION_LOOPWAIT)
				default:
					// last sprite reached
					if render.Animate.Loop {
						render.Animate.Index = 0
					} else {
						EntitiesToRemove = append(EntitiesToRemove, query.Entity())
					}
				}
			} else {
				render.Animate.Timer.Update()
			}
		}
	}

	for _, entity := range EntitiesToRemove {
		system.World.RemoveEntity(entity)
	}

	return nil
}

func (system *AnimationSystem) Draw(screen *ebiten.Image) {
	// write animations (these are no tiles!)
	op := &ebiten.DrawImageOptions{}
	query := system.Selector.Query(system.World)

	for query.Next() {
		pos, render := query.Get()

		if render.Animate.Active {
			op.GeoM.Reset()
			op.GeoM.Translate(float64(pos.X), float64(pos.Y))
			screen.DrawImage(render.Animate.Tiles[render.Animate.Index], op)
		}
	}
}
