local ____lualib = require("lualib_bundle")
local Set = ____lualib.Set
local __TS__New = ____lualib.__TS__New
local ____exports = {}
local ____cachedEnumValues = require("arrays.cachedEnumValues")
local DOOR_SLOT_FLAG_VALUES = ____cachedEnumValues.DOOR_SLOT_FLAG_VALUES
local ____cachedClasses = require("core.cachedClasses")
local game = ____cachedClasses.game
local ____doors = require("functions.doors")
local doorSlotFlagToDoorSlot = ____doors.doorSlotFlagToDoorSlot
local ____flag = require("functions.flag")
local hasFlag = ____flag.hasFlag
--- Helper function to get the room data for the current room.
-- 
-- You can optionally provide a room grid index as an argument to get the data for that room
-- instead.
-- 
-- (The version of the function without any arguments will not return undefined since the current
-- room is guaranteed to have data.)
-- Helper function to get the room data for the current or provided room.
-- 
-- @param roomGridIndex Optional. Default is the current room index.
-- @returns The room data for the room or undefined if the provided room does not have any data.
function ____exports.getRoomData(self, roomGridIndex)
    local roomDescriptor = ____exports.getRoomDescriptor(nil, roomGridIndex)
    return roomDescriptor.Data
end
--- Helper function to get the descriptor for a room.
-- 
-- @param roomGridIndex Optional. Default is the current room index.
function ____exports.getRoomDescriptor(self, roomGridIndex)
    local level = game:GetLevel()
    if roomGridIndex == nil then
        roomGridIndex = ____exports.getRoomGridIndex(nil)
    end
    return level:GetRoomByIdx(roomGridIndex)
end
--- Alias for the `Level.GetCurrentRoomDesc` method. Use this to make it more clear what type of
-- `RoomDescriptor` object that you are retrieving.
function ____exports.getRoomDescriptorReadOnly(self)
    local level = game:GetLevel()
    return level:GetCurrentRoomDesc()
end
--- Helper function to get the grid index of the current room.
-- 
-- - If the current room is inside of the grid, this function will return the `SafeGridIndex` from
--   the room descriptor. (The safe grid index is defined as the top-left 1x1 section that the room
--   overlaps with, or the top-right 1x1 section of a `RoomType.SHAPE_LTL` room.)
-- - If the current room is outside of the grid, it will return the index from the
--   `Level.GetCurrentRoomIndex` method (since `SafeGridIndex` is bugged for these cases, as
--   demonstrated by entering a Genesis room and entering `l
--   print(Game():GetLevel():GetCurrentRoomDesc().SafeGridIndex)` into the console).
-- 
-- Use this function instead of the `Level.GetCurrentRoomIndex` method directly because the latter
-- will return the specific 1x1 quadrant that the player entered the room at. For most situations,
-- using the safe grid index is more reliable than this.
-- 
-- Data structures that store data per room should use the room's `ListIndex` instead of
-- `SafeGridIndex`, since the former is unique across different dimensions.
function ____exports.getRoomGridIndex(self)
    local level = game:GetLevel()
    local currentRoomIndex = level:GetCurrentRoomIndex()
    if currentRoomIndex < 0 then
        return currentRoomIndex
    end
    local roomDescriptor = ____exports.getRoomDescriptorReadOnly(nil)
    return roomDescriptor.SafeGridIndex
end
--- Helper function to get the set of allowed door slots for the room at the supplied grid index.
-- This corresponds to the doors that are enabled in the STB/XML file for the room.
function ____exports.getRoomAllowedDoors(self, roomGridIndex)
    local allowedDoors = __TS__New(Set)
    local roomData = ____exports.getRoomData(nil, roomGridIndex)
    if roomData == nil then
        return allowedDoors
    end
    for ____, doorSlotFlag in ipairs(DOOR_SLOT_FLAG_VALUES) do
        if hasFlag(nil, roomData.Doors, doorSlotFlag) then
            local doorSlot = doorSlotFlagToDoorSlot(nil, doorSlotFlag)
            allowedDoors:add(doorSlot)
        end
    end
    return allowedDoors
