// use super::{IoAccess, IoHandle};
use crate::{MemoryBank, Page, backend::memory::PhysAddr};

pub struct Display {
    width: usize,
    height: usize,
    addr: PhysAddr,

    mem: MemoryBank,
    buffer: Vec<u8>,
    visible: bool,
}

impl Display {
    pub fn new(width: u32, height: u32, addr: PhysAddr, mem: MemoryBank) -> Self {
        Self {
            width: width as usize,
            height: height as usize,
            addr,
            mem,
            buffer: Vec::new(),
            visible: true,
        }
    }

    pub fn visible(&mut self) -> &mut bool {
        &mut self.visible
    }

    pub fn width(&self) -> usize {
        self.width
    }

    pub fn height(&self) -> usize {
        self.height
    }

    fn internal_read(&self) -> Vec<u8> {
        let pages = (0..((self.width * self.height).div_ceil(Page::SIZE)))
            .map(|i| {
                let page = self.mem.read_page(self.addr + i as u32 * 4096);
                page.as_slice().to_owned()
            })
            .flatten()
            .take((self.width * self.height) as usize)
            .collect::<Vec<u8>>();
        pages
    }

    pub fn changed(&mut self) -> bool {
        let temp = self.internal_read();
        if temp != self.buffer {
            self.buffer = temp;
            return true;
        }
        false
    }

    pub fn read(&mut self) -> Vec<u8> {
        self.internal_read()
    }
}
