// 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.5;
const TIME: f32 = 0.375;
const FADE: f32 = TIME / 32.0;

const NOTE_COUNT: usize = 3;
const NOTE_TIME: f32 = TIME / NOTE_COUNT as f32 * 1.5;
const NOTE_FADE_IN: f32 = 0.0625;

fn envelope(t: f32) -> f32 {
	let mut amplitude = 1.0;
	amplitude *= 1.0 - (1.0 - (t / NOTE_FADE_IN).min(1.0)).powi(2); // Fade in
	amplitude *= 1.0 - t;
	amplitude.max(0.0)
}

pub fn generate() {
	super::generate("speed", TIME, AMPLITUDE, |t| {
		let mut wave = 0.0;
		for i in 0..NOTE_COUNT {
			let centre = (i as f32 + 0.5) / NOTE_COUNT as f32 * TIME;
			let freq = 600.0 * 2.0f32.powf(i as f32 * 0.5);

			for i in 0..4u32 {
				let freq = freq * (i + 1) as f32;
				let fade = envelope((t - centre) / NOTE_TIME + 0.5);
				let amplitude = fade.powf(1.0 + i as f32 * 0.875) / (i + 1).pow(3) as f32;
				wave += (t * freq * TAU).smooth_square(1.0 - 1.0 / (i as f32 * 1.5 + 3.0)) * amplitude;
			}
		}

		let mut amplitude = 1.0 - (1.0 - (t / FADE).min(1.0)).powi(2); // Fade in
		amplitude *= 1.0 - (1.0 - ((TIME - t) / FADE).min(1.0)).powi(2); // Fade out
		wave * amplitude
	});
}
