use std::time::Duration;

use palette::{Hsl, IntoColor, Pixel, Srgb};
use sdl2::{pixels::Color, rect::Rect};

use crate::layers::OutputLayer;

pub struct HSLCycle {
    cycle_millis: usize,
    time: usize,
    rgb: [u8; 3],
}

impl HSLCycle {
    pub fn new(cycle_length: Duration) -> Self {
        Self {
            cycle_millis: cycle_length.as_millis() as usize,
            time: 0,
            rgb: [0, 0, 0],
        }
    }
}

impl OutputLayer for HSLCycle {
    fn tick(&mut self, dt: std::time::Duration) {
        self.time += dt.as_millis() as usize;
        self.time %= self.cycle_millis;

        let hsl: Srgb = Hsl::new(
            360.0 * (self.time as f32 / self.cycle_millis as f32),
            1.0,
            0.5,
        )
        .into_color();

        self.rgb = hsl.into_format().into_raw();
    }

    fn draw_sdl(&self, canvas: &mut sdl2::render::Canvas<sdl2::video::Window>, _texture_size: u32) {
        let [r, g, b] = self.rgb;
        canvas.set_draw_color(Color::RGB(r, g, b));
        canvas.fill_rect(Rect::new(0, 0, 5, 5)).unwrap();
    }

    fn on_sdl_event(&mut self, _event: &sdl2::event::Event) {}

    fn update_dmx(&self, output: &mut [crate::fixtures::MovingHead; 4]) {
        let [r, g, b] = self.rgb;
        for head in output.iter_mut() {
            head.rgbw = (r, g, b, 0);
        }
    }
}
