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

use super::waves::Waves;

const AMPLITUDE: f32 = 0.39375;
pub(super) const TIME: f32 = 0.125;
const FADE_IN: f32 = TIME / 32.0;

pub fn wave(t: f32, freq_mul: f32) -> f32 {
	let mut wave = 0.0;
	for i in 0..4u32 {
		let freq = 175.0 + (i as f32) * 4.0;
		let amplitude = 1.0 / (1 + i.pow(3)) as f32;
		let smoothness = 1.0 - 0.6875 / (i + 1) as f32;

		let beats = [freq, freq + 1.0];
		for f in beats {
			wave += (t * f * freq_mul * TAU).smooth_square(smoothness) * amplitude;
		}
	}
	wave
}

pub fn envelope(t: f32) -> f32 {
	let mut amplitude = (1.0 - t / TIME).powi(2); // Fade out
	amplitude *= 1.0 - (1.0 - (t / FADE_IN).min(1.0)).powi(2); // Fade in
	amplitude
}

pub fn generate() {
	super::generate("shot", TIME, AMPLITUDE, |t| wave(t, 1.0) * envelope(t));
}
