use crate::color::Color;

/// Interp color
pub fn color_interp(
    start: Color,
    end: Color,
    time: f32,
    duration: f32,
    easing: fn(f32) -> f32,
) -> Color {
    let wave = time % duration;
    let wave = if ((time / duration) as u32).is_multiple_of(2) {
        wave
    } else {
        1.0 - wave
    };

    let t = easing(wave.clamp(0.0, 1.0));

    let sr = start.r;
    let sg = start.g;
    let sb = start.b;
    let sa = start.a;

    let er = end.r;
    let eg = end.g;
    let eb = end.b;
    let ea = end.a;

    Color {
        r: (sr + (er - sr) * t).round(),
        g: (sg + (eg - sg) * t).round(),
        b: (sb + (eb - sb) * t).round(),
        a: (sa + (ea - sa) * t).round(),
    }
}

pub fn ease_in_out_quad(t: f32) -> f32 {
    if t < 0.5 {
        2.0 * t * t
    } else {
        let ft = t * 2.0 - 1.0;
        1.0 - ft * ft / 2.0
    }
}

pub fn ease_out_elastic(t: f32) -> f32 {
    let c4 = (2.0 * std::f32::consts::PI) / 3.0;
    if t == 0.0 {
        0.0
    } else if t == 1.0 {
        1.0
    } else {
        2.0_f32.powf(-10.0 * t) * ((t * 10.0 - 0.75) * c4).sin() + 1.0
    }
}

pub fn ease_out_expo(t: f32) -> f32 {
    if t >= 1.0 {
        1.0
    } else {
        1.0 - 2.0_f32.powf(-10.0 * t)
    }
}
