use super::{render::RenderError, window::Window};
use crate::arch::x86_64::drivers::framebuffer::colour::Colour;
use crate::std::maths::geometry::Vec2;
use alloc::{vec, vec::Vec};

pub struct Frame<'f> {
    data: Vec<Vec<Colour>>,
    window: &'f Window,
}

impl<'a> Frame<'a> {
    pub fn new(window: &'a Window) -> Self {
        Self {
            data: vec![
                vec![Colour::Black; window.dimensions().x()];
                window.dimensions().y()
            ],
            window,
        }
    }

    pub fn render(&self) -> Result<(), RenderError> {
        let data: Vec<&[Colour]> =
            self.data.iter().map(|v| v.as_slice()).collect::<Vec<_>>();
        self.window
            .render(data.as_slice())
            .map_err(|_| RenderError::Generic)
    }

    pub fn write_pixel(
        &mut self,
        x: usize,
        y: usize,
        color: Colour,
    ) -> Result<(), RenderError> {
        if x >= self.window.dimensions().x()
            || y >= self.window.dimensions().y()
        {
            return Err(RenderError::Generic);
        }
        self.data[y][x] = color;
        Ok(())
    }

    pub const fn dimensions(&self) -> Vec2<usize> {
        self.window.dimensions()
    }
}
