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 ParticleSystem struct {
	World    *ecs.World
	Selector *generic.Filter3[Position, Particle, Timer]
	Cellsize int
}

func NewParticleSystem(world *ecs.World, cellsize int) System {
	system := &ParticleSystem{
		Selector: generic.NewFilter3[Position, Particle, Timer](),
		World:    world,
		Cellsize: cellsize,
	}

	return system
}

func (system *ParticleSystem) Update() error {
	// display debris after collecting
	EntitiesToRemove := []ecs.Entity{}

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

	for query.Next() {
		// we loop, but it's only one anyway
		_, particle, timer := query.Get()

		particle.Show = true

		if timer.IsReady() {
			switch {
			// particle shows from earlier tick, animate
			case particle.Index > -1 && particle.Index < len(particle.Tiles)-1:
				particle.Index++
				timer.Start(config.PARTICLE_LOOPWAIT)
			default:
				// last sprite reached, remove it
				EntitiesToRemove = append(EntitiesToRemove, query.Entity())
			}
		} else {
			timer.Update()
		}

	}

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

	return nil
}

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

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

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