use log::debug;
use crate::constants::constants_system::{SIZE_1KB, SIZE_32KB};
use crate::periph::mos6530::mos6530::Mos6530;
use crate::traits::bus_device::BusDevice;
use crate::traits::memory_chip::MemoryChip;
use crate::traits::ram_chip::RamChip;
use crate::traits::rom_chip::RomChip;
use crate::traits::via_chip::ViaChip;

impl BusDevice for Mos6530 {
    fn min_offset(&self) -> u16 {
        self.ram_offset
    }

    fn max_offset(&self) -> u16 {
        self.min_offset() + SIZE_1KB as u16
    }

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

    fn data_bus(&self) -> u8 {
        self.data_bus
    }

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

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

}

impl RamChip for Mos6530 {
    fn write(&mut self, offset: &u16, value: &u8) {
        debug!("🐙 Writing ${value:02x} to ${offset:04x}");
    }
}

impl MemoryChip for Mos6530 {
    fn read(&self, offset: &u16) -> u8 {
        debug!("🐙 Reading from ${offset:04x}");
        0
    }
}

impl RomChip for Mos6530 {
    fn program(new_data: &[u8]) -> Box<Self> {
        debug!("🐙 programming {}b to ROM", new_data.len());
        Box::new(Mos6530 {
            data: new_data.to_vec().try_into().unwrap(),
            ram: [0x00; 64],
            porta: 0,
            portb: 0,
            data_bus: 0,
            address_bus: 0,
            cs1: false,
            cs2: false,
            rw: false,
            reset: false,
            io_offset: 0,
            ram_offset: 0,
            rom_offset: 0,
        })
    }
}

impl ViaChip for Mos6530 {
    fn set_port_ddr(&mut self, port_index: u8, value: u8) {
        debug!("🐙Setting DDR{port_index} to {value:02x}");
    }

    fn set_port_data(&mut self, port_index: u8, value: u8) {
        debug!("🐙Setting PORT{port_index} to {value:02x}");
    }
}
