"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isVanillaWallGridIndex = exports.getVanillaWallGridIndexSetForRoomShape = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedEnumValues_1 = require("../cachedEnumValues");
const cachedClasses_1 = require("../core/cachedClasses");
const CornerType_1 = require("../enums/CornerType");
const ReadonlyMap_1 = require("../types/ReadonlyMap");
const ReadonlySet_1 = require("../types/ReadonlySet");
const gridIndex_1 = require("./gridIndex");
const roomShape_1 = require("./roomShape");
const rooms_1 = require("./rooms");
const utils_1 = require("./utils");
const ROOM_SHAPE_TO_WALL_GRID_INDEX_MAP = new ReadonlyMap_1.ReadonlyMap(cachedEnumValues_1.ROOM_SHAPE_VALUES.map((roomShape) => [
    roomShape,
    getVanillaWallGridIndexSetForRoomShape(roomShape),
]));
/** The Home closet is is 9x3, which is different from `RoomShape.IH` (which is 13x3). */
const HOME_CLOSET_CORNERS = [
    {
        type: CornerType_1.CornerType.TOP_LEFT,
        gridIndex: 30,
        position: Vector(60, 220),
    },
    {
        type: CornerType_1.CornerType.TOP_RIGHT,
        gridIndex: 38,
        position: Vector(340, 220),
    },
    {
        type: CornerType_1.CornerType.BOTTOM_LEFT,
        gridIndex: 90,
        position: Vector(60, 340),
    },
    {
        type: CornerType_1.CornerType.BOTTOM_RIGHT,
        gridIndex: 98,
        position: Vector(340, 340),
    },
];
const HOME_CLOSET_CORNERS_SET = getVanillaWallGridIndexSetForRectangleRoomShape(isaac_typescript_definitions_1.RoomShape.IH, HOME_CLOSET_CORNERS);
/**
 * The Mother Boss Room is 15x11, which is different from `RoomShape.SHAPE_1x2` (which is 15x16).
 */
const MOTHER_ROOM_CORNERS = [
    {
        type: CornerType_1.CornerType.TOP_LEFT,
        gridIndex: 0,
        position: Vector(60, 140),
    },
    {
        type: CornerType_1.CornerType.TOP_RIGHT,
        gridIndex: 14,
        position: Vector(580, 140),
    },
    {
        type: CornerType_1.CornerType.BOTTOM_LEFT,
        gridIndex: 150,
        position: Vector(60, 500),
    },
    {
        type: CornerType_1.CornerType.BOTTOM_RIGHT,
        gridIndex: 164,
        position: Vector(580, 500),
    },
];
const MOTHER_ROOM_CORNERS_SET = getVanillaWallGridIndexSetForRectangleRoomShape(isaac_typescript_definitions_1.RoomShape.SHAPE_1x2, MOTHER_ROOM_CORNERS);
/**
 * Helper function to get the set of grid indexes that represent where the walls are supposed to be
 * in a given room shape.
 *
 * This function only works reliably in vanilla rooms because in a modded room, it is possible to
 * place walls in a non-standard location.
 */
