package projectile

import (
	"image/color"

	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/vector"
)

// Projectile configuration

type ProjectileConfig struct {
	Speed  float64
	Radius float64
	Color  color.NRGBA
}

type Projectile struct {
	X         float64
	Y         float64
	VelocityX float64
	VelocityY float64
	Radius    float64
	Color     color.NRGBA
	Active    bool
}

func New(x, y, directionX, directionY float64, config ProjectileConfig) *Projectile {
	return &Projectile{
		X:         x,
		Y:         y,
		VelocityX: directionX * config.Speed,
		VelocityY: directionY * config.Speed,
		Radius:    config.Radius,
		Color:     config.Color,
		Active:    true,
	}
}

func (p *Projectile) Update(dt float64, screenWidth, screenHeight float64) {
	if dt > 0.1 {
		dt = 0.1
	}

	p.X += p.VelocityX * dt
	p.Y += p.VelocityY * dt

	margin := p.Radius * 2
	if p.X < -margin || p.X > screenWidth+margin || p.Y < -margin || p.Y > screenHeight+margin {
		p.Active = false
	}
}

func (p *Projectile) Draw(screen *ebiten.Image) {
	if !p.Active {
		return
	}

	drawX := float32(int(p.X + 0.5))
	drawY := float32(int(p.Y + 0.5))

	vector.DrawFilledCircle(
		screen,
		drawX,
		drawY,
		float32(p.Radius),
		p.Color,
		true,
	)
}

// Projectile manager

type Manager struct {
	Projectiles []*Projectile
}

func NewManager() *Manager {
	return &Manager{
		Projectiles: make([]*Projectile, 0),
	}
}

func (m *Manager) Shoot(x, y, directionX float64, config ProjectileConfig) {
	p := New(x, y, directionX, 0, config)
	m.Projectiles = append(m.Projectiles, p)
}

func (m *Manager) Update(dt float64, screenWidth, screenHeight float64) {
	for i := len(m.Projectiles) - 1; i >= 0; i-- {
		p := m.Projectiles[i]
		p.Update(dt, screenWidth, screenHeight)

		if !p.Active {
			m.Projectiles = append(m.Projectiles[:i], m.Projectiles[i+1:]...)
		}
	}
}

func (m *Manager) Draw(screen *ebiten.Image) {
	for _, p := range m.Projectiles {
		p.Draw(screen)
	}
}

func (m *Manager) Clear() {
	m.Projectiles = make([]*Projectile, 0)
}
