// 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::utils::maths::decay::Decay;
use crate::world::powerup::RADIUS;

pub struct Forcefield {
	pos: Vec2,
	size: f32,
	green: f32,
	r: f32,
	theta: f32,
	vel: f32,
	max_r: f32,
	rot_vel: f32,
	t: f32,
	max_time: f32,
}

impl Forcefield {
	pub fn new(pos: Vec2) -> Forcefield {
		let max_time = rand::random::<f32>() * 3.0 + 2.0;
		Forcefield {
			pos,
			size: (rand::random::<f32>() + 1.0) * 0.0234375,
			green: rand::random::<f32>() * 0.125 + 0.3125,
			r: rand::random::<f32>() * RADIUS,
			theta: rand::random::<f32>() * TAU,
			vel: rand::random::<f32>() * 0.75 + 1.0,
			max_r: rand::random::<f32>().powi(2) * 0.375 + 0.75,
			rot_vel: rand::random::<f32>() * 4.0 - 2.0,
			t: 1.0,
			max_time,
		}
	}
}

impl Particle for Forcefield {
	fn get_pos(&self) -> Vec2 {
		let (sin, cos) = self.theta.sin_cos();
		self.pos + self.r * Vec2::new(cos, sin)
	}

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

	fn update(&mut self, dt: f32) -> bool {
		self.r.decay_to(self.max_r, self.vel, dt);
		self.theta += self.rot_vel * dt;
		self.t -= dt / self.max_time;
		self.t >= 0.0
	}
}
