use glium::RawUniformValue::Vec2;
use imgui::sys::ImColor;
use imgui::{ImColor32, Ui};
use ratatui::{style::Style, widgets::Widget};

use crate::constants::{CHIP8_MEMORY_SIZE, CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_WIDTH};

pub const CHIP8FONT_0: [u8; 5] = [0xF0, 0x90, 0x90, 0x90, 0xF0];
pub const CHIP8FONT_1: [u8; 5] = [0x20, 0x60, 0x20, 0x20, 0x70];
pub const CHIP8FONT_2: [u8; 5] = [0xF0, 0x10, 0xF0, 0x80, 0xF0];
pub const CHIP8FONT_3: [u8; 5] = [0xF0, 0x10, 0xF0, 0x10, 0xF0];
pub const CHIP8FONT_4: [u8; 5] = [0x90, 0x90, 0xF0, 0x10, 0x10];
pub const CHIP8FONT_5: [u8; 5] = [0xF0, 0x80, 0xF0, 0x10, 0xF0];
pub const CHIP8FONT_6: [u8; 5] = [0xF0, 0x80, 0xF0, 0x90, 0xF0];
pub const CHIP8FONT_7: [u8; 5] = [0xF0, 0x10, 0x20, 0x40, 0x40];
pub const CHIP8FONT_8: [u8; 5] = [0xF0, 0x90, 0xF0, 0x90, 0xF0];
pub const CHIP8FONT_9: [u8; 5] = [0xF0, 0x90, 0xF0, 0x10, 0xF0];
pub const CHIP8FONT_A: [u8; 5] = [0xF0, 0x90, 0xF0, 0x90, 0x90];
pub const CHIP8FONT_B: [u8; 5] = [0xE0, 0x90, 0xE0, 0x90, 0xE0];
pub const CHIP8FONT_C: [u8; 5] = [0xF0, 0x80, 0x80, 0x80, 0xF0];
pub const CHIP8FONT_D: [u8; 5] = [0xE0, 0x90, 0x90, 0x90, 0xE0];
pub const CHIP8FONT_E: [u8; 5] = [0xF0, 0x80, 0xF0, 0x80, 0xF0];
pub const CHIP8FONT_F: [u8; 5] = [0xF0, 0x80, 0xF0, 0x80, 0x80];

#[derive(Clone, Copy)]
pub struct Chip8SystemMemory {
    memory: [u8; CHIP8_MEMORY_SIZE as usize],
}

impl Default for Chip8SystemMemory {
    fn default() -> Self {
        Self {
            memory: Chip8SystemMemory::load_to_memory([0x00; CHIP8_MEMORY_SIZE as usize]),
        }
    }
}

impl Widget for Chip8SystemMemory {
    fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer)
    where
        Self: Sized,
    {
        // build the text version of the system memory...
        // ...and stuff it in the display.
        let style = Style::new();
        let string = String::new();
        buf.set_string(0, 0, string, style)
    }
    // Display the system memory as a widget
}

const cell_width: i32 = 5i32;
const cell_height: i32 = 5i32;

impl Chip8SystemMemory {
    pub fn gui_render(self, ui: &Ui) {
    }

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

    pub fn poke(mut self, address: u16, value: u8) -> Chip8SystemMemory {
        self.memory[address as usize] = value;
        self
    }

    pub fn load_to_memory(
        to_load_into: [u8; CHIP8_MEMORY_SIZE as usize],
    ) -> [u8; CHIP8_MEMORY_SIZE as usize] {
        let mut working = to_load_into.clone();
        let all_font_characters = [
            CHIP8FONT_0,
            CHIP8FONT_1,
            CHIP8FONT_2,
            CHIP8FONT_3,
            CHIP8FONT_4,
            CHIP8FONT_5,
            CHIP8FONT_6,
            CHIP8FONT_7,
            CHIP8FONT_8,
            CHIP8FONT_9,
            CHIP8FONT_A,
            CHIP8FONT_B,
            CHIP8FONT_C,
            CHIP8FONT_D,
            CHIP8FONT_E,
            CHIP8FONT_F,
        ];

        for (font_index, current_font) in all_font_characters.iter().enumerate() {
            for font_mem_offset in 0..=4 {
                let real_offset = font_index * 5 + font_mem_offset;
                working[real_offset] = current_font[font_mem_offset];
            }
        }
        println!("__FINISHED LOADING FONTS__");
        working
    }
}
