use core::mos6502cpu::cpu::Mos6502Cpu;
use macroquad::color::{BLACK, Color};
use macroquad::prelude::*;
use macroquad::text::draw_text;

pub struct CpuDisplay {}
impl CpuDisplay {
    pub fn render(cpu: &Mos6502Cpu, x_offset: f32, y_offset: f32) {
        // get the data to display...
        let (pc, a, x, y, address_bus, data_bus, microsteps_remaining, reset_vector, interrupt_vector, nmi_vector) = cpu.dump_data();

        // ...build the interface
        Self::draw_square(x_offset, y_offset, x_offset + 300.0, y_offset + 85.0, BLACK);

        draw_text(
            format!("PC: 0x{:04x} / {}", pc, pc).as_str(),
            x_offset + 5.0,
            y_offset + 18.0,
            15.0,
            BLACK,
        );
        draw_text(
            format!("A: 0x{:02x} X: 0x{:02x} Y: 0x{:02x}", a, x, y).as_str(),
            x_offset + 5.0,
            y_offset + 35.0,
            15.0,
            BLACK,
        );
        draw_text(
            format!("Address: {:016b} | {:04x}", address_bus, address_bus).as_str(),
            x_offset + 5.0,
            y_offset + 55.0,
            15.0,
            BLACK,
        );
        draw_text(
            format!("Data: {:08b} | {:02x}", data_bus, data_bus).as_str(),
            x_offset + 5.0,
            y_offset + 75.0,
            15.0,
            BLACK,
        );
        draw_text(
            format!("MS: {:02x}", microsteps_remaining).as_str(),
            x_offset + 5.0,
            y_offset + 95.0,
            15.0,
            BLACK,
        );
    }

    fn draw_square(x1: f32, y1: f32, x2: f32, y2: f32, color: Color) {
        // println!("Square from {x1:2.0}x{y1:2.0} to {x2:2.0}x{y2:2.0} with {:?}", color);
        draw_line(x1, y1, x2, y1, 1.0, color);
        draw_line(x1, y1, x1, y2, 1.0, color);
        draw_line(x1, y2, x2, y2, 1.0, color);
        draw_line(x2, y1, x2, y2, 1.0, color);
    }
}
