use eframe::egui;
use core::computers::rom_only::RomOnlyComputer;
struct MyApp {
    address: String,
    data: String,
    cpu_read: bool,
    computer: RomOnlyComputer
}

impl Default for MyApp {
    fn default() -> Self {
        let rom_data = vec![0x01, 0x02, 0x03, 0x04];
        Self {
            address: String::new(),
            data: String::new(),
            cpu_read: false,
            computer: RomOnlyComputer::program(rom_data), // Example memory: 0x00 to 0xFF
        }
    }
}

impl eframe::App for MyApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |ui| {
            ui.heading("Memory Inspector");

            ui.horizontal(|ui| {
                ui.label("Address:");
                ui.text_edit_singleline(&mut self.address);
            });

            ui.horizontal(|ui| {
                ui.label("Data:");
                ui.text_edit_singleline(&mut self.data);
            });

            ui.checkbox(&mut self.cpu_read, "CPU Read");

            if ui.button("Tick").clicked() {
                println!(
                    "Ticked with Address: {}, Data: {}, CPU Read: {}",
                    self.address, self.data, self.cpu_read
                );
            }

            ui.horizontal(|ui| {
                ui.label(format!("Address Bus ${:?}", self.address).as_str());
                ui.label(format!("Data Bus ${:?}", self.data).as_str());
            });

            ui.separator();
            ui.label("Memory View (Hex Dump):");

            egui::ScrollArea::vertical().show(ui, |ui| {
                let bytes_per_row = 16;
                for (i, chunk) in self.computer.rom_chunks(bytes_per_row).enumerate() {
                    let address = i * bytes_per_row;
                    let hex_values: String = chunk
                        .iter()
                        .map(|b| format!("{:02X} ", b))
                        .collect();

                    let ascii_values: String = chunk
                        .iter()
                        .map(|b| {
                            if b.is_ascii_graphic() {
                                *b as char
                            } else {
                                '.'
                            }
                        })
                        .collect();

                    ui.monospace(format!("{:08X}: {:<48}  {}", address, hex_values, ascii_values));
                }
            });
        });
    }
}

fn main() -> eframe::Result<()> {
    let options = eframe::NativeOptions::default();
    eframe::run_native(
        "Memory Inspector",
        options,
        Box::new(|_cc| Box::new(MyApp::default())),
    )
}
