// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
use std::f32::consts::TAU;

use glam::{Vec2, Vec4};

use super::super::Particle;

use crate::world::powerup::RADIUS;

pub struct Speed {
	p0: Vec2, p1: Vec2, p2: Vec2,
	size: f32,
	speed: f32,
	red: f32,
	t: f32,
}

impl Speed {
	pub fn new(mut pos: Vec2) -> Speed {
		let dir = Vec2::from_angle(rand::random::<f32>() * TAU);
		pos += dir * rand::random::<f32>() * RADIUS;
		let ext = dir * rand::random::<f32>();
		let off = dir.perp() * (rand::random::<f32>() * 1.5 - 0.75);
		Speed {
			p0: pos,
			p1: pos + ext + off,
			p2: pos + ext - off,
			size: (rand::random::<f32>() + 1.0) * 0.03125,
			speed: rand::random::<f32>() * 2.0 + 1.0,
			red: rand::random::<f32>() * 0.125 + 0.1875,
			t: 0.0,
		}
	}
}

impl Particle for Speed {
	// Calculates the cubic Bézier curve with points [p0, p1, p2, p0].
	fn get_pos(&self) -> Vec2 {
		let s = 1.0 - self.t;
		let common = 3.0 * s * self.t;
		(1.0 - common) * self.p0 + common * (s * self.p1 + self.t * self.p2)
	}

	fn get_size(&self) -> f32 { self.size }
	fn get_colour(&self) -> Vec4 { Vec4::new(self.red, 0.5, 0.125, 1.0 - self.t) }

	fn update(&mut self, dt: f32) -> bool {
		self.t += dt * self.speed;
		self.t <= 1.0
	}
}