end
--- Helper function to get the list grid index of the provided room, which is equal to the index in
-- the `RoomList.Get` method. In other words, this is equal to the order that the room was created
-- by the floor generation algorithm.
-- 
-- Use this as an index for data structures that store data per room, since it is unique across
-- different dimensions.
-- 
-- @param roomGridIndex Optional. Default is the current room index.
function ____exports.getRoomListIndex(self, roomGridIndex)
    local roomDescriptor = ____exports.getRoomDescriptor(nil, roomGridIndex)
    return roomDescriptor.ListIndex
end
--- Helper function to get the name of the current room as it appears in the STB/XML data.
-- 
-- You can optionally provide a room grid index as an argument to get the name for that room
-- instead.
-- 
-- (The version of the function without any arguments will not return undefined since the current
-- room is guaranteed to have data.)
-- 
-- If you want to get the room name for a specific room type, use the `getRoomTypeName` function.
-- Helper function to get the name of the room as it appears in the STB/XML data.
-- 
-- If you want to get the room name for a specific room type, use the `getRoomTypeName` function.
-- 
-- @param roomGridIndex Optional. Default is the current room index.
-- @returns The room name. Returns undefined if the room data was not found.
function ____exports.getRoomName(self, roomGridIndex)
    local roomData = ____exports.getRoomData(nil, roomGridIndex)
    local ____temp_0
    if roomData == nil then
        ____temp_0 = nil
    else
        ____temp_0 = roomData.Name
    end
    return ____temp_0
end
--- Helper function to get the shape of the current room as it appears in the STB/XML data.
-- 
-- You can optionally provide a room grid index as an argument to get the shape for that room
-- instead.
-- 
-- (The version of the function without any arguments will not return undefined since the current
-- room is guaranteed to have data.)
-- Helper function to get the shape of the room as it appears in the STB/XML data.
-- 
-- @param roomGridIndex Optional. Default is the current room index.
-- @returns The room shape. Returns undefined if the room data was not found.
function ____exports.getRoomShape(self, roomGridIndex)
    local roomData = ____exports.getRoomData(nil, roomGridIndex)
    local ____temp_1
    if roomData == nil then
        ____temp_1 = nil
    else
        ____temp_1 = roomData.Shape
    end
    return ____temp_1
end
--- Helper function to get the stage ID for the current room as it appears in the STB/XML data.
-- 
-- The room stage ID will correspond to the first number in the filename of the XML/STB file. For
-- example, a Depths room would have a stage ID of `StageID.DEPTHS` (7).
-- 
-- You can optionally provide a room grid index as an argument to get the stage ID for that room
-- instead.
-- 
-- (The version of the function without any arguments will not return undefined since the current
-- room is guaranteed to have data.)
-- Helper function to get the stage ID for a room as it appears in the STB/XML data.
-- 
-- The room stage ID will correspond to the first number in the filename of the XML/STB file. For
-- example, a Depths room would have a stage ID of `StageID.DEPTHS` (7).
-- 
-- @param roomGridIndex Optional. Default is the current room index.
-- @returns The room stage ID. Returns undefined if the room data was not found.
function ____exports.getRoomStageID(self, roomGridIndex)
    local roomData = ____exports.getRoomData(nil, roomGridIndex)
    local ____temp_2
    if roomData == nil then
        ____temp_2 = nil
    else
        ____temp_2 = roomData.StageID
    end
    return ____temp_2
