// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
use std::fs;
use std::path::Path;
use std::time::SystemTime;

use rand::RngCore;

pub trait Float: RngCore { // Slightly different implementation than the game, but that doesn't matter
	fn next_f32(&mut self) -> f32 {
		self.next_u32() as f32 / u32::MAX as f32
	}
}

impl<T: RngCore> Float for T {}

pub fn lerp(x0: f32, x1: f32, t: f32) -> f32 {
	x0 + (x1 - x0) * t
}

pub fn bilerp(x00: f32, x10: f32, x01: f32, x11: f32, tx: f32, ty: f32) -> f32 {
	lerp(lerp(x00, x10, tx), lerp(x01, x11, tx), ty)
}

pub fn smoothstep(t: f32) -> f32 {
	t * t * (3.0 - t * 2.0)
}

fn modified_time(path: &str) -> Option<SystemTime> {
	fs::metadata(path).ok().map(|m| m.modified().expect("Use a better OS"))
}

pub fn modified_time_input(path: &str) -> SystemTime {
	modified_time(path).expect("Input file doesn't exist")
}

pub fn modified_time_output(path: &str) -> SystemTime {
	modified_time(path).unwrap_or(SystemTime::UNIX_EPOCH)
}

// Checks if the input is newer than the output
// Panics if the input doesn't exist
pub fn newer(input: &str, output: &str) -> bool {
	modified_time_input(input) > modified_time_output(output)
}

pub fn exists(path: &str) -> bool {
	Path::new(path).exists()
}
