"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SaveContext = void 0;
const JSONTemplate_1 = require("modloader64_api/JSONTemplate");
const Z64API = __importStar(require("../../API/imports"));
const Z64CORE = __importStar(require("../importsZ64"));
class SaveContext extends JSONTemplate_1.JSONTemplate {
    ModLoader;
    emulator;
    instance = Z64CORE.Z64.Z64_SAVE;
    entrance_index_addr = this.instance + 0x0000;
    age_addr = this.instance + 0x0004;
    cutscene_number_addr = this.instance + 0x000a;
    world_time_addr = this.instance + 0x000c;
    world_night_addr = this.instance + 0x0010;
    zeldaz_addr = this.instance + 0x001c;
    death_addr = this.instance + 0x0022;
    player_name_addr = this.instance + 0x0024;
    dd_flag_addr = this.instance + 0x002c;
    heart_container_addr = this.instance + 0x002e;
    health_addr = this.instance + 0x0030;
    magic_meter_size_addr = this.instance + 0x0032;
    magic_current_addr = this.instance + 0x0033;
    magic_limit_addr = this.instance + 0x13f4;
    magic_flag_1_addr = this.instance + 0x003a;
    magic_flag_2_addr = this.instance + 0x003c;
    magic_fill_cap_addr = this.instance + 0x13f7;
    rupees_address = this.instance + 0x0034;
    navi_timer_addr = this.instance + 0x0038;
    checksum_addr = this.instance + 0x1352;
    magic_beans_addr = this.instance + 0x009b;
    poe_score_addr = this.instance + 0x0ebc;
    scene_data_addr = this.instance + 0x00d4;
    event_data_addr = this.instance + 0x0ed4;
    item_flag_addr = this.instance + 0x0ef0;
    inf_table_addr = this.instance + 0x0ef8;
    skulltula_table_addr = this.instance + 0x0e9c;
    scarecrowsSongChildFlag_addr = this.instance + 0x12c4;
    scarecrowsSong_addr = this.instance + 0x12c6;
    scarecrowsSong_addr_1 = 0x801029FC;
    scarecrowsSong_addr_2 = 0x80102A9C;
    double_defense_addr_1 = this.instance + 0x00cf;
    double_defense_addr_2 = this.instance + 0x3d;
    index_addr = 0x1354;
    // Further abstractions
    swords;
    shields;
    tunics;
    boots;
    inventory;
    questStatus;
    keyManager;
    dungeonItemManager;
    commandBuffer;
    jsonFields = [
        'entrance_index',
        'cutscene_number',
        'world_time',
        'world_night_flag',
        'zeldaz_string',
        'death_counter',
        'player_name',
        'dd_flag',
        'heart_containers',
        'health',
        'magic_meter_size',
        'magic_current',
        'rupee_count',
        'navi_timer',
        'checksum',
        'age',
        'swords',
        'shields',
        'tunics',
        'boots',
        'inventory',
        'questStatus',
        'magic_beans_purchased',
        'poe_collector_score',
        'scarecrowsSongChildFlag',
        'scarecrowsSong'
    ];
    constructor(ModLoader, log, core) {
        super();
        this.ModLoader = ModLoader;
        this.emulator = ModLoader.emulator;
        this.swords = new Z64CORE.Z64.SwordsEquipment(this.emulator, core);
        this.shields = new Z64CORE.Z64.ShieldsEquipment(this.emulator);
        this.tunics = new Z64CORE.OoT.TunicsEquipment(this.emulator);
        this.boots = new Z64CORE.OoT.BootsEquipment(this.emulator);
        this.inventory = new Z64CORE.OoT.Inventory(this.emulator, log);
        this.questStatus = new Z64CORE.OoT.QuestStatus(this.emulator);
        this.keyManager = new Z64CORE.Z64.KeyManager(this.emulator);
        this.dungeonItemManager = new Z64CORE.Z64.DungeonItemManager(this.emulator);
    }
    // https://wiki.cloudmodding.com/oot/Entrance_Table
    // https://wiki.cloudmodding.com/oot/Entrance_Table_(Data)
    get entrance_index() {
        return this.emulator.rdramRead32(this.entrance_index_addr);
    }
    set entrance_index(index) {
        this.emulator.rdramWrite32(this.entrance_index_addr, index);
    }
    get cutscene_number() {
        return this.emulator.rdramRead16(this.cutscene_number_addr);
    }
    set cutscene_number(index) {
        this.emulator.rdramWrite16(this.cutscene_number_addr, index);
    }
    get world_time() {
        return this.emulator.rdramRead16(this.world_time_addr);
    }
    set world_time(time) {
        this.emulator.rdramWrite16(this.world_time_addr, time);
    }
    get world_night_flag() {
        return this.emulator.rdramRead32(this.world_night_addr) === 1;
    }
    set world_night_flag(bool) {
        this.emulator.rdramWrite32(this.world_night_addr, (function (bool) {
            return bool ? 1 : 0;
        })(bool));
    }
    get zeldaz_string() {
        return this.emulator.rdramReadBuffer(this.zeldaz_addr, 6).toString('ascii');
    }
    get death_counter() {
        return this.emulator.rdramRead16(this.death_addr);
    }
    set death_counter(deaths) {
        this.emulator.rdramWrite16(this.death_addr, deaths);
    }
    get player_name() {
        return Z64API.zeldaString.decode(this.emulator.rdramReadBuffer(this.player_name_addr, 8));
    }
    set player_name(str) {
        this.emulator.rdramWriteBuffer(this.player_name_addr, Z64API.zeldaString.encode(str));
    }
    // Will always be false normally.
    get dd_flag() {
        return this.emulator.rdramRead16(this.dd_flag_addr) === 1;
    }
    set dd_flag(bool) {
        this.emulator.rdramWrite16(this.dd_flag_addr, (function (bool) {
            return bool ? 1 : 0;
        })(bool));
    }
    get heart_containers() {
        return this.emulator.rdramRead16(this.heart_container_addr) / 0x10;
    }
    set heart_containers(num) {
        this.emulator.rdramWrite16(this.heart_container_addr, num * 0x10);
    }
    get health() {
        return this.emulator.rdramRead16(this.health_addr);
    }
    set health(hearts) {
        this.emulator.rdramWrite16(this.health_addr, hearts);
    }
    get magic_meter_size() {
        return this.emulator.rdramRead8(this.magic_meter_size_addr);
    }
    // Several things need to be set in order for magic to function properly.
    set magic_meter_size(size) {
        switch (size) {
            case 0 /* Z64API.Z64.Magic.NONE */: {
                this.emulator.rdramWrite8(this.magic_flag_1_addr, 0);
                this.emulator.rdramWrite8(this.magic_flag_2_addr, 0);
                this.emulator.rdramWrite8(this.magic_fill_cap_addr, 0 /* Z64API.Z64.MagicQuantities.NONE */);
                this.emulator.rdramWrite8(this.magic_meter_size_addr, 0);
                break;
            }
            case 1 /* Z64API.Z64.Magic.NORMAL */: {
                this.emulator.rdramWrite8(this.magic_flag_1_addr, 1);
                this.emulator.rdramWrite8(this.magic_flag_2_addr, 0);
                this.emulator.rdramWrite8(this.magic_fill_cap_addr, 48 /* Z64API.Z64.MagicQuantities.NORMAL */);
                this.emulator.rdramWrite8(this.magic_meter_size_addr, 0);
                break;
            }
            case 2 /* Z64API.Z64.Magic.EXTENDED */: {
                this.emulator.rdramWrite8(this.magic_flag_1_addr, 1);
                this.emulator.rdramWrite8(this.magic_flag_2_addr, 1);
                this.emulator.rdramWrite8(this.magic_fill_cap_addr, 96 /* Z64API.Z64.MagicQuantities.EXTENDED */);
                this.emulator.rdramWrite8(this.magic_meter_size_addr, 0);
                break;
            }
        }
    }
    get magic_current() {
        return this.emulator.rdramRead8(this.magic_current_addr);
    }
    set magic_current(amount) {
        this.emulator.rdramWrite8(this.magic_current_addr, amount);
    }
    get rupee_count() {
        return this.emulator.rdramRead16(this.rupees_address);
    }
    set rupee_count(dosh) {
        this.emulator.rdramWrite16(this.rupees_address, dosh);
    }
    get navi_timer() {
        return this.emulator.rdramRead16(this.navi_timer_addr);
    }
    set navi_timer(time) {
        this.emulator.rdramWrite16(this.navi_timer_addr, time);
    }
    get checksum() {
        return this.emulator.rdramRead16(this.checksum_addr);
    }
    get age() {
        return this.emulator.rdramRead32(this.age_addr);
    }
    set age(age) {
        this.emulator.rdramWrite32(this.age_addr, age);
    }
    get magic_beans_purchased() {
        return this.emulator.rdramRead8(this.magic_beans_addr);
    }
    set magic_beans_purchased(amt) {
        this.emulator.rdramWrite8(this.magic_beans_addr, amt);
    }
    get poe_collector_score() {
        return this.emulator.rdramRead32(this.poe_score_addr);
    }
    set poe_collector_score(pts) {
        this.emulator.rdramWrite32(this.poe_score_addr, pts);
    }
    get permSceneData() {
        return this.emulator.rdramReadBuffer(this.scene_data_addr, 0xb0c);
    }
    set permSceneData(buf) {
        this.emulator.rdramWriteBuffer(this.scene_data_addr, buf);
    }
    get eventFlags() {
        return this.emulator.rdramReadBuffer(this.event_data_addr, 0x1c);
    }
    set eventFlags(buf) {
        this.emulator.rdramWriteBuffer(this.event_data_addr, buf);
    }
    get itemFlags() {
        return this.emulator.rdramReadBuffer(this.item_flag_addr, 0x8);
    }
    set itemFlags(buf) {
        this.emulator.rdramWriteBuffer(this.item_flag_addr, buf);
    }
    get infTable() {
        return this.emulator.rdramReadBuffer(this.inf_table_addr, 0x3c);
    }
    set infTable(buf) {
        this.emulator.rdramWriteBuffer(this.inf_table_addr, buf);
    }
    get skulltulaFlags() {
        return this.emulator.rdramReadBuffer(this.skulltula_table_addr, 0x18);
    }
    set skulltulaFlags(buf) {
        this.emulator.rdramWriteBuffer(this.skulltula_table_addr, buf);
    }
    get scarecrowsSongChildFlag() {
        return this.emulator.rdramRead16(this.scarecrowsSongChildFlag_addr) === 1;
    }
    set scarecrowsSongChildFlag(bool) {
        this.emulator.rdramWrite16(this.scarecrowsSongChildFlag_addr, (function (bool) {
            return bool ? 1 : 0;
        })(bool));
    }
    get scarecrowsSong() {
        return this.emulator.rdramReadBuffer(this.scarecrowsSong_addr, 0x80);
    }
    set scarecrowsSong(buf) {
        this.emulator.rdramWriteBuffer(this.scarecrowsSong_addr, buf);
        this.emulator.rdramWriteBuffer(this.scarecrowsSong_addr_1, buf);
        //this.emulator.rdramWriteBuffer(this.scarecrowsSong_addr_2, buf);
    }
    get double_defense() {
        return this.emulator.rdramRead8(this.double_defense_addr_1);
    }
    set double_defense(n) {
        this.emulator.rdramWrite8(this.double_defense_addr_1, n);
        if (n > 0) {
            this.emulator.rdramWrite8(this.double_defense_addr_2, 0x1);
        }
        else {
            this.emulator.rdramWrite8(this.double_defense_addr_2, 0x0);
        }
    }
    get bButton() {
        return this.emulator.rdramRead8(this.instance + 0x68);
    }
    get index() {
        return this.emulator.rdramRead32(this.instance + this.index_addr);
    }
}
exports.SaveContext = SaveContext;
//# sourceMappingURL=SaveContext.js.map