use std::default::Default;
use std::fs::DirEntry;
use std::time::Instant;
use gemma::{
    chip8::computer::Chip8Computer,
    constants::{CHIP8_MEMORY_SIZE, CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_WIDTH},
};
use imgui::*;
use sys::{ImColor, ImVec2, ImVector_ImU32};
use rand::random;
use gemma::chip8::computer_manager::Chip8ComputerManager;
use gemma::chip8::cpu_states::Chip8CpuStates::WaitingForInstruction;
use gemma::chip8::system_memory::Chip8SystemMemory;
use support::{emmagui_support::GemmaImguiSupport, ui_state::ImGuiUiState};

mod support;

/// Keypad Mappings for my Linux box
/// 1 2 3 C
/// 4 5 6 D
/// 7 8 9 E
/// A 0 B F

const LIN_KEYS: [(u16, u8); 0x10] = [(537, 0x01),(538, 0x02),(539, 0x03),(540, 0x0c),
                              (562, 0x04),(568, 0x05),(550, 0x06),(563, 0x0d),
                              (546, 7),(564, 8),(549, 9),(551, 0xe),
                              (571, 0xa),(569, 0),(548, 0xb),(567, 0xf)];

fn main() {
    pretty_env_logger::init();
    let mut system = Chip8ComputerManager::default();
    let mut ui_state = ImGuiUiState::default();

    support::simple_init(file!(), move |_, ui| {
        let current_time = Instant::now();

        // Key Checks
        let down_keys = ui.io().keys_down;

        // START DEBUG CODE TO DISPLAY WHAT KEYS WE TRAPPED
        for (idx, val) in down_keys.iter().enumerate() {
            if *val {
                println!("{idx} = {val}");
            }
        }
        // END DEBUG CODE


        for (key_code, key_reg) in LIN_KEYS {
            if down_keys[key_code as usize] {
                system.press_key(key_reg);
                system.press_key(key_reg);
                system.wait_for_instruction();
            } else {
                // do we need to release it?

                if system.is_key_pressed(key_reg) {
                    system.release_key(key_reg);
                }
            }
        }

        system.tick();


        // GUI Parts
        if ui_state.show_video {
            GemmaImguiSupport::video_display(&system.state(), &ui_state, ui);
        }

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

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

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

        if ui_state.show_keypad {
            GemmaImguiSupport::keypad_display(&system.state(), ui);
        }
    });
}
