use std::default::Default;
use std::fs::DirEntry;
use std::time::Instant;
use gemmaemu::{
    chip8::computer::Chip8Computer,
    constants::{CHIP8_MEMORY_SIZE, CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_WIDTH},
};
use imgui::*;
use ratatui::symbols::half_block;
use sys::{ImColor, ImVec2, ImVector_ImU32};
use rand::random;
use gemmaemu::chip8::system_memory::Chip8SystemMemory;
use support::emmagui_support::EmmaGui;
mod support;


struct UiState {
    pub show_registers: bool,
    pub show_memory: bool,
    pub show_video: bool,
    pub filename_to_load: String,
   pub on_colour: ImColor32,
   pub off_colour: ImColor32,
    pub is_running: bool,
    pub frame_time: f32
}

impl Clone for UiState {
    fn clone(&self) -> Self {
        UiState {
            show_registers: self.show_registers,
            show_memory: self.show_memory,
            show_video: self.show_video,
            filename_to_load: self.filename_to_load.to_string(),
            on_colour: self.on_colour,
            off_colour: self.off_colour,
            is_running: self.is_running,
            frame_time: self.frame_time
        }
    }
}

impl Default for UiState {
    fn default() -> Self {
        UiState {
            show_registers: false,
            show_memory: false,
            show_video: true,
            filename_to_load: String::new(),
            on_colour: ImColor32::from_rgb(0xff, 0xff, 0x00),
            off_colour: ImColor32::from_rgb(0x00, 0xff, 0xff),
            is_running: false,
            frame_time: 32.0
        }
    }
}

fn main() {
    pretty_env_logger::init();
    let mut system = Chip8Computer::default();
    let mut ui_state = UiState::default();
    let mut last_tick_time = Instant::now();

    support::simple_init(file!(), move |_, ui| {
        let current_time = Instant::now();
        let time_since_last_tick = current_time.duration_since(last_tick_time).as_millis();
        if ui_state.is_running && time_since_last_tick > ui_state.frame_time as u128 {
            system.step_system();
            last_tick_time = current_time;
        }

        EmmaGui::system_controls(&mut system, &mut ui_state, ui);

        if ui_state.show_registers {
            EmmaGui::registers_view(&system, ui);
        }

        if ui_state.show_video {
            EmmaGui::video_display(&system, &ui_state, ui);
        }

        if ui_state.show_memory {
            let active_instruction = system.registers.peek_pc();
            EmmaGui::hex_memory_display(system.memory.clone(), (0x100, 0x10), active_instruction as i16, ui);
        }
    });
}
