"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.pocketItemsEquals = exports.isFirstSlotPocketActiveItem = exports.hasOpenPocketItemSlot = exports.getPocketItems = exports.getFirstPill = exports.getFirstCardOrPill = exports.getFirstCard = exports.getActivePocketItemSlot = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedEnumValues_1 = require("../cachedEnumValues");
const PocketItemType_1 = require("../enums/PocketItemType");
const players_1 = require("./players");
/**
 * Helper function to get the `PocketItemSlot` that the player's pocket active collectible item is
 * in, if any. Returns undefined if the player does not have a pocket active item.
 */
function getActivePocketItemSlot(player) {
    const pocketItems = getPocketItems(player);
    for (const pocketItem of pocketItems) {
        if (pocketItem.type === PocketItemType_1.PocketItemType.ACTIVE_ITEM) {
            return pocketItem.slot;
        }
    }
    return undefined;
}
exports.getActivePocketItemSlot = getActivePocketItemSlot;
/** Helper item to get the first card that a player is holding in their pocket item slots. */
function getFirstCard(player) {
    const pocketItems = getPocketItems(player);
    return pocketItems.find((pocketItem) => pocketItem.type === PocketItemType_1.PocketItemType.CARD);
}
exports.getFirstCard = getFirstCard;
/**
 * Helper item to get the first card or pill that a player is holding in their pocket item slots.
 */
function getFirstCardOrPill(player) {
    const pocketItems = getPocketItems(player);
    return pocketItems.find((pocketItem) => pocketItem.type === PocketItemType_1.PocketItemType.CARD ||
        pocketItem.type === PocketItemType_1.PocketItemType.PILL);
}
exports.getFirstCardOrPill = getFirstCardOrPill;
/** Helper item to get the first pill that a player is holding in their pocket item slots. */
function getFirstPill(player) {
    const pocketItems = getPocketItems(player);
    return pocketItems.find((pocketItem) => pocketItem.type === PocketItemType_1.PocketItemType.PILL);
}
exports.getFirstPill = getFirstPill;
/**
 * Use this helper function as a workaround for the `EntityPlayer.GetPocketItem` method not working
 * correctly.
 *
 * Note that due to API limitations, there is no way to determine the location of a Dice Bag trinket
 * dice. Furthermore, when the player has a Dice Bag trinket dice and a pocket active at the same
 * time, there is no way to determine the location of the pocket active item. If this function
 * cannot determine the identity of a particular slot, it will mark the type of the slot as
 * `PocketItemType.UNDETERMINABLE`.
 */
function getPocketItems(player) {
    const pocketItem = player.GetActiveItem(isaac_typescript_definitions_1.ActiveSlot.POCKET);
    const hasPocketItem = pocketItem !== isaac_typescript_definitions_1.CollectibleType.NULL;
    const pocketItem2 = player.GetActiveItem(isaac_typescript_definitions_1.ActiveSlot.POCKET_SINGLE_USE);
    const hasPocketItem2 = pocketItem2 !== isaac_typescript_definitions_1.CollectibleType.NULL;
    const maxPocketItems = player.GetMaxPocketItems();
    const pocketItems = [];
    let pocketItemIdentified = false;
    let pocketItem2Identified = false;
    for (const slot of cachedEnumValues_1.POCKET_ITEM_SLOT_VALUES) {
        const cardType = player.GetCard(slot);
        const pillColor = player.GetPill(slot);
        if (cardType !== isaac_typescript_definitions_1.CardType.NULL) {
            pocketItems.push({
                slot,
                type: PocketItemType_1.PocketItemType.CARD,
                subType: cardType,
            });
        }
        else if (pillColor !== isaac_typescript_definitions_1.PillColor.NULL) {
            pocketItems.push({
                slot,
                type: PocketItemType_1.PocketItemType.PILL,
                subType: pillColor,
            });
        }
        else if (hasPocketItem && !hasPocketItem2 && !pocketItemIdentified) {
            pocketItemIdentified = true;
            pocketItems.push({
                slot,
                type: PocketItemType_1.PocketItemType.ACTIVE_ITEM,
                subType: pocketItem,
            });
        }
        else if (!hasPocketItem && hasPocketItem2 && !pocketItem2Identified) {
            pocketItem2Identified = true;
            pocketItems.push({
                slot,
                type: PocketItemType_1.PocketItemType.DICE_BAG_DICE,
                subType: pocketItem2,
            });
        }
        else if (hasPocketItem && hasPocketItem2) {
            pocketItems.push({
                slot,
                type: PocketItemType_1.PocketItemType.UNDETERMINABLE,
                subType: 0,
            });
        }
        else {
            pocketItems.push({
                slot,
                type: PocketItemType_1.PocketItemType.EMPTY,
                subType: 0,
            });
        }
        if (slot + 1 === maxPocketItems) {
            break;
        }
    }
    return pocketItems;
}
exports.getPocketItems = getPocketItems;
/**
 * Returns whether the player can hold an additional pocket item, beyond what they are currently
 * carrying. This takes into account items that modify the max number of pocket items, like Starter
 * Deck.
 *
 * If the player is the Tainted Soul, this always returns false, since that character cannot pick up
 * items. (Only Tainted Forgotten can pick up items.)
 */
function hasOpenPocketItemSlot(player) {
    if ((0, players_1.isCharacter)(player, isaac_typescript_definitions_1.PlayerType.SOUL_B)) {
        return false;
    }
    const pocketItems = getPocketItems(player);
    return pocketItems.some((pocketItem) => pocketItem.type === PocketItemType_1.PocketItemType.EMPTY);
}
exports.hasOpenPocketItemSlot = hasOpenPocketItemSlot;
/**
 * Helper function to determine whether the player's "active" pocket item slot is set to their
 * pocket active item.
 */
function isFirstSlotPocketActiveItem(player) {
    const pocketItems = getPocketItems(player);
    const firstPocketItem = pocketItems[0];
    if (firstPocketItem === undefined) {
        return false;
    }
    return firstPocketItem.type === PocketItemType_1.PocketItemType.ACTIVE_ITEM;
}
exports.isFirstSlotPocketActiveItem = isFirstSlotPocketActiveItem;
/** Helper function to see if two sets of pocket item descriptions are identical. */
function pocketItemsEquals(pocketItems1, pocketItems2) {
    if (pocketItems1.length !== pocketItems2.length) {
        return false;
    }
    // eslint-disable-next-line unicorn/no-for-loop
    for (let i = 0; i < pocketItems1.length; i++) {
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        const pocketItem1 = pocketItems1[i];
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        const pocketItem2 = pocketItems2[i];
        const keys = Object.keys(pocketItem1);
        for (const key of keys) {
            if (pocketItem1[key] !== pocketItem2[key]) {
                return false;
            }
        }
    }
    return true;
}
exports.pocketItemsEquals = pocketItemsEquals;
