"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setRoomDisplayFlags = exports.setFloorDisplayFlags = exports.setAllDisplayFlags = exports.isRoomVisible = exports.hideRoomOnMinimap = exports.getRoomDisplayFlags = exports.getFloorDisplayFlags = exports.clearRoomDisplayFlags = exports.clearFloorDisplayFlags = exports.addRoomDisplayFlag = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedClasses_1 = require("../core/cachedClasses");
const flag_1 = require("./flag");
const roomData_1 = require("./roomData");
const rooms_1 = require("./rooms");
const types_1 = require("./types");
const utils_1 = require("./utils");
/**
 * Helper function to add a `DisplayFlag` to a particular room's minimap display flags (e.g. whether
 * it is visible and so on).
 *
 * This function automatically accounts for if MinimapAPI is being used.
 *
 * @param roomGridIndex Set to undefined to use the current room index.
 * @param displayFlag The `DisplayFlag` to set. (See the `DisplayFlag` enum.)
 * @param updateVisibility Optional. Whether to call the `Level.UpdateVisibility` method in order to
 *                         make the changes immediately visible. Default is true.
 */
function addRoomDisplayFlag(roomGridIndex, displayFlag, updateVisibility = true) {
    const oldDisplayFlags = getRoomDisplayFlags(roomGridIndex);
    const newDisplayFlags = (0, flag_1.addFlag)(oldDisplayFlags, displayFlag);
    setRoomDisplayFlags(roomGridIndex, newDisplayFlags, updateVisibility);
}
exports.addRoomDisplayFlag = addRoomDisplayFlag;
/**
 * Helper function to set the value of `DisplayFlag` for every room on the floor to 0.
 *
 * This function automatically accounts for if MinimapAPI is being used.
 *
 * This function automatically calls the `Level.UpdateVisibility` after setting the flags so that
 * the changes will be immediately visible.
 */
function clearFloorDisplayFlags() {
    setAllDisplayFlags(isaac_typescript_definitions_1.DisplayFlagZero);
}
exports.clearFloorDisplayFlags = clearFloorDisplayFlags;
/**
 * Helper function to set the value of `DisplayFlag` for a room 0.
 *
 * This function automatically accounts for if MinimapAPI is being used.
 *
 * This function automatically calls the `Level.UpdateVisibility` after setting the flags so that
 * the changes will be immediately visible.
 *
 * Note that if you clear the display flags of a room but then the player travels to the room (or an
 * adjacent room), the room will appear on the minimap again. If you want to permanently hide the
 * room even in this circumstance, use the `hideRoomOnMinimap` helper function instead.
 */
function clearRoomDisplayFlags(roomGridIndex) {
    setRoomDisplayFlags(roomGridIndex, isaac_typescript_definitions_1.DisplayFlagZero);
}
exports.clearRoomDisplayFlags = clearRoomDisplayFlags;
/**
 * Helper function to get the minimap `DisplayFlag` value for every room on the floor. Returns a map
 * that is indexed by the room's safe grid index.
 *
 * This function automatically accounts for if MinimapAPI is being used.
 *
 * @param minimapAPI Optional. If MinimapAPI should be used, if present. Default is true.
 */
function getFloorDisplayFlags(minimapAPI = true) {
    const displayFlagsMap = new Map();
    for (const roomDescriptor of (0, rooms_1.getRoomsInsideGrid)()) {
        const roomGridIndex = roomDescriptor.SafeGridIndex;
        const displayFlags = getRoomDisplayFlags(roomGridIndex, minimapAPI);
        displayFlagsMap.set(roomGridIndex, displayFlags);
    }
    return displayFlagsMap;
}
exports.getFloorDisplayFlags = getFloorDisplayFlags;
/**
 * Helper function to get a particular room's minimap display flags (e.g. whether it is visible and
 * so on).
 *
 * This function automatically accounts for if MinimapAPI is being used.
 *
 * @param roomGridIndex Optional. Default is the current room index.
 * @param minimapAPI Optional. If MinimapAPI should be used, if present. Default is true.
 */
function getRoomDisplayFlags(roomGridIndex, minimapAPI = true) {
    if (roomGridIndex === undefined) {
        roomGridIndex = (0, roomData_1.getRoomGridIndex)();
    }
    if (MinimapAPI === undefined || !minimapAPI) {
        const roomDescriptor = (0, roomData_1.getRoomDescriptor)(roomGridIndex);
        return roomDescriptor.DisplayFlags;
    }
    const minimapAPIRoomDescriptor = MinimapAPI.GetRoomByIdx(roomGridIndex);
    (0, utils_1.assertDefined)(minimapAPIRoomDescriptor, `Failed to get the MinimapAPI room descriptor for the room at grid index: ${roomGridIndex}`);
    return minimapAPIRoomDescriptor.GetDisplayFlags();
}
exports.getRoomDisplayFlags = getRoomDisplayFlags;
/**
 * Helper function to hide a specific room on the minimap.
 *
 * If you want the room to be permanently hidden, you must to call this function on every new room.
 * This is because if the player enters into the room or walks into an adjacent room, the room will
 * reappear on the minimap.
 *
 * This function automatically accounts for if MinimapAPI is being used.
 */
