"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isVanillaPillEffect = exports.isValidPillEffect = exports.isModdedPillEffect = exports.isHorsePill = exports.isGoldPill = exports.getVanillaPillEffectsOfType = exports.getPillEffectType = exports.getPillEffectName = exports.getPillEffectClass = exports.getPillColorFromEffect = exports.getPHDPillEffect = exports.getNormalPillColors = exports.getNormalPillColorFromHorse = exports.getHorsePillColors = exports.getHorsePillColor = exports.getFalsePHDPillEffect = exports.getAllPillColors = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedEnumValues_1 = require("../cachedEnumValues");
const cachedClasses_1 = require("../core/cachedClasses");
const constantsFirstLast_1 = require("../core/constantsFirstLast");
const PHDPillConversionsMap_1 = require("../maps/PHDPillConversionsMap");
const falsePHDPillConversionsMap_1 = require("../maps/falsePHDPillConversionsMap");
const pillEffectClasses_1 = require("../objects/pillEffectClasses");
const pillEffectNames_1 = require("../objects/pillEffectNames");
const pillEffectTypeToPillEffects_1 = require("../objects/pillEffectTypeToPillEffects");
const pillEffectTypes_1 = require("../objects/pillEffectTypes");
const types_1 = require("./types");
const utils_1 = require("./utils");
/**
 * Add this to a `PillColor` to get the corresponding giant pill color.
 *
 * Corresponds to the vanilla `PillColor.GIANT_FLAG` value.
 *
 * 1 << 11
 */
const HORSE_PILL_COLOR_ADJUSTMENT = 2048;
/**
 * Helper function to get an array with every non-null pill color. This includes all gold colors and
 * all horse colors.
 */
function getAllPillColors() {
    return cachedEnumValues_1.PILL_COLOR_VALUES.slice(1); // Remove `PillColor.NULL`
}
exports.getAllPillColors = getAllPillColors;
/**
 * Helper function to get the associated pill effect after False PHD is acquired. If a pill effect
 * is not altered by False PHD, then the same pill effect will be returned.
 */
function getFalsePHDPillEffect(pillEffect) {
    const convertedPillEffect = falsePHDPillConversionsMap_1.FALSE_PHD_PILL_CONVERSIONS_MAP.get(pillEffect);
    return convertedPillEffect ?? pillEffect;
}
exports.getFalsePHDPillEffect = getFalsePHDPillEffect;
/**
 * Helper function to get the corresponding horse pill color from a normal pill color.
 *
 * For example, passing `PillColor.BLUE_BLUE` would result in 2049, which is the value that
 * corresponds to the horse pill color for blue/blue.
 *
 * If passed a horse pill color, this function will return the unmodified pill color.
 */
function getHorsePillColor(pillColor) {
    return isHorsePill(pillColor)
        ? pillColor
        : pillColor + HORSE_PILL_COLOR_ADJUSTMENT;
}
exports.getHorsePillColor = getHorsePillColor;
/** Helper function to get an array with every non-gold horse pill color. */
function getHorsePillColors() {
    return (0, utils_1.iRange)(constantsFirstLast_1.FIRST_HORSE_PILL_COLOR, constantsFirstLast_1.LAST_HORSE_PILL_COLOR);
}
exports.getHorsePillColors = getHorsePillColors;
/**
 * Helper function to get the corresponding normal pill color from a horse pill color.
 *
 * For example, passing 2049 would result in `PillColor.BLUE_BLUE`.
 *
 * If called with a non-horse pill color, this function will return back the same color.
 */
function getNormalPillColorFromHorse(pillColor) {
    return isHorsePill(pillColor)
        ? (0, types_1.asPillColor)(pillColor - HORSE_PILL_COLOR_ADJUSTMENT)
        : pillColor;
}
exports.getNormalPillColorFromHorse = getNormalPillColorFromHorse;
/** Helper function to get an array with every non-gold and non-horse pill color. */
function getNormalPillColors() {
    return (0, utils_1.iRange)(constantsFirstLast_1.FIRST_PILL_COLOR, constantsFirstLast_1.LAST_NORMAL_PILL_COLOR);
}
exports.getNormalPillColors = getNormalPillColors;
/**
 * Helper function to get the associated pill effect after PHD is acquired. If a pill effect is not
 * altered by PHD, then the same pill effect will be returned.
 */
function getPHDPillEffect(pillEffect) {
    const convertedPillEffect = PHDPillConversionsMap_1.PHD_PILL_CONVERSIONS_MAP.get(pillEffect);
    return convertedPillEffect ?? pillEffect;
}
exports.getPHDPillEffect = getPHDPillEffect;
/**
 * Helper function to get the corresponding pill color from an effect by repeatedly using the
 * `ItemPool.GetPillEffect` method.
 *
 * Note that this will return the corresponding effect even if the passed pill color is not yet
 * identified by the player.
 *
 * Returns `PillColor.NULL` if there is the corresponding pill color cannot be found.
 *
 * This function is especially useful in the `POST_USE_PILL` callback, since at that point, the used
 * pill is already consumed, and the callback only passes the effect. In this specific circumstance,
 * consider using the `POST_USE_PILL_FILTER` callback instead of the `POST_USE_PILL` callback, since
 * it correctly passes the color and handles the case of horse pills.
 */
