package entities

import (
	"git.solsynth.dev/highland/codingland/pkg/internal/land"
	"github.com/veandco/go-sdl2/sdl"
)

const (
	Acceleration = 0.5
	Friction     = 0.9
)

type Player struct {
	land.BaseObject

	Position land.Vector2D
	Size     land.Vector2D
	Velocity land.Vector2D
}

func (p *Player) Update() {
	if !p.Velocity.IsZero() {
		p.SlideByVelocity()
	}

	keys := sdl.GetKeyboardState()
	if keys[sdl.SCANCODE_UP] == 1 || keys[sdl.SCANCODE_W] == 1 {
		p.Move(0, -1)
	}
	if keys[sdl.SCANCODE_DOWN] == 1 || keys[sdl.SCANCODE_S] == 1 {
		p.Move(0, 1)
	}
	if keys[sdl.SCANCODE_LEFT] == 1 || keys[sdl.SCANCODE_A] == 1 {
		p.Move(-1, 0)
	}
	if keys[sdl.SCANCODE_RIGHT] == 1 || keys[sdl.SCANCODE_D] == 1 {
		p.Move(1, 0)
	}
}

func (p *Player) Move(deltaX, deltaY float64) {
	p.Velocity.X += deltaX * Acceleration
	p.Velocity.Y += deltaY * Acceleration
}

func (p *Player) SlideByVelocity() {
	p.Position.X += p.Velocity.X
	p.Position.Y += p.Velocity.Y

	p.Velocity.X *= Friction
	p.Velocity.Y *= Friction
}

func (p *Player) Draw(pen *sdl.Renderer) {
	pen.SetDrawColor(255, 255, 255, 255)
	pen.FillRect(&sdl.Rect{
		X: int32(p.Position.X),
		Y: int32(p.Position.Y),
		W: int32(p.Size.X),
		H: int32(p.Size.Y),
	})

	for _, child := range p.Children {
		if drawableChild, ok := child.(land.DrawableObject); ok {
			drawableChild.Draw(pen)
		}
	}
}

func (p *Player) GetPosition() land.Vector2D {
	return p.Position
}

func (p *Player) GetSize() land.Vector2D {
	return p.Size
}

func (p *Player) OnCollide(other land.CollidableObject) {
	if p.Position.X < other.GetPosition().X {
		p.Position.X = other.GetPosition().X - p.Size.X
		p.Velocity.X = 0
	} else if p.Position.X > other.GetPosition().X {
		p.Position.X = other.GetPosition().X + other.GetSize().X
		p.Velocity.X = 0
	}

	if p.Position.Y < other.GetPosition().Y {
		p.Position.Y = other.GetPosition().Y - p.Size.Y
		p.Velocity.Y = 0
	} else if p.Position.Y > other.GetPosition().Y {
		p.Position.Y = other.GetPosition().Y + other.GetSize().Y
		p.Velocity.Y = 0
	}
}
