// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
use glam::{Vec2, Vec4};

use super::Particle;

use crate::world::bullet::RADIUS as BULLET_RADIUS;

const TIME: f32 = 0.125;

pub struct ForcefieldDeflection {
	pos: Vec2,
	vel: Vec2,
	acc: Vec2,
	time: f32,
	r: f32,
	g: f32,
	a: f32,
	size: f32,
}

impl ForcefieldDeflection {
	pub fn new(bullet_pos: Vec2, bullet_dir: Vec2, mut strength: f32) -> ForcefieldDeflection {
		strength += 0.5;
		let speed = rand::random::<f32>() * 2.0 / TIME * strength;

		let dir = -bullet_dir.rotate(Vec2::from_angle(rand::random::<f32>() * 0.25 - 0.125));
		let vel = dir * speed;
		let pos = bullet_pos + (rand::random::<Vec2>() - 0.5) * BULLET_RADIUS;

		let acc = Vec2::new(bullet_dir.y, -bullet_dir.x) * (rand::random::<f32>() * 2.0 - 1.0) * 24.0 / TIME * strength;

		let g = rand::random::<f32>() * 0.25 + 0.375;
		let r = g * rand::random::<f32>() * 0.5;
		let a = 1.0 - rand::random::<f32>().powi(2);
		let size = rand::random::<f32>() * 0.0625 + 0.125;

		ForcefieldDeflection { pos, vel, acc, time: TIME, r, g, a, size }
	}
}

impl Particle for ForcefieldDeflection {
	fn get_pos(&self) -> Vec2 { self.pos }
	fn get_size(&self) -> f32 { self.size }
	fn get_colour(&self) -> Vec4 { Vec4::new(self.r, self.g, 1.0, self.time / TIME * self.a) }

	fn update(&mut self, dt: f32) -> bool {
		self.vel += self.acc * dt;
		self.pos += self.vel * dt;
		self.time -= dt;
		self.time >= 0.0
	}
}
