"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EdenStartingStatsHealth = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const decorators_1 = require("../../../decorators");
const ModCallbackCustom_1 = require("../../../enums/ModCallbackCustom");
const collectibles_1 = require("../../../functions/collectibles");
const playerDataStructures_1 = require("../../../functions/playerDataStructures");
const playerHealth_1 = require("../../../functions/playerHealth");
const players_1 = require("../../../functions/players");
const stats_1 = require("../../../functions/stats");
const Feature_1 = require("../../private/Feature");
const v = {
    run: {
        edenActiveCollectibles: new Map(),
        edenPassiveCollectibles: new Map(),
        edenPlayerStats: new Map(),
        edenPlayerHealth: new Map(),
    },
};
class EdenStartingStatsHealth extends Feature_1.Feature {
    /** @internal */
    v = v;
    /** @internal */
    constructor() {
        super();
        this.callbacksUsed = [
            // 9
            [isaac_typescript_definitions_1.ModCallback.POST_PLAYER_INIT, this.postPlayerInit],
        ];
        this.customCallbacksUsed = [
            [
                ModCallbackCustom_1.ModCallbackCustom.POST_PLAYER_COLLECTIBLE_ADDED,
                this.postPlayerCollectibleAdded,
            ],
        ];
    }
    /**
     * We must use the `POST_PLAYER_INIT` callback since the two random collectibles have not been
     * granted yet.
     */
    postPlayerInit = (player) => {
        if (!(0, players_1.isEden)(player)) {
            return;
        }
        this.getEdenStats(player);
        this.getEdenHealth(player);
    };
    getEdenStats(player) {
        const existingStatMap = (0, playerDataStructures_1.mapGetPlayer)(v.run.edenPlayerStats, player);
        if (existingStatMap !== undefined) {
            return;
        }
        const playerStats = (0, stats_1.getPlayerStats)(player);
        (0, playerDataStructures_1.mapSetPlayer)(v.run.edenPlayerStats, player, playerStats);
    }
    getEdenHealth(player) {
        const existingHealthMap = (0, playerDataStructures_1.mapGetPlayer)(v.run.edenPlayerHealth, player);
        if (existingHealthMap !== undefined) {
            return;
        }
        const playerHealth = (0, playerHealth_1.getPlayerHealth)(player);
        (0, playerDataStructures_1.mapSetPlayer)(v.run.edenPlayerHealth, player, playerHealth);
    }
    /**
     * We must use the `POST_PLAYER_COLLECTIBLE_ADDED` callback since the collectibles are not yet
     * granted in the `POST_PLAYER_INIT` callback.
     */
    postPlayerCollectibleAdded = (player, collectibleType) => {
        if (!(0, players_1.isEden)(player)) {
            return;
        }
        const map = (0, collectibles_1.isActiveCollectible)(collectibleType)
            ? v.run.edenActiveCollectibles
            : v.run.edenPassiveCollectibles;
        if (!(0, playerDataStructures_1.mapHasPlayer)(map, player)) {
            (0, playerDataStructures_1.mapSetPlayer)(map, player, collectibleType);
        }
    };
    /**
     * Helper function to get the active collectible that Eden started with at the beginning of the
     * run.
     *
     * Returns undefined if passed a player that is not Eden or if the starting collectibles are not
     * yet added. (Eden's starting collectibles are added after the `POST_PLAYER_INIT` callback has
     * fired.)
     *
     * @public
     */
    getEdenStartingActiveCollectible(player) {
        return (0, playerDataStructures_1.mapGetPlayer)(v.run.edenActiveCollectibles, player);
    }
    /**
     * Helper function to get an array containing the active collectible and the passive collectible
     * that Eden started with at the beginning of the run. The active collectible will be the first
     * element and the passive collectible will be the second element.
     *
     * Returns an empty array if passed a player that is not Eden or if the starting collectibles are
     * not yet added. (Eden's starting collectibles are added after the `POST_PLAYER_INIT` callback
     * has fired.)
     *
     * @public
     */
    getEdenStartingCollectibles(player) {
        const collectibleTypes = [];
        const activeCollectibleType = (0, playerDataStructures_1.mapGetPlayer)(v.run.edenActiveCollectibles, player);
        if (activeCollectibleType !== undefined) {
            collectibleTypes.push(activeCollectibleType);
        }
        const passiveCollectibleType = (0, playerDataStructures_1.mapGetPlayer)(v.run.edenPassiveCollectibles, player);
        if (passiveCollectibleType !== undefined) {
            collectibleTypes.push(passiveCollectibleType);
        }
        return collectibleTypes;
    }
    /**
     * Helper function to get the health that Eden started with at the beginning of the run before any
     * of the random collectibles were added.
     *
     * Returns undefined if passed a player that is not Eden.
     *
     * In order to use this function, you must upgrade your mod with `ISCFeature.EDEN_STARTING_STATS`.
     *
     * @public
     */
    getEdenStartingHealth(player) {
        return (0, playerDataStructures_1.mapGetPlayer)(v.run.edenPlayerHealth, player);
    }
    /**
     * Helper function to get the passive collectible that Eden started with at the beginning of the
     * run.
     *
     * Returns undefined if passed a player that is not Eden or if the starting collectibles are not
     * yet added. (Eden's starting collectibles are added after the `POST_PLAYER_INIT` callback has
     * fired.)
     *
     * @public
     */
    getEdenStartingPassiveCollectible(player) {
        return (0, playerDataStructures_1.mapGetPlayer)(v.run.edenPassiveCollectibles, player);
    }
    /**
     * Helper function to get the value of the randomized starting stat for Eden that was assigned at
     * the beginning of the run before any of the random collectibles were added.
     *
     * Returns undefined if passed a player that is not Eden.
     *
     * In order to use this function, you must upgrade your mod with `ISCFeature.EDEN_STARTING_STATS`.
     *
     * @public
     */
    getEdenStartingStat(player, playerStat) {
        const playerStats = (0, playerDataStructures_1.mapGetPlayer)(v.run.edenPlayerStats, player);
        if (playerStats === undefined) {
            return undefined;
        }
        return playerStats[playerStat];
    }
    /**
     * Helper function to get all of the stat values that Eden started with at the beginning of the
     * run before any of the random collectibles were added.
     *
     * Returns undefined if passed a player that is not Eden.
     *
     * In order to use this function, you must upgrade your mod with `ISCFeature.EDEN_STARTING_STATS`.
     *
     * @public
     */
    getEdenStartingStats(player) {
        return (0, playerDataStructures_1.mapGetPlayer)(v.run.edenPlayerStats, player);
    }
}
exports.EdenStartingStatsHealth = EdenStartingStatsHealth;
__decorate([
    decorators_1.Exported
], EdenStartingStatsHealth.prototype, "getEdenStartingActiveCollectible", null);
__decorate([
    decorators_1.Exported
], EdenStartingStatsHealth.prototype, "getEdenStartingCollectibles", null);
__decorate([
    decorators_1.Exported
], EdenStartingStatsHealth.prototype, "getEdenStartingHealth", null);
__decorate([
    decorators_1.Exported
], EdenStartingStatsHealth.prototype, "getEdenStartingPassiveCollectible", null);
__decorate([
    decorators_1.Exported
], EdenStartingStatsHealth.prototype, "getEdenStartingStat", null);
__decorate([
    decorators_1.Exported
], EdenStartingStatsHealth.prototype, "getEdenStartingStats", null);
