use log::debug;
use crate::computers::ram_rom::RamRomComputer;
use crate::periph::at28c256::At28C256;
use crate::traits::backplane::Backplane;
use crate::periph::hm62256::Hm62256;

impl Backplane for RamRomComputer {
    fn data_bus(&self) -> u8 {
        self.data_bus
    }

    fn address_bus(&self) -> u16 {
        self.address_bus
    }

    fn read_mode(&self) -> bool {
        self.read_mode
    }

    fn set_read_mode(&mut self, new_mode: bool) {
        self.read_mode = new_mode;
    }

    fn set_data_bus(&mut self, new_value: u8) {
        self.data_bus = new_value;
    }

    fn set_address_bus(&mut self, new_value: u16) {
        self.address_bus = new_value;
    }

    fn tick(&mut self) {
        println!("Preparing to tick the backplane. - ${:04x} ${:02x} {}", self.address_bus, self.data_bus, self.read_mode);

        // who are we talking to?
        match self.address_bus {
            0x0000..=0x3fff => {
                // RAM
                println!("ADDRESSING RAM");
                let (ram_address_bus, ram_data_bus) = self.ram.tick(self.address_bus, self.data_bus, self.read_mode, true);
                if self.read_mode {
                    self.data_bus = ram_data_bus;
                }
            },
            0x4000..=0x7fff => {
                // ROM
                println!("ADDRESSING ROM");
                let  rom_data_bus = self.rom.signal_tick(self.address_bus, self.data_bus, true, true, true);
                self.data_bus = rom_data_bus;
            }
            _ => {
                // Out of range
            }
        }
    }

    fn tick_ram(&mut self, address: u16, data: u8, cs: bool, oe: bool, we: bool) -> u8 {
        debug!("Ticking ram with A${address:04x} D${data:02x} CS:{cs} OE:{oe} WE:{we}");
        0
    }

    fn tick_rom(&mut self, address: u16, cs: bool, oe: bool) -> u8 {
        debug!("Ticking rom with A${address:04x} CS:{cs} OE:{oe}");
        0
    }

    fn tick_via(&mut self, address: u16, data: u8, cs0: bool, cs1: bool, rw: bool, rs0: bool, rs1: bool) -> (u8, bool, bool) {
        debug!("Ticking Via with A${address:04x} D${data:02x} cs0:{cs0} cs1:{cs1} rw:{rw} rs0:{rs0} rs1:{rs1}");
        (0, false, false)
    }
}

