// 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 = 1.5;
const FADE: f32 = TIME / 64.0;

const NOTE_FADE_IN: f32 = 0.0625;

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

pub fn generate() {
	super::generate("game_win", TIME, AMPLITUDE, |t| {
		let (i, s) = {
			let t = t / TIME;
			let s = t * (1.0 + 0.25 * t) * (45.0 / 1.25) as f32;
			let i = s.floor();
			(i as usize, s - i)
		};

		let note_freq = (600.0 + i as f32 * 20.0) * (1.0 + 0.625 * (i % 3) as f32);

		let mut wave = 0.0;
		for i in 0..4 {
			let freq = note_freq * (i + 1) as f32;
			let amplitude = (1.0 - s).powf(i as f32 * 0.5) / (i as f32 + 1.0).powi(3);
			wave += (t * freq * TAU).smooth_square(0.5) * amplitude;
		}

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