use crate::emulator::{
    system::model::{Command, State},
    ui::interface::Component,
};

use common::instructions::Register;

pub struct StackInspector {
    visible: bool,
}

impl Default for StackInspector {
    fn default() -> Self {
        Self::new()
    }
}

impl StackInspector {
    #[must_use]
    pub const fn new() -> Self {
        Self { visible: false }
    }
}

impl Component for StackInspector {
    fn visible(&mut self) -> &mut bool {
        &mut self.visible
    }

    fn name(&self) -> &'static str {
        "Stack Inspector"
    }

    fn category(&self) -> super::interface::Category {
        super::interface::Category::Memory
    }

    fn render(&mut self, state: &mut State, ui: &mut egui::Ui, _ctx: &egui::Context) {
        state.send(Command::StackRequest);

        ui.vertical(|ui| {
            ui.heading("Stack Inspector");
            egui::ScrollArea::vertical()
                .id_salt("stack_inspector_scroll")
                .show(ui, |ui| {
                    egui::Grid::new("stack_grid")
                        .num_columns(2)
                        .spacing([40.0, 4.0])
                        .striped(true)
                        .show(ui, |ui| {
                            ui.label("Address");
                            ui.label("Value");
                            ui.end_row();
                            for (i, value) in
                                state.stack_view.chunks(4).take(32).enumerate()
                            {
                                let value = u32::from_be_bytes(value.try_into().expect(
                                    "Could not read 4 byte instruction or data! Something is wrong.",
                                ));
                                ui.label(format!(
                                    "+{} [{}]",
                                    i*4,
                                    state.reg_file.get(Register::Spr).expect("SPR should never be invalid") + i as u32 * 4
                                ));
                                ui.label(format!("0x{value:08X} ({value})"));
                                ui.end_row();
                            }

                            if state.stack_view.is_empty() {
                                ui.label("(empty)");
                                ui.label("-");
                                ui.end_row();
                            }
                        });
                });
        });
    }
}
