"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ROM_REGIONS = exports.ROM_VERSIONS = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const GameAliases_1 = require("./Common/types/GameAliases");
const MajorasMask_1 = require("./MajorasMask");
const OcarinaofTime_1 = require("./OcarinaofTime");
const Z64LibSupportedGames_1 = require("../API/Utilities/Z64LibSupportedGames");
const PatchManager_1 = require("modloader64_api/Patchers/PatchManager");
const EventHandler_1 = require("modloader64_api/EventHandler");
const PluginLifecycle_1 = require("modloader64_api/PluginLifecycle");
const ModLoaderAPIInjector_1 = require("modloader64_api/ModLoaderAPIInjector");
const BackwardsCompat_1 = require("./Common/compat/BackwardsCompat");
var ROM_VERSIONS;
(function (ROM_VERSIONS) {
    ROM_VERSIONS[ROM_VERSIONS["N0"] = 0] = "N0";
    ROM_VERSIONS[ROM_VERSIONS["GAMECUBE"] = 15] = "GAMECUBE";
    ROM_VERSIONS[ROM_VERSIONS["REV_A"] = 1] = "REV_A";
    ROM_VERSIONS[ROM_VERSIONS["REV_B"] = 2] = "REV_B";
})(ROM_VERSIONS = exports.ROM_VERSIONS || (exports.ROM_VERSIONS = {}));
var ROM_REGIONS;
(function (ROM_REGIONS) {
    ROM_REGIONS["DEBUG_OOT"] = "NZL";
    ROM_REGIONS["NTSC_OOT"] = "CZL";
    ROM_REGIONS["NTSC_MM"] = "NZS";
})(ROM_REGIONS = exports.ROM_REGIONS || (exports.ROM_REGIONS = {}));
class Z64Lib {
    header = [ROM_REGIONS.NTSC_OOT, ROM_REGIONS.DEBUG_OOT, ROM_REGIONS.NTSC_MM];
    ModLoader;
    eventTicks = new Map();
    OOT;
    MM;
    rom_header;
    get heap_size() {
        if (this.OOT !== undefined)
            return this.OOT.heap_size;
        if (this.MM !== undefined)
            return this.MM.heap_size;
        return -1;
    }
    get heap_start() {
        if (this.OOT !== undefined)
            return this.OOT.heap_start;
        if (this.MM !== undefined)
            return this.MM.heap_start;
        return -1;
    }
    postconstructor() {
        new BackwardsCompat_1.OldCoresBackwardsCompat().inject();
        switch (this.rom_header.id) {
            case (ROM_REGIONS.NTSC_OOT):
                this.OOT = new OcarinaofTime_1.OcarinaofTime();
                this.OOT.rom_header = this.rom_header;
                (0, GameAliases_1.setupOot)();
                break;
            case (ROM_REGIONS.DEBUG_OOT):
                this.OOT = new OcarinaofTime_1.OcarinaofTime();
                this.OOT.rom_header = this.rom_header;
                (0, GameAliases_1.setupOotDBG)();
                break;
            case (ROM_REGIONS.NTSC_MM):
                this.MM = new MajorasMask_1.MajorasMask();
                this.MM.rom_header = this.rom_header;
                (0, GameAliases_1.setupMM)();
                break;
        }
    }
    applyVersionPatch(msg, bps, target) {
        this.ModLoader.logger.info(msg);
        let r = PatchManager_1.PatchTypes.get(".bps").patch(this.ModLoader.rom.romReadBuffer(0x0, (32 * 1024 * 1024)), fs_1.default.readFileSync(path_1.default.join(__dirname, "OoT/conversionPatch", bps)));
        this.ModLoader.rom.romWriteBuffer(0x0, r);
        this.rom_header.revision = target;
    }
    preinit() {
        if (this.rom_header.revision === ROM_VERSIONS.GAMECUBE && this.rom_header.id === ROM_REGIONS.NTSC_OOT) {
            // Check if its the retail Gamecube roms from the collector's edition discs or the actual debug rom.
            let rom = this.ModLoader.rom.romReadBuffer(0x0, (32 * 1024 * 1024));
            let hash = this.ModLoader.utils.hashBuffer(rom);
            // Is this Master Quest?
            let mq_GC = "da35577fe54579f6a266931cc75f512d";
            let vanilla_GC = "cd09029edcfb7c097ac01986a0f83d3f";
            if (hash === mq_GC) {
                this.applyVersionPatch("Rom downgrade in progress... (Ura -> GC)", "UratoGC.bps", ROM_VERSIONS.GAMECUBE);
                this.applyVersionPatch("Rom downgrade in progress... (GC -> 1.2)", "GCtoRevB.bps", ROM_VERSIONS.REV_B);
            }
            else if (hash === vanilla_GC) {
                this.applyVersionPatch("Rom downgrade in progress... (GC -> 1.2)", "GCtoRevB.bps", ROM_VERSIONS.REV_B);
            }
        }
        if (this.rom_header.revision === ROM_VERSIONS.REV_B) {
            this.applyVersionPatch("Rom downgrade in progress... (1.2 -> 1.1)", "RevB.bps", ROM_VERSIONS.REV_A);
        }
        if (this.rom_header.revision === ROM_VERSIONS.REV_A) {
            this.applyVersionPatch("Rom downgrade in progress... (1.1 -> 1.0)", "RevA.bps", ROM_VERSIONS.N0);
        }
        if (GameAliases_1.Z64_GAME !== undefined) {
            this.ModLoader.logger.info('Loaded Core: ' + Z64LibSupportedGames_1.Z64LibSupportedGames[GameAliases_1.Z64_GAME]);
        }
        else
            this.ModLoader.logger.error("No core loaded! Debug[ ID: " + this.rom_header.id + " || VERSION: " + this.rom_header.revision + " || COUNTRY: " + this.rom_header.country_code + ']');
    }
    init() {
        if (this.OOT !== undefined) {
            (0, EventHandler_1.setupEventHandlers)(this.OOT, this.ModLoader.publicBus);
            (0, PluginLifecycle_1.setupLifecycle_IPlugin)(this.OOT);
            (0, PluginLifecycle_1.setupLifecycle)(this.OOT);
            (0, ModLoaderAPIInjector_1.setupMLInjects)(this.OOT, this.ModLoader);
            this.OOT.preinit();
        }
        else if (this.MM !== undefined) {
            (0, EventHandler_1.setupEventHandlers)(this.MM, this.ModLoader.publicBus);
            (0, PluginLifecycle_1.setupLifecycle_IPlugin)(this.MM);
            (0, PluginLifecycle_1.setupLifecycle)(this.MM);
            (0, ModLoaderAPIInjector_1.setupMLInjects)(this.MM, this.ModLoader);
            this.MM.preinit();
        }
    }
    postinit() {
    }
    onTick() {
    }
}
exports.default = Z64Lib;
//# sourceMappingURL=Z64Lib.js.map