"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.Link = void 0;
const JSONTemplate_1 = require("modloader64_api/JSONTemplate");
const Z64API = __importStar(require("../../API/imports"));
const Z64CORE = __importStar(require("../importsZ64"));
class Link extends JSONTemplate_1.JSONTemplate {
    emulator;
    instance = Z64CORE.Z64.Z64_PLAYER;
    save_context = Z64CORE.Z64.Z64_SAVE;
    anim = 0x80400500;
    state_addr = 0x8040081C;
    state2_addr = 0x8040081C; //TODO: Find real State2_Addr
    tunic_addr = this.instance + 0x013c;
    shield_addr = this.instance + 0x013e;
    bMMs_addr = this.instance + 0x013f;
    mask_addr = this.instance + 0x014f;
    pos_addr = this.instance + 0x24;
    rot_addr = this.instance + 0xb4;
    sword_addr = this.save_context + 0x0070 + 0x1;
    link_state = 0xA6C;
    sound_addr = 0x800000 + 0x88;
    anim_data_addr = 0x600000;
    anim_raw_data_addr = this.anim;
    rotation;
    position;
    homePos;
    homeRot;
    actorUUID = 'Link';
    jsonFields = [
        'state',
        'tunic',
        'shield',
        'bMMs',
        'mask',
        'pos',
        'rot',
        'anim_data',
        'current_sound_id',
    ];
    constructor(emu) {
        super();
        this.emulator = emu;
        this.rotation = new Z64CORE.Z64.Rotation(this);
        this.position = new Z64CORE.Z64.Position(this);
        this.homePos = new Z64CORE.Z64.Position(this, 0x8);
        this.homeRot = new Z64CORE.Z64.Rotation(this, 0xC);
    }
    tunic;
    boots;
    projected_position;
    pointer;
    isTransitionActor;
    bitCount8(value) {
        return this.emulator.bitCount8(value);
    }
    bitCount16(value) {
        return this.emulator.bitCount16(value);
    }
    bitCount32(value) {
        return this.emulator.bitCount32(value);
    }
    bitCountBuffer(buf, off, len) {
        return this.emulator.bitCountBuffer(buf, off, len);
    }
    getRdramBuffer() {
        return this.emulator.getRdramBuffer();
    }
    invalidateCachedCode() {
    }
    get rawStateValue() {
        return this.emulator.rdramRead32(this.instance + this.link_state);
    }
    get anim_data() {
        return this.emulator.rdramReadBuffer(this.anim, 0x86);
    }
    get rawPos() {
        return this.emulator.rdramReadBuffer(this.instance + 0x24, 0xC);
    }
    get actorID() {
        return this.rdramRead16(0x0);
    }
    get actorType() {
        return this.rdramRead8(0x2);
    }
    get room() {
        return this.rdramRead8(0x3);
    }
    set room(r) {
        this.rdramWrite8(0x3, r);
    }
    get renderingFlags() {
        return this.rdramRead32(0x4);
    }
    set renderingFlags(flags) {
        this.rdramWrite32(0x4, flags);
    }
    get variable() {
        return this.rdramRead16(0x1c);
    }
    get objectTableIndex() {
        return this.rdramRead8(0x1e);
    }
    get soundEffect() {
        return this.rdramRead16(0x20);
    }
    set soundEffect(s) {
        this.rdramWrite16(0x20, s);
    }
    get health() {
        return this.rdramRead8(0xaf);
    }
    set health(h) {
        this.rdramWrite8(0xaf, h);
    }
    get redeadFreeze() {
        return this.rdramReadS16(0x118);
    }
    set redeadFreeze(f) {
        this.rdramWrite16(0x118, f);
    }
    get exists() {
        return this.emulator.rdramRead32(this.instance) === 0x2ff;
    }
    destroy() { }
    get state() {
        switch (this.emulator.rdramRead32(this.state_addr)) {
            case 0:
                return 1 /* Z64API.Z64.LinkState.STANDING */;
            case 0x00000008:
                return 1 /* Z64API.Z64.LinkState.STANDING */;
            case 0x20000000:
                return 4 /* Z64API.Z64.LinkState.BUSY */;
            case 0x30000000:
                return 3 /* Z64API.Z64.LinkState.OCARINA */;
            case 0x20000001:
                return 5 /* Z64API.Z64.LinkState.LOADING_ZONE */;
            case 0x80000000:
                return 6 /* Z64API.Z64.LinkState.ENTERING_GROTTO */;
            case 0x00100000:
                return 7 /* Z64API.Z64.LinkState.FIRST_PERSON */;
            case 0x00040000:
                return 8 /* Z64API.Z64.LinkState.JUMPING */;
            case 0x08000000:
                return 2 /* Z64API.Z64.LinkState.SWIMMING */;
            case 0x00004000:
                return 9 /* Z64API.Z64.LinkState.CLIMBING_OUT_OF_WATER */;
            case 0x00002000:
                return 10 /* Z64API.Z64.LinkState.HANGING_FROM_LEDGE */;
            case 0x00800000:
                return 15 /* Z64API.Z64.LinkState.RIDING_EPONA */;
            case 0x00000080:
                return 16 /* Z64API.Z64.LinkState.DYING */;
            case 0x04000000:
                return 17 /* Z64API.Z64.LinkState.TAKING_DAMAGE */;
            case 0x00080000:
                return 18 /* Z64API.Z64.LinkState.FALLING */;
            case 0x00068000:
                return 18 /* Z64API.Z64.LinkState.FALLING */;
            case 0xa0040000:
                return 19 /* Z64API.Z64.LinkState.VOIDING_OUT */;
            case 0x20000c00:
                return 13 /* Z64API.Z64.LinkState.GETTING_ITEM */;
            case 0x20010040:
                return 20 /* Z64API.Z64.LinkState.TALKING */;
            case 0x00018000:
                return 22 /* Z64API.Z64.LinkState.Z_TARGETING */;
            case 0x00028000:
                return 22 /* Z64API.Z64.LinkState.Z_TARGETING */;
            case 0x00000800:
                return 12 /* Z64API.Z64.LinkState.HOLDING_ACTOR */;
            case 0x00100200:
                return 23 /* Z64API.Z64.LinkState.CAMERA */;
            case 0x00100208:
                return 23 /* Z64API.Z64.LinkState.CAMERA */;
        }
        return 0 /* Z64API.Z64.LinkState.UNKNOWN */;
    }
    get state2() {
        let s2 = this.emulator.rdramRead32(this.state2_addr);
        let digits = s2.toString().split('');
        let realDigits = digits.map(Number);
        let idle = realDigits[0];
        let crawlspace = realDigits[3];
        let moving = realDigits[6];
        if (idle === 0x1) {
            return 1 /* Z64API.Z64.LinkState2.IDLE */;
        }
        if (crawlspace === 0x4) {
            return 2 /* Z64API.Z64.LinkState2.CRAWLSPACE */;
        }
        if (moving === 0x2) {
            return 3 /* Z64API.Z64.LinkState2.MOVING_FORWARD */;
        }
        return 0 /* Z64API.Z64.LinkState2.UNKNOWN */;
    }
    get shield() {
        return this.emulator.rdramRead8(this.shield_addr);
    }
    set shield(shield) {
        this.emulator.rdramWrite8(this.shield_addr, shield);
    }
    get sword() {
        return this.emulator.rdramRead8(this.sword_addr);
    }
    set sword(sword) {
        this.emulator.rdramWrite8(this.sword_addr, sword);
    }
    get mask() {
        return this.emulator.rdramRead8(this.mask_addr);
    }
    set mask(mask) {
        this.emulator.rdramWrite8(this.mask_addr, mask);
    }
    get pos() {
        return this.emulator.rdramReadBuffer(this.pos_addr, 0xc);
    }
    set pos(pos) {
        this.emulator.rdramWriteBuffer(this.pos_addr, pos);
    }
    get rot() {
        return this.emulator.rdramReadBuffer(this.rot_addr, 0x8);
    }
    set rot(rot) {
        this.emulator.rdramWriteBuffer(this.rot_addr, rot);
    }
    set anim_data(buf) {
        this.emulator.rdramWriteBuffer(this.anim_raw_data_addr, buf);
    }
    get current_sound_id() {
        return this.emulator.rdramRead16(this.sound_addr);
    }
    set current_sound_id(s) {
        this.emulator.rdramWrite16(this.sound_addr, s);
    }
    get_anim_id() {
        return this.emulator.rdramRead16(this.instance + 0x24A);
    }
    get_anim_frame() {
        return this.emulator.rdramRead16(this.instance + 0x24A + 0x18);
    }
    // Give ILink a complete IMemory implementation for shortcuts.
    rdramRead8(addr) {
        return this.emulator.rdramRead8(this.instance + addr);
    }
    rdramWrite8(addr, value) {
        this.emulator.rdramWrite8(this.instance + addr, value);
    }
    rdramRead16(addr) {
        return this.emulator.rdramRead16(this.instance + addr);
    }
    rdramWrite16(addr, value) {
        this.emulator.rdramWrite16(this.instance + addr, value);
    }
    rdramWrite32(addr, value) {
        this.emulator.rdramWrite32(this.instance + addr, value);
    }
    rdramRead32(addr) {
        return this.emulator.rdramRead32(this.instance + addr);
    }
    rdramReadBuffer(addr, size) {
        return this.emulator.rdramReadBuffer(this.instance + addr, size);
    }
    rdramWriteBuffer(addr, buf) {
        this.emulator.rdramWriteBuffer(this.instance + addr, buf);
    }
    dereferencePointer(addr) {
        return this.emulator.dereferencePointer(this.instance + addr);
    }
    rdramReadS8(addr) {
        return this.emulator.rdramReadS8(this.instance + addr);
    }
    rdramReadS16(addr) {
        return this.emulator.rdramReadS16(this.instance + addr);
    }
    rdramReadS32(addr) {
        return this.emulator.rdramReadS32(this.instance + addr);
    }
    rdramReadBitsBuffer(addr, bytes) {
        return this.emulator.rdramReadBitsBuffer(this.instance + addr, bytes);
    }
    rdramReadBits8(addr) {
        return this.emulator.rdramReadBits8(this.instance + addr);
    }
    rdramReadBit8(addr, bitoffset) {
        return this.emulator.rdramReadBit8(this.instance + addr, bitoffset);
    }
    rdramWriteBitsBuffer(addr, buf) {
        this.emulator.rdramWriteBitsBuffer(this.instance + addr, buf);
    }
    rdramWriteBits8(addr, buf) {
        this.emulator.rdramWriteBits8(this.instance + addr, buf);
    }
    rdramWriteBit8(addr, bitoffset, bit) {
        this.emulator.rdramWriteBit8(this.instance + addr, bitoffset, bit);
    }
    rdramReadPtr8(addr, offset) {
        return this.emulator.rdramReadPtr8(this.instance + addr, offset);
    }
    rdramWritePtr8(addr, offset, value) {
        this.emulator.rdramWritePtr8(this.instance + addr, offset, value);
    }
    rdramReadPtr16(addr, offset) {
        return this.emulator.rdramReadPtr16(this.instance + addr, offset);
    }
    rdramWritePtr16(addr, offset, value) {
        this.emulator.rdramWritePtr16(this.instance + addr, offset, value);
    }
    rdramWritePtr32(addr, offset, value) {
        this.emulator.rdramWritePtr32(this.instance + addr, offset, value);
    }
    rdramReadPtr32(addr, offset) {
        return this.emulator.rdramReadPtr32(this.instance + addr, offset);
    }
    rdramReadPtrBuffer(addr, offset, size) {
        return this.emulator.rdramReadPtrBuffer(this.instance + addr, offset, size);
    }
    rdramWritePtrBuffer(addr, offset, buf) {
        this.emulator.rdramWritePtrBuffer(this.instance + addr, offset, buf);
    }
    rdramReadPtrS8(addr, offset) {
        return this.emulator.rdramReadPtrS8(this.instance + addr, offset);
    }
    rdramReadPtrS16(addr, offset) {
        return this.emulator.rdramReadPtrS16(this.instance + addr, offset);
    }
    rdramReadPtrS32(addr, offset) {
        return this.emulator.rdramReadPtrS32(this.instance + addr, offset);
    }
    rdramReadPtrBitsBuffer(addr, offset, bytes) {
        return this.emulator.rdramReadPtrBitsBuffer(this.instance + addr, offset, bytes);
    }
    rdramReadPtrBits8(addr, offset) {
        return this.emulator.rdramReadPtrBits8(this.instance + addr, offset);
    }
    rdramReadPtrBit8(addr, offset, bitoffset) {
        return this.emulator.rdramReadPtrBit8(this.instance + addr, offset, bitoffset);
    }
    rdramWritePtrBitsBuffer(addr, offset, buf) {
        this.emulator.rdramWritePtrBitsBuffer(this.instance + addr, offset, buf);
    }
    rdramWritePtrBits8(addr, offset, buf) {
        this.emulator.rdramWritePtrBits8(this.instance + addr, offset, buf);
    }
    rdramWritePtrBit8(addr, offset, bitoffset, bit) {
        this.emulator.rdramWritePtrBit8(this.instance + addr, offset, bitoffset, bit);
    }
    rdramReadF32(addr) {
        return this.emulator.rdramReadF32(this.instance + addr);
    }
    rdramReadPtrF32(addr, offset) {
        return this.emulator.rdramReadPtrF32(this.instance + addr, offset);
    }
    rdramWriteF32(addr, value) {
        this.emulator.rdramWriteF32(this.instance + addr, value);
    }
    rdramWritePtrF32(addr, offset, value) {
        this.emulator.rdramWritePtrF32(this.instance + addr, offset, value);
    }
    memoryDebugLogger(bool) { }
    rdramRead64(addr) {
        return this.emulator.rdramRead64(this.pointer + addr);
    }
    rdramReadS64(addr) {
        return this.emulator.rdramReadS64(this.pointer + addr);
    }
    rdramReadF64(addr) {
        return this.emulator.rdramReadF64(this.pointer + addr);
    }
    rdramWrite64(addr, val) {
        this.emulator.rdramWrite64(this.pointer + addr, val);
    }
    rdramWriteF64(addr, val) {
        this.emulator.rdramWriteF64(this.pointer + addr, val);
    }
    rdramReadBigInt64(addr) {
        return this.emulator.rdramReadBigInt64(this.pointer + addr);
    }
    rdramReadBigIntS64(addr) {
        return this.emulator.rdramReadBigIntS64(this.pointer + addr);
    }
    rdramWriteBigInt64(addr, val) {
        this.emulator.rdramWriteBigInt64(this.pointer + addr, val);
    }
    get iframes() {
        return 0;
    }
    set iframes(f) {
        console.log("iframes not implemented yet in MM!");
    }
    u8;
    u16;
    u32;
    u64;
    s8;
    s16;
    s32;
    s64;
    f32;
    f64;
}
exports.Link = Link;
//# sourceMappingURL=Link.js.map