use ratatui::prelude::*;
use ratatui::{layout::Rect, style::Style, widgets::Widget};

use crate::constants::CHIP8_VIDEO_MEMORY;


#[derive(Clone, Copy)]
pub struct Chip8Video {
    memory: [bool; CHIP8_VIDEO_MEMORY]
}

impl Chip8Video {
    pub fn new(initial_configuration: [bool; CHIP8_VIDEO_MEMORY]) -> Self {
        Self {
            memory: initial_configuration
        }
    }

    pub fn peek(self, address: u16) -> bool {
        self.memory[address as usize]
    }

    pub fn poke(mut self, address: u16, new_value: bool) -> Self {
        self.memory[address as usize] = new_value;
        self
    }

    pub fn format_as_string(self) -> String {
        let mut output = String::new();
        for row in 0..32 {
            let row_offset = row * 32;
            for column in 0..64 {
                let data_position = row_offset + column;
                println!("DP  {} {} {} {}", data_position, row, row_offset, column);
                output += if self.memory[data_position] {
                    "*"
                } else {
                    " "
                };
            }
            output += "\n";
        }
        panic!("{}", output);
        output    
    }

    pub fn dump_to_console(self) {
        println!("{}", self.format_as_string());
    }
}

impl Default for Chip8Video {
    fn default() -> Self {
        Self { memory: [false; CHIP8_VIDEO_MEMORY as usize] }
    }
}

impl Widget for Chip8Video {
    fn render(self, area: Rect, buf: &mut ratatui::prelude::Buffer)
    where
        Self: Sized {
            println!("STARTING TO RENDER VIDEO!");
            let style = Style::new().on_cyan();
            buf.set_string(0, 0, self.format_as_string(), style)
    }
}
