"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.temporarilyRemoveTrinkets = exports.temporarilyRemoveTrinket = exports.smeltTrinkets = exports.smeltTrinket = exports.giveTrinketsBack = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const playerCollectibles_1 = require("./playerCollectibles");
const trinkets_1 = require("./trinkets");
const utils_1 = require("./utils");
/**
 * Helper function to restore the player's trinkets back to the way they were before the
 * `temporarilyRemoveTrinket` function was used. It will re-smelt any smelted trinkets that were
 * removed.
 */
function giveTrinketsBack(player, trinketSituation) {
    // A trinket situation of undefined signifies that we did not have to remove the trinket. If this
    // is the case, we do not have to give anything back.
    if (trinketSituation === undefined) {
        return;
    }
    const trinketType1 = player.GetTrinket(isaac_typescript_definitions_1.TrinketSlot.SLOT_1);
    const trinketType2 = player.GetTrinket(isaac_typescript_definitions_1.TrinketSlot.SLOT_2);
    // Remove any existing trinkets.
    if (trinketType1 !== isaac_typescript_definitions_1.TrinketType.NULL) {
        player.TryRemoveTrinket(trinketType1);
    }
    if (trinketType2 !== isaac_typescript_definitions_1.TrinketType.NULL) {
        player.TryRemoveTrinket(trinketType2);
    }
    // First, add the smelted trinkets back.
    (0, utils_1.repeat)(trinketSituation.numSmeltedTrinkets, () => {
        player.AddTrinket(trinketSituation.trinketTypeRemoved, false);
        (0, playerCollectibles_1.useActiveItemTemp)(player, isaac_typescript_definitions_1.CollectibleType.SMELTER);
    });
    // Second, add back the stored trinkets.
    if (trinketSituation.trinketType1 !== isaac_typescript_definitions_1.TrinketType.NULL) {
        player.AddTrinket(trinketSituation.trinketType1, false);
    }
    if (trinketSituation.trinketType2 !== isaac_typescript_definitions_1.TrinketType.NULL) {
        player.AddTrinket(trinketSituation.trinketType2, false);
    }
}
exports.giveTrinketsBack = giveTrinketsBack;
/**
 * Helper function to smelt a trinket. Before smelting, this function will automatically remove the
 * trinkets that the player is holding, if any, and then give them back after the new trinket is
 * smelted.
 *
 * @param player The player to smelt the trinkets to.
 * @param trinketType The trinket type to smelt.
 * @param numTrinkets Optional. If specified, will smelt the given number of trinkets. Use this to
 *                    avoid calling this function multiple times. Default is 1.
 */
function smeltTrinket(player, trinketType, numTrinkets = 1) {
    const trinketSituation = temporarilyRemoveTrinkets(player);
    (0, utils_1.repeat)(numTrinkets, () => {
        player.AddTrinket(trinketType);
        (0, playerCollectibles_1.useActiveItemTemp)(player, isaac_typescript_definitions_1.CollectibleType.SMELTER);
    });
    giveTrinketsBack(player, trinketSituation);
}
exports.smeltTrinket = smeltTrinket;
/**
 * Helper function to smelt two or more different trinkets. If you want to smelt one trinket (or
 * multiple copies of one trinket), then use the `smeltTrinket` helper function instead.
 *
 * This function is variadic, meaning that you can pass as many trinket types as you want to smelt.
 *
 * Before smelting, this function will automatically remove the trinkets that the player is holding,
 * if any, and then give them back after the new trinket is smelted.
 *
 * @param player The player to smelt the trinkets to.
 * @param trinketTypes The trinket types to smelt.
 */
function smeltTrinkets(player, ...trinketTypes) {
    for (const trinketType of trinketTypes) {
        smeltTrinket(player, trinketType);
    }
}
exports.smeltTrinkets = smeltTrinkets;
/**
 * Helper function to temporarily remove a specific kind of trinket from the player. Use this in
 * combination with the `giveTrinketsBack` function to take away and give back a trinket on the same
 * frame. This function correctly handles multiple trinket slots and ensures that all copies of the
 * trinket are removed, including smelted trinkets.
 *
 * Note that one smelted golden trinket is the same as two smelted normal trinkets.
 *
 * @returns Undefined if the player does not have the trinket, or TrinketSituation if they do.
 */
function temporarilyRemoveTrinket(player, trinketType) {
    if (!player.HasTrinket(trinketType)) {
        return undefined;
    }
    const trinketType1 = player.GetTrinket(isaac_typescript_definitions_1.TrinketSlot.SLOT_1);
    const trinketType2 = player.GetTrinket(isaac_typescript_definitions_1.TrinketSlot.SLOT_2);
    let numTrinkets = 0;
    while (player.HasTrinket(trinketType)) {
        player.TryRemoveTrinket(trinketType);
        numTrinkets++;
    }
    let numSmeltedTrinkets = numTrinkets;
    const trinketWasInSlot1 = trinketType1 === trinketType ||
        trinketType1 === (0, trinkets_1.getGoldenTrinketType)(trinketType);
    if (trinketWasInSlot1) {
        numSmeltedTrinkets--;
    }
    const trinketWasInSlot2 = trinketType2 === trinketType ||
        trinketType2 === (0, trinkets_1.getGoldenTrinketType)(trinketType);
    if (trinketWasInSlot2) {
        numSmeltedTrinkets--;
    }
    return {
        trinketTypeRemoved: trinketType,
        trinketType1,
        trinketType2,
        numSmeltedTrinkets,
    };
}
exports.temporarilyRemoveTrinket = temporarilyRemoveTrinket;
/**
 * Helper function to temporarily removes a player's held trinkets, if any. This will not remove any
 * smelted trinkets. Use this in combination with the `giveTrinketsBack` function to take away and
 * give back trinkets on the same frame.
 *
 * @returns Undefined if the player does not have any trinkets, or TrinketSituation if they do.
 */
function temporarilyRemoveTrinkets(player) {
    const trinketType1 = player.GetTrinket(isaac_typescript_definitions_1.TrinketSlot.SLOT_1);
    const trinketType2 = player.GetTrinket(isaac_typescript_definitions_1.TrinketSlot.SLOT_2);
    if (trinketType1 === isaac_typescript_definitions_1.TrinketType.NULL && trinketType2 === isaac_typescript_definitions_1.TrinketType.NULL) {
        return undefined;
    }
    if (trinketType1 !== isaac_typescript_definitions_1.TrinketType.NULL) {
        player.TryRemoveTrinket(trinketType1);
    }
    if (trinketType2 !== isaac_typescript_definitions_1.TrinketType.NULL) {
        player.TryRemoveTrinket(trinketType2);
    }
    return {
        trinketTypeRemoved: isaac_typescript_definitions_1.TrinketType.NULL,
        trinketType1,
        trinketType2,
        numSmeltedTrinkets: 0,
    };
}
exports.temporarilyRemoveTrinkets = temporarilyRemoveTrinkets;