function getVanillaWallGridIndexSetForRoomShape(roomShape) {
    const corners = (0, roomShape_1.getRoomShapeCorners)(roomShape);
    const lRoom = (0, roomShape_1.isLRoomShape)(roomShape);
    if (lRoom && corners.length !== 6) {
        error(`Failed to get the correct amount of corners for: RoomShape.${isaac_typescript_definitions_1.RoomShape[roomShape]} (${roomShape})`);
    }
    switch (roomShape) {
        // 9
        case isaac_typescript_definitions_1.RoomShape.LTL: {
            const [topMiddle, topRight, middleLeft, middle, bottomLeft, bottomRight] = corners;
            return new ReadonlySet_1.ReadonlySet([
                // Horizontal
                ...(0, gridIndex_1.getGridIndexesBetween)(topMiddle.gridIndex, topRight.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(middleLeft.gridIndex, middle.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(bottomLeft.gridIndex, bottomRight.gridIndex, roomShape),
                // Vertical
                ...(0, gridIndex_1.getGridIndexesBetween)(middleLeft.gridIndex, bottomLeft.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(topMiddle.gridIndex, middle.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(topRight.gridIndex, bottomRight.gridIndex, roomShape),
            ]);
        }
        // 10
        case isaac_typescript_definitions_1.RoomShape.LTR: {
            const [topLeft, topMiddle, middle, middleRight, bottomLeft, bottomRight] = corners;
            return new ReadonlySet_1.ReadonlySet([
                // Horizontal
                ...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, topMiddle.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(middle.gridIndex, middleRight.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(bottomLeft.gridIndex, bottomRight.gridIndex, roomShape),
                // Vertical
                ...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, bottomLeft.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(topMiddle.gridIndex, middle.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(middleRight.gridIndex, bottomRight.gridIndex, roomShape),
            ]);
        }
        // 11
        case isaac_typescript_definitions_1.RoomShape.LBL: {
            const [topLeft, topRight, middleLeft, middle, bottomMiddle, bottomRight] = corners;
            return new ReadonlySet_1.ReadonlySet([
                // Horizontal
                ...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, topRight.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(middleLeft.gridIndex, middle.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(bottomMiddle.gridIndex, bottomRight.gridIndex, roomShape),
                // Vertical
                ...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, middleLeft.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(middle.gridIndex, bottomMiddle.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(topRight.gridIndex, bottomRight.gridIndex, roomShape),
            ]);
        }
        // 12
        case isaac_typescript_definitions_1.RoomShape.LBR: {
            const [topLeft, topRight, middle, middleRight, bottomLeft, bottomMiddle] = corners;
            return new ReadonlySet_1.ReadonlySet([
                // Horizontal
                ...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, topRight.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(middle.gridIndex, middleRight.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(bottomLeft.gridIndex, bottomMiddle.gridIndex, roomShape),
                // Vertical
                ...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, bottomLeft.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(middle.gridIndex, bottomMiddle.gridIndex, roomShape),
                ...(0, gridIndex_1.getGridIndexesBetween)(topRight.gridIndex, middleRight.gridIndex, roomShape),
            ]);
        }
        default: {
            return getVanillaWallGridIndexSetForRectangleRoomShape(roomShape, corners);
        }
    }
}
exports.getVanillaWallGridIndexSetForRoomShape = getVanillaWallGridIndexSetForRoomShape;
/**
 * Providing the room shape is necessary so that the `getGridIndexesBetween` function can use the
 * corresponding grid width.
 */
function getVanillaWallGridIndexSetForRectangleRoomShape(roomShape, corners) {
    if (corners.length !== 4) {
        error("Failed to get the correct amount of corners for rectangular room shape.");
    }
    const [topLeft, topRight, bottomLeft, bottomRight] = corners;
    return new ReadonlySet_1.ReadonlySet([
        // Horizontal
        ...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, topRight.gridIndex, roomShape),
        ...(0, gridIndex_1.getGridIndexesBetween)(bottomLeft.gridIndex, bottomRight.gridIndex, roomShape),
        // Vertical
        ...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, bottomLeft.gridIndex, roomShape),
        ...(0, gridIndex_1.getGridIndexesBetween)(topRight.gridIndex, bottomRight.gridIndex, roomShape),
    ]);
}
/**
 * Helper function to determine if a given grid index should have a wall generated by the vanilla
 * game. This is useful as a mechanism to distinguish between real walls and custom walls spawned by
 * mods.
 *
 * This function properly handles the special cases of the Mother boss room and the Home closet
 * rooms, which are both non-standard room shapes.
 */
function isVanillaWallGridIndex(gridIndex) {
    const room = cachedClasses_1.game.GetRoom();
    const roomShape = room.GetRoomShape();
    // Handle the special cases of non-standard room shapes.
    let wallGridIndexSet;
    if ((0, rooms_1.inHomeCloset)()) {
        wallGridIndexSet = HOME_CLOSET_CORNERS_SET;
    }
    else if ((0, rooms_1.inBossRoomOf)(isaac_typescript_definitions_1.BossID.MOTHER)) {
        wallGridIndexSet = MOTHER_ROOM_CORNERS_SET;
    }
    else {
        wallGridIndexSet = ROOM_SHAPE_TO_WALL_GRID_INDEX_MAP.get(roomShape);
        (0, utils_1.assertDefined)(wallGridIndexSet, `Failed to find the wall grid index set for: RoomShape.${isaac_typescript_definitions_1.RoomShape[roomShape]} (${roomShape})`);
    }
    return wallGridIndexSet.has(gridIndex);
}
exports.isVanillaWallGridIndex = isVanillaWallGridIndex;