end
--- Helper function to get the sub-type for the current room as it appears in the STB/XML data.
-- 
-- The room sub-type will correspond to different things depending on what XML/STB file it draws
-- from. For example, in the "00.special rooms.stb" file, an Angel Room with a sub-type of 0 will
-- correspond to a normal Angel Room and a sub-type of 1 will correspond to an Angel Room shop from
-- The Stairway.
-- 
-- You can optionally provide a room grid index as an argument to get the sub-type for that room
-- instead.
-- 
-- (The version of the function without any arguments will not return undefined since the current
-- room is guaranteed to have data.)
-- Helper function to get the sub-type for a room as it appears in the STB/XML data.
-- 
-- The room sub-type will correspond to different things depending on what XML/STB file it draws
-- from. For example, in the "00.special rooms.stb" file, an Angel Room with a sub-type of 0 will
-- correspond to a normal Angel Room and a sub-type of 1 will correspond to an Angel Room shop from
-- The Stairway.
-- 
-- @param roomGridIndex Optional. Default is the current room index.
-- @returns The room sub-type. Returns undefined if the room data was not found.
function ____exports.getRoomSubType(self, roomGridIndex)
    local roomData = ____exports.getRoomData(nil, roomGridIndex)
    local ____temp_3
    if roomData == nil then
        ____temp_3 = nil
    else
        ____temp_3 = roomData.Subtype
    end
    return ____temp_3
end
--- Helper function to get the type for the current room as it appears in the STB/XML data.
-- 
-- You can optionally provide a room grid index as an argument to get the type for that room
-- instead.
-- 
-- (The version of the function without any arguments will not return undefined since the current
-- room is guaranteed to have data.)
-- Helper function to get the type for a room as it appears in the STB/XML data.
-- Helper function for getting the type of the room with the given grid index.
-- 
-- @param roomGridIndex Optional. Default is the current room index.
-- @returns The room type. Returns undefined if the room data was not found.
-- @param roomGridIndex Optional. Default is the current room index.
-- @returns The room data type. Returns -1 if the room data was not found.
function ____exports.getRoomType(self, roomGridIndex)
    local roomData = ____exports.getRoomData(nil, roomGridIndex)
    local ____temp_4
    if roomData == nil then
        ____temp_4 = nil
    else
        ____temp_4 = roomData.Type
    end
    return ____temp_4
end
--- Helper function to get the variant for the current room as it appears in the STB/XML data.
-- 
-- You can think of a room variant as its identifier. For example, to go to Basement room #123, you
-- would use a console command of `goto d.123` while on the Basement.
-- 
-- You can optionally provide a room grid index as an argument to get the variant for that room
-- instead.
-- 
-- (The version of the function without any arguments will not return undefined since the current
-- room is guaranteed to have data.)
-- Helper function to get the variant for a room as it appears in the STB/XML data.
-- 
-- You can think of a room variant as its identifier. For example, to go to Basement room #123, you
-- would use a console command of `goto d.123` while on the Basement.
-- 
-- @param roomGridIndex Optional. Default is the current room index.
-- @returns The room variant. Returns undefined if the room data was not found.
function ____exports.getRoomVariant(self, roomGridIndex)
    local roomData = ____exports.getRoomData(nil, roomGridIndex)
    return roomData == nil and -1 or roomData.Variant
end
--- Note that the room visited count will be inaccurate during the period before the `POST_NEW_ROOM`
-- callback has fired (i.e. when entities are initializing and performing their first update). This
-- is because the variable is only incremented immediately before the `POST_NEW_ROOM` callback
-- fires.
-- 
-- @param roomGridIndex Optional. Default is the current room index.
function ____exports.getRoomVisitedCount(self, roomGridIndex)
    local roomDescriptor = ____exports.getRoomDescriptor(nil, roomGridIndex)
    return roomDescriptor.VisitedCount
end
--- Helper function to set the data for a given room. This will change the room type, contents, and
-- so on.
function ____exports.setRoomData(self, roomGridIndex, roomData)
    local roomDescriptor = ____exports.getRoomDescriptor(nil, roomGridIndex)
    roomDescriptor.Data = roomData
end
return ____exports
