use super::cpu::*;
use super::mmu::*;
use super::mem_map;

use std::str;

pub struct Gameboy {
    cpu: CPU,
    mmu: MMU,
}

impl Gameboy {
    pub fn new(boot_rom: Box<[u8]>, cart_rom: Box<[u8]>) -> Gameboy {
        Gameboy {
            cpu: CPU::new(),
            mmu: MMU::new(boot_rom, cart_rom),
        }
    }

    pub fn power_up(&mut self) {
        println!("");
        println!("####################");

        // Read Name
        let buffer = &[
            self.mmu.read(0x0134),
            self.mmu.read(0x0135),
            self.mmu.read(0x0136),
            self.mmu.read(0x0137),
            self.mmu.read(0x0138),
            self.mmu.read(0x0139),
            self.mmu.read(0x013A),
            self.mmu.read(0x013B),
            self.mmu.read(0x013C),
            self.mmu.read(0x013D),
            self.mmu.read(0x013E),
            self.mmu.read(0x013F),
            self.mmu.read(0x0140),
            self.mmu.read(0x0141),
            self.mmu.read(0x0142),
            self.mmu.read(0x0143)
        ];
        let s = str::from_utf8(buffer).unwrap();
        println!("Title: {}", s);

        // SGB Flag
        let sgb_flag = self.mmu.read(0x0146);
        println!("SBG Flag: {0:#x}", sgb_flag);

        // Cart Type
        let cart_type = self.mmu.read(0x0147);
        println!("Cartridge Type: {0}", mem_map::cartridge_type(cart_type));

        // Cart ROM size
        let rom_size = self.mmu.read(0x0148);
        println!("ROM Size: {0}", mem_map::rom_size(rom_size));

        // Cart RAM size
        let ram_size = self.mmu.read(0x0149);
        println!("RAM Size: {0}", mem_map::ram_size(ram_size));

        // Destination Code
        let dest_code = self.mmu.read(0x014A);
        println!("Destination Code: {0:#x}", dest_code);

        // Licensee Code (New | Old)
        let old_code = self.mmu.read(0x014B);
        println!("License Code: {0:#x}", old_code);

        // Mask ROM Version
        let version = self.mmu.read(0x014C);
        println!("Version: {0:#x}", version);

        // Complement Checksum
        let header_check = self.mmu.read(0x014D);
        println!("Header Checksum: {0:#x}", header_check);

        // Global Checksum
        let global_check = (self.mmu.read(0x014E) as u16) << 8 | self.mmu.read(0x014F) as u16;
        println!("Global Checksum: {0:#x}", global_check);

        println!("####################");
        println!("");
        // panic!("") // Show Cartridge Information
    }

    pub fn step(&mut self) 

}

{
        self.cpu.step(&mut self.mmu);
    }