local ____lualib = require("lualib_bundle")
local __TS__ArrayMap = ____lualib.__TS__ArrayMap
local __TS__New = ____lualib.__TS__New
local __TS__SparseArrayNew = ____lualib.__TS__SparseArrayNew
local __TS__SparseArrayPush = ____lualib.__TS__SparseArrayPush
local __TS__SparseArraySpread = ____lualib.__TS__SparseArraySpread
local ____exports = {}
local getVanillaWallGridIndexSetForRectangleRoomShape
local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
local BossID = ____isaac_2Dtypescript_2Ddefinitions.BossID
local RoomShape = ____isaac_2Dtypescript_2Ddefinitions.RoomShape
local ____cachedEnumValues = require("arrays.cachedEnumValues")
local ROOM_SHAPE_VALUES = ____cachedEnumValues.ROOM_SHAPE_VALUES
local ____cachedClasses = require("core.cachedClasses")
local game = ____cachedClasses.game
local ____CornerType = require("enums.CornerType")
local CornerType = ____CornerType.CornerType
local ____ReadonlyMap = require("types.ReadonlyMap")
local ReadonlyMap = ____ReadonlyMap.ReadonlyMap
local ____ReadonlySet = require("types.ReadonlySet")
local ReadonlySet = ____ReadonlySet.ReadonlySet
local ____gridIndex = require("functions.gridIndex")
local getGridIndexesBetween = ____gridIndex.getGridIndexesBetween
local ____roomShape = require("functions.roomShape")
local getRoomShapeCorners = ____roomShape.getRoomShapeCorners
local isLRoomShape = ____roomShape.isLRoomShape
local ____rooms = require("functions.rooms")
local inBossRoomOf = ____rooms.inBossRoomOf
local inHomeCloset = ____rooms.inHomeCloset
local ____utils = require("functions.utils")
local assertDefined = ____utils.assertDefined
--- 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 ____exports.getVanillaWallGridIndexSetForRoomShape(self, roomShape)
    local corners = getRoomShapeCorners(nil, roomShape)
    local lRoom = isLRoomShape(nil, roomShape)
    if lRoom and #corners ~= 6 then
        error(((("Failed to get the correct amount of corners for: RoomShape." .. RoomShape[roomShape]) .. " (") .. tostring(roomShape)) .. ")")
    end
    repeat
        local ____switch5 = roomShape
        local ____cond5 = ____switch5 == RoomShape.LTL
        if ____cond5 then
            do
                local topMiddle, topRight, middleLeft, middle, bottomLeft, bottomRight = table.unpack(corners)
                local ____ReadonlySet_1 = ReadonlySet
                local ____array_0 = __TS__SparseArrayNew(table.unpack(getGridIndexesBetween(nil, topMiddle.gridIndex, topRight.gridIndex, roomShape)))
                __TS__SparseArrayPush(
                    ____array_0,
                    table.unpack(getGridIndexesBetween(nil, middleLeft.gridIndex, middle.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_0,
                    table.unpack(getGridIndexesBetween(nil, bottomLeft.gridIndex, bottomRight.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_0,
                    table.unpack(getGridIndexesBetween(nil, middleLeft.gridIndex, bottomLeft.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_0,
                    table.unpack(getGridIndexesBetween(nil, topMiddle.gridIndex, middle.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_0,
                    table.unpack(getGridIndexesBetween(nil, topRight.gridIndex, bottomRight.gridIndex, roomShape))
                )
                return __TS__New(
                    ____ReadonlySet_1,
                    {__TS__SparseArraySpread(____array_0)}
                )
            end
        end
        ____cond5 = ____cond5 or ____switch5 == RoomShape.LTR
        if ____cond5 then
            do
                local topLeft, topMiddle, middle, middleRight, bottomLeft, bottomRight = table.unpack(corners)
                local ____ReadonlySet_3 = ReadonlySet
                local ____array_2 = __TS__SparseArrayNew(table.unpack(getGridIndexesBetween(nil, topLeft.gridIndex, topMiddle.gridIndex, roomShape)))
                __TS__SparseArrayPush(
                    ____array_2,
                    table.unpack(getGridIndexesBetween(nil, middle.gridIndex, middleRight.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_2,
                    table.unpack(getGridIndexesBetween(nil, bottomLeft.gridIndex, bottomRight.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_2,
                    table.unpack(getGridIndexesBetween(nil, topLeft.gridIndex, bottomLeft.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_2,
                    table.unpack(getGridIndexesBetween(nil, topMiddle.gridIndex, middle.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_2,
                    table.unpack(getGridIndexesBetween(nil, middleRight.gridIndex, bottomRight.gridIndex, roomShape))
                )
                return __TS__New(
                    ____ReadonlySet_3,
                    {__TS__SparseArraySpread(____array_2)}
                )
            end
        end
        ____cond5 = ____cond5 or ____switch5 == RoomShape.LBL
        if ____cond5 then
            do
                local topLeft, topRight, middleLeft, middle, bottomMiddle, bottomRight = table.unpack(corners)
                local ____ReadonlySet_5 = ReadonlySet
                local ____array_4 = __TS__SparseArrayNew(table.unpack(getGridIndexesBetween(nil, topLeft.gridIndex, topRight.gridIndex, roomShape)))
                __TS__SparseArrayPush(
                    ____array_4,
                    table.unpack(getGridIndexesBetween(nil, middleLeft.gridIndex, middle.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_4,
                    table.unpack(getGridIndexesBetween(nil, bottomMiddle.gridIndex, bottomRight.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_4,
                    table.unpack(getGridIndexesBetween(nil, topLeft.gridIndex, middleLeft.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_4,
                    table.unpack(getGridIndexesBetween(nil, middle.gridIndex, bottomMiddle.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_4,
                    table.unpack(getGridIndexesBetween(nil, topRight.gridIndex, bottomRight.gridIndex, roomShape))
                )
                return __TS__New(
                    ____ReadonlySet_5,
                    {__TS__SparseArraySpread(____array_4)}
                )
            end
        end
        ____cond5 = ____cond5 or ____switch5 == RoomShape.LBR
        if ____cond5 then
            do
                local topLeft, topRight, middle, middleRight, bottomLeft, bottomMiddle = table.unpack(corners)
                local ____ReadonlySet_7 = ReadonlySet
                local ____array_6 = __TS__SparseArrayNew(table.unpack(getGridIndexesBetween(nil, topLeft.gridIndex, topRight.gridIndex, roomShape)))
                __TS__SparseArrayPush(
                    ____array_6,
                    table.unpack(getGridIndexesBetween(nil, middle.gridIndex, middleRight.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_6,
                    table.unpack(getGridIndexesBetween(nil, bottomLeft.gridIndex, bottomMiddle.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_6,
                    table.unpack(getGridIndexesBetween(nil, topLeft.gridIndex, bottomLeft.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_6,
                    table.unpack(getGridIndexesBetween(nil, middle.gridIndex, bottomMiddle.gridIndex, roomShape))
                )
                __TS__SparseArrayPush(
                    ____array_6,
                    table.unpack(getGridIndexesBetween(nil, topRight.gridIndex, middleRight.gridIndex, roomShape))
                )
                return __TS__New(
                    ____ReadonlySet_7,
                    {__TS__SparseArraySpread(____array_6)}
                )
            end
        end
        do
            do
                return getVanillaWallGridIndexSetForRectangleRoomShape(nil, roomShape, corners)
            end
        end
    until true
end
function getVanillaWallGridIndexSetForRectangleRoomShape(self, roomShape, corners)
    if #corners ~= 4 then
        error("Failed to get the correct amount of corners for rectangular room shape.")
    end
    local topLeft, topRight, bottomLeft, bottomRight = table.unpack(corners)
    local ____ReadonlySet_9 = ReadonlySet
    local ____array_8 = __TS__SparseArrayNew(table.unpack(getGridIndexesBetween(nil, topLeft.gridIndex, topRight.gridIndex, roomShape)))
    __TS__SparseArrayPush(
        ____array_8,
        table.unpack(getGridIndexesBetween(nil, bottomLeft.gridIndex, bottomRight.gridIndex, roomShape))
    )
    __TS__SparseArrayPush(
        ____array_8,
        table.unpack(getGridIndexesBetween(nil, topLeft.gridIndex, bottomLeft.gridIndex, roomShape))
    )
    __TS__SparseArrayPush(
        ____array_8,
        table.unpack(getGridIndexesBetween(nil, topRight.gridIndex, bottomRight.gridIndex, roomShape))
    )
    return __TS__New(
        ____ReadonlySet_9,
        {__TS__SparseArraySpread(____array_8)}
    )
end
local ROOM_SHAPE_TO_WALL_GRID_INDEX_MAP = __TS__New(
    ReadonlyMap,
    __TS__ArrayMap(
        ROOM_SHAPE_VALUES,
        function(____, roomShape) return {
            roomShape,
            ____exports.getVanillaWallGridIndexSetForRoomShape(nil, roomShape)
        } end
    )
)
--- The Home closet is is 9x3, which is different from `RoomShape.IH` (which is 13x3).
local HOME_CLOSET_CORNERS = {
    {
        type = CornerType.TOP_LEFT,
        gridIndex = 30,
        position = Vector(60, 220)
    },
    {
        type = CornerType.TOP_RIGHT,
        gridIndex = 38,
        position = Vector(340, 220)
    },
    {
        type = CornerType.BOTTOM_LEFT,
        gridIndex = 90,
        position = Vector(60, 340)
    },
    {
        type = CornerType.BOTTOM_RIGHT,
        gridIndex = 98,
        position = Vector(340, 340)
    }
}
local HOME_CLOSET_CORNERS_SET = getVanillaWallGridIndexSetForRectangleRoomShape(nil, RoomShape.IH, HOME_CLOSET_CORNERS)
--- The Mother Boss Room is 15x11, which is different from `RoomShape.SHAPE_1x2` (which is 15x16).
local MOTHER_ROOM_CORNERS = {
    {
        type = CornerType.TOP_LEFT,
        gridIndex = 0,
        position = Vector(60, 140)
    },
    {
        type = CornerType.TOP_RIGHT,
        gridIndex = 14,
        position = Vector(580, 140)
    },
    {
        type = CornerType.BOTTOM_LEFT,
        gridIndex = 150,
        position = Vector(60, 500)
    },
    {
        type = CornerType.BOTTOM_RIGHT,
        gridIndex = 164,
        position = Vector(580, 500)
    }
}
local MOTHER_ROOM_CORNERS_SET = getVanillaWallGridIndexSetForRectangleRoomShape(nil, RoomShape.SHAPE_1x2, MOTHER_ROOM_CORNERS)
--- 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 ____exports.isVanillaWallGridIndex(self, gridIndex)
    local room = game:GetRoom()
    local roomShape = room:GetRoomShape()
    local wallGridIndexSet
    if inHomeCloset(nil) then
        wallGridIndexSet = HOME_CLOSET_CORNERS_SET
    elseif inBossRoomOf(nil, BossID.MOTHER) then
        wallGridIndexSet = MOTHER_ROOM_CORNERS_SET
    else
        wallGridIndexSet = ROOM_SHAPE_TO_WALL_GRID_INDEX_MAP:get(roomShape)
        assertDefined(
            nil,
            wallGridIndexSet,
            ((("Failed to find the wall grid index set for: RoomShape." .. RoomShape[roomShape]) .. " (") .. tostring(roomShape)) .. ")"
        )
    end
    return wallGridIndexSet:has(gridIndex)
end
return ____exports