function getPillColorFromEffect(pillEffect) {
    const itemPool = cachedClasses_1.game.GetItemPool();
    const normalPillColors = getNormalPillColors();
    for (const normalPillColor of normalPillColors) {
        const normalPillEffect = itemPool.GetPillEffect(normalPillColor);
        if (normalPillEffect === pillEffect) {
            return normalPillColor;
        }
    }
    return isaac_typescript_definitions_1.PillColor.NULL;
}
exports.getPillColorFromEffect = getPillColorFromEffect;
/**
 * Helper function to get a pill effect class from a PillEffect enum value. In this context, the
 * class is equal to the numerical prefix in the "class" tag in the "pocketitems.xml" file. Use the
 * `getPillEffectType` helper function to determine whether the pill effect is positive, negative,
 * or neutral.
 *
 * Due to limitations in the API, this function will not work properly for modded pill effects, and
 * will always return `DEFAULT_PILL_EFFECT_CLASS` in those cases.
 */
function getPillEffectClass(pillEffect) {
    // `ItemConfigPillEffect` does not contain the "class" tag, so we must manually compile a map of
    // pill effect classes. Modded pill effects are not included in the map.
    const pillEffectClass = pillEffectClasses_1.PILL_EFFECT_CLASSES[pillEffect];
    // Handle modded pill effects.
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
    return pillEffectClass ?? pillEffectClasses_1.DEFAULT_PILL_EFFECT_CLASS;
}
exports.getPillEffectClass = getPillEffectClass;
/**
 * Helper function to get a pill effect name from a `PillEffect`. Returns "Unknown" if the provided
 * pill effect is not valid.
 *
 * This function works for both vanilla and modded pill effects.
 *
 * For example, `getPillEffectName(PillEffect.BAD_GAS)` would return "Bad Gas".
 */
function getPillEffectName(pillEffect) {
    // `ItemConfigPillEffect.Name` is bugged with vanilla pill effects on patch v1.7.6, so we use a
    // hard-coded map as a workaround.
    const pillEffectName = pillEffectNames_1.PILL_EFFECT_NAMES[pillEffect];
    // Handle modded pill effects.
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
    if (pillEffectName !== undefined) {
        return pillEffectName;
    }
    const itemConfigPillEffect = cachedClasses_1.itemConfig.GetPillEffect(pillEffect);
    if (itemConfigPillEffect !== undefined) {
        return itemConfigPillEffect.Name;
    }
    return pillEffectNames_1.DEFAULT_PILL_EFFECT_NAME;
}
exports.getPillEffectName = getPillEffectName;
/**
 * Helper function to get a pill effect type from a `PillEffect` enum value. In this context, the
 * type is equal to positive, negative, or neutral. This is derived from the suffix of the "class"
 * tag in the "pocketitems.xml" file. Use the `getPillEffectClass` helper function to determine the
 * "power" of the pill.
 *
 * Due to limitations in the API, this function will not work properly for modded pill effects, and
 * will always return `DEFAULT_PILL_EFFECT_TYPE` in those cases.
 */
function getPillEffectType(pillEffect) {
    // `ItemConfigPillEffect` does not contain the "class" tag, so we must manually compile a map of
    // pill effect classes. Modded pill effects are not included in the map.
    const pillEffectType = pillEffectTypes_1.PILL_EFFECT_TYPES[pillEffect];
    // Handle modded pill effects.
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
    return pillEffectType ?? pillEffectTypes_1.DEFAULT_PILL_EFFECT_TYPE;
}
exports.getPillEffectType = getPillEffectType;
function getVanillaPillEffectsOfType(pillEffectType) {
    return pillEffectTypeToPillEffects_1.PILL_EFFECT_TYPE_TO_PILL_EFFECTS[pillEffectType];
}
exports.getVanillaPillEffectsOfType = getVanillaPillEffectsOfType;
/** Helper function to see if the given pill color is either a gold pill or a horse gold pill. */
function isGoldPill(pillColor) {
    return pillColor === isaac_typescript_definitions_1.PillColor.GOLD || pillColor === isaac_typescript_definitions_1.PillColor.HORSE_GOLD;
}
exports.isGoldPill = isGoldPill;
/** Helper function to see if the given pill color is a horse pill. */
function isHorsePill(pillColor) {
    return (0, types_1.asNumber)(pillColor) > HORSE_PILL_COLOR_ADJUSTMENT;
}
exports.isHorsePill = isHorsePill;
function isModdedPillEffect(pillEffect) {
    return !isVanillaPillEffect(pillEffect);
}
exports.isModdedPillEffect = isModdedPillEffect;
function isValidPillEffect(pillEffect) {
    const potentialPillEffect = (0, types_1.asPillEffect)(pillEffect);
    const itemConfigPillEffect = cachedClasses_1.itemConfig.GetPillEffect(potentialPillEffect);
    return itemConfigPillEffect !== undefined;
}
exports.isValidPillEffect = isValidPillEffect;
function isVanillaPillEffect(pillEffect) {
    return pillEffect <= constantsFirstLast_1.LAST_VANILLA_PILL_EFFECT;
}
exports.isVanillaPillEffect = isVanillaPillEffect;
