use crate::parts::clock::Clock;
use core::constants::constants_system::*;
use core::mos6502cpu::cpu::Mos6502Cpu;
use std::fs;
use std::fs::File;
use std::io::{BufReader, Read};
use std::path::Path;

pub struct BenEaterPC {
    clock: Clock,
    // pub because i am rendering it.
    // there should be a proper interface to get the data
    // for ui out of this.
    pub cpu: Mos6502Cpu,
}

impl BenEaterPC {
    pub fn new() -> Self {
        println!("New BENEATERPC");
        BenEaterPC {
            clock: Clock::new(),
            cpu: Mos6502Cpu::default(),
        }
    }

    pub fn tick_system(&mut self) {
        self.cpu.tick();
        if self.cpu.microcode_step == 0 {
            // tick the clock.
            // tick the memory
            // tick the VIA
        } else {
            self.cpu.tick();
        }
    }

    pub fn load_rom(&mut self, rom_to_load: &str) {
        println!("Preparing to load {rom_to_load}");

        let file = File::open(rom_to_load).unwrap();
        let mut reader = BufReader::new(file);
        let mut chunks = Vec::new();

        loop {
            let mut buffer = vec![0u8; 1];
            let bytes_read = reader.read(&mut buffer).unwrap_or(0);
            if bytes_read == 0 {
                break;
            }
            buffer.truncate(bytes_read);
            chunks.push(buffer[0]);
        }
        let data_size = chunks.len();
        print!("Loaded {}b of data.  Poking into memory...", data_size);
        for i in 0..SIZE_32KB {
            self.cpu.poke(i as u16, chunks[i]);
        }
        println!("poke complete.  Poked {}b of data.", data_size);
    }
}