function hideRoomOnMinimap(roomGridIndex) {
    clearRoomDisplayFlags(roomGridIndex);
    // In vanilla, the map only updates at the beginning of every room. In MinimapAPI, it constant
    // updates, so we must specifically tell MinimapAPI that the room should be hidden using the
    // `Hidden` property.
    if (MinimapAPI !== undefined) {
        const minimapAPIRoomDescriptor = MinimapAPI.GetRoomByIdx(roomGridIndex);
        (0, utils_1.assertDefined)(minimapAPIRoomDescriptor, `Failed to get the MinimapAPI room descriptor for the room at grid index: ${roomGridIndex}`);
        minimapAPIRoomDescriptor.Hidden = true;
    }
}
exports.hideRoomOnMinimap = hideRoomOnMinimap;
/**
 * Helper function to check if a given room is visible on the minimap.
 *
 * @param roomGridIndexOrRoomDescriptor The room to check.
 * @param minimapAPI Optional. Whether MinimapAPI should be used, if present. Default is true.
 */
function isRoomVisible(roomGridIndexOrRoomDescriptor, minimapAPI = true) {
    const roomGridIndex = (0, types_1.isInteger)(roomGridIndexOrRoomDescriptor)
        ? roomGridIndexOrRoomDescriptor
        : roomGridIndexOrRoomDescriptor.SafeGridIndex;
    const roomDisplayFlags = getRoomDisplayFlags(roomGridIndex, minimapAPI);
    return roomDisplayFlags !== isaac_typescript_definitions_1.DisplayFlagZero;
}
exports.isRoomVisible = isRoomVisible;
/**
 * Helper function to set the minimap `DisplayFlag` value for every room on the floor at once.
 *
 * This function automatically calls the `Level.UpdateVisibility` after setting the flags so that
 * the changes will be immediately visible.
 *
 * This function automatically accounts for if MinimapAPI is being used.
 */
function setAllDisplayFlags(displayFlags) {
    for (const room of (0, rooms_1.getRoomsInsideGrid)()) {
        // We pass false to the `updateVisibility` argument as a small optimization.
        setRoomDisplayFlags(room.SafeGridIndex, displayFlags, false);
    }
    // In vanilla, we must call the "Level.UpdateVisibility" method for the changes to be visible.
    if (MinimapAPI === undefined) {
        const level = cachedClasses_1.game.GetLevel();
        level.UpdateVisibility();
    }
}
exports.setAllDisplayFlags = setAllDisplayFlags;
/**
 * Helper function to set the minimap `DisplayFlag` value for multiple rooms at once.
 *
 * This function automatically calls the `Level.UpdateVisibility` after setting the flags so that
 * the changes will be immediately visible.
 *
 * This function automatically accounts for if MinimapAPI is being used.
 *
 * @param displayFlagsMap A map of the display flags that is indexed by the room's safe grid index.
 */
function setFloorDisplayFlags(displayFlagsMap) {
    for (const [roomGridIndex, displayFlags] of displayFlagsMap) {
        // We pass false to the `updateVisibility` argument as a small optimization.
        setRoomDisplayFlags(roomGridIndex, displayFlags, false);
    }
    // In vanilla, we must call the "Level.UpdateVisibility" method for the changes to be visible.
    if (MinimapAPI === undefined) {
        const level = cachedClasses_1.game.GetLevel();
        level.UpdateVisibility();
    }
}
exports.setFloorDisplayFlags = setFloorDisplayFlags;
/**
 * Helper function to set a particular room's minimap display flags (e.g. whether it is visible and
 * so on).
 *
 * This function automatically accounts for if MinimapAPI is being used.
 *
 * @param roomGridIndex Set to undefined to use the current room index.
 * @param displayFlags The bit flags value to set. (See the `DisplayFlag` enum.)
 * @param updateVisibility Optional. Whether to call the `Level.UpdateVisibility` method in order to
 *                         make the changes immediately visible. Default is true. Set this to false
 *                         if you are doing a bunch of display flag setting and then manually call
 *                         the `Level.UpdateVisibility` method after you are done.
 */
function setRoomDisplayFlags(roomGridIndex, displayFlags, updateVisibility = true) {
    if (roomGridIndex === undefined) {
        roomGridIndex = (0, roomData_1.getRoomGridIndex)();
    }
    if (MinimapAPI === undefined) {
        const roomDescriptor = (0, roomData_1.getRoomDescriptor)(roomGridIndex);
        roomDescriptor.DisplayFlags = displayFlags;
        if (updateVisibility) {
            const level = cachedClasses_1.game.GetLevel();
            level.UpdateVisibility();
        }
    }
    else {
        const minimapAPIRoomDescriptor = MinimapAPI.GetRoomByIdx(roomGridIndex);
        (0, utils_1.assertDefined)(minimapAPIRoomDescriptor, `Failed to get the MinimapAPI room descriptor for the room at grid index: ${roomGridIndex}`);
        minimapAPIRoomDescriptor.SetDisplayFlags(displayFlags);
    }
}
exports.setRoomDisplayFlags = setRoomDisplayFlags;
