local ____lualib = require("lualib_bundle")
local Map = ____lualib.Map
local __TS__New = ____lualib.__TS__New
local Set = ____lualib.Set
local __TS__Class = ____lualib.__TS__Class
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
local __TS__Iterator = ____lualib.__TS__Iterator
local __TS__DecorateLegacy = ____lualib.__TS__DecorateLegacy
local ____exports = {}
local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
local CollectibleType = ____isaac_2Dtypescript_2Ddefinitions.CollectibleType
local GridCollisionClass = ____isaac_2Dtypescript_2Ddefinitions.GridCollisionClass
local GridEntityType = ____isaac_2Dtypescript_2Ddefinitions.GridEntityType
local ModCallback = ____isaac_2Dtypescript_2Ddefinitions.ModCallback
local ____cachedClasses = require("core.cachedClasses")
local game = ____cachedClasses.game
local ____decorators = require("decorators")
local Exported = ____decorators.Exported
local ____ISCFeature = require("enums.ISCFeature")
local ISCFeature = ____ISCFeature.ISCFeature
local ____ModCallbackCustom = require("enums.ModCallbackCustom")
local ModCallbackCustom = ____ModCallbackCustom.ModCallbackCustom
local ____gridEntities = require("functions.gridEntities")
local removeGridEntity = ____gridEntities.removeGridEntity
local spawnGridEntityWithVariant = ____gridEntities.spawnGridEntityWithVariant
local ____players = require("functions.players")
local getPlayerFromPtr = ____players.getPlayerFromPtr
local ____roomData = require("functions.roomData")
local getRoomListIndex = ____roomData.getRoomListIndex
local ____types = require("functions.types")
local isInteger = ____types.isInteger
local ____utils = require("functions.utils")
local assertDefined = ____utils.assertDefined
local ____vector = require("functions.vector")
local isVector = ____vector.isVector
local ____DefaultMap = require("classes.DefaultMap")
local DefaultMap = ____DefaultMap.DefaultMap
local ____Feature = require("classes.private.Feature")
local Feature = ____Feature.Feature
local v = {
    level = {customGridEntities = __TS__New(
        DefaultMap,
        function() return __TS__New(Map) end
    )},
    room = {
        genericPropPtrHashes = __TS__New(Set),
        manuallyUsingShovel = false
    }
}
____exports.CustomGridEntities = __TS__Class()
local CustomGridEntities = ____exports.CustomGridEntities
CustomGridEntities.name = "CustomGridEntities"
__TS__ClassExtends(CustomGridEntities, Feature)
function CustomGridEntities.prototype.____constructor(self, runInNFrames)
    Feature.prototype.____constructor(self)
    self.v = v
    self.preUseItemWeNeedToGoDeeper = function(____, _collectibleType, _rng, player, _useFlags, _activeSlot, _customVarData)
        local room = game:GetRoom()
        local roomListIndex = getRoomListIndex(nil)
        local roomCustomGridEntities = v.level.customGridEntities:get(roomListIndex)
        if roomCustomGridEntities == nil then
            return nil
        end
        local gridIndex = room:GetGridIndex(player.Position)
        local customGridEntity = roomCustomGridEntities:get(gridIndex)
        if customGridEntity == nil then
            return nil
        end
        if customGridEntity.gridCollisionClass ~= GridCollisionClass.NONE then
            return nil
        end
        removeGridEntity(nil, customGridEntity.gridIndex, false)
        local entityPtr = EntityPtr(player)
        self.runInNFrames:runNextGameFrame(function()
            local futurePlayer = getPlayerFromPtr(nil, entityPtr)
            if futurePlayer == nil then
                return
            end
            v.room.manuallyUsingShovel = true
            futurePlayer:UseActiveItem(CollectibleType.WE_NEED_TO_GO_DEEPER)
            v.room.manuallyUsingShovel = false
        end)
        return true
    end
    self.postNewRoomReordered = function()
        local roomListIndex = getRoomListIndex(nil)
        local roomCustomGridEntities = v.level.customGridEntities:get(roomListIndex)
        if roomCustomGridEntities == nil then
            return
        end
        local room = game:GetRoom()
        for ____, ____value in __TS__Iterator(roomCustomGridEntities) do
            local gridIndex = ____value[1]
            local data = ____value[2]
            do
                local decoration = room:GetGridEntity(gridIndex)
                if decoration == nil then
                    roomCustomGridEntities:delete(gridIndex)
                    goto __continue12
                end
                if data.anm2Path ~= nil then
                    local sprite = decoration:GetSprite()
                    sprite:Load(data.anm2Path, true)
                    local animationToPlay = data.defaultAnimation or sprite:GetDefaultAnimation()
                    sprite:Play(animationToPlay, true)
                end
            end
            ::__continue12::
        end
    end
    self.featuresUsed = {ISCFeature.RUN_IN_N_FRAMES}
    self.callbacksUsed = {{ModCallback.PRE_USE_ITEM, self.preUseItemWeNeedToGoDeeper, {CollectibleType.WE_NEED_TO_GO_DEEPER}}}
    self.customCallbacksUsed = {{ModCallbackCustom.POST_NEW_ROOM_REORDERED, self.postNewRoomReordered}}
    self.runInNFrames = runInNFrames
end
function CustomGridEntities.prototype.spawnCustomGridEntity(self, gridEntityTypeCustom, gridIndexOrPosition, gridCollisionClass, anm2Path, defaultAnimation, baseGridEntityType, baseGridEntityVariant)
    if baseGridEntityType == nil then
        baseGridEntityType = GridEntityType.DECORATION
    end
    if baseGridEntityVariant == nil then
        baseGridEntityVariant = 0
    end
    local room = game:GetRoom()
    local roomListIndex = getRoomListIndex(nil)
    local gridIndex = isVector(nil, gridIndexOrPosition) and room:GetGridIndex(gridIndexOrPosition) or gridIndexOrPosition
    local customGridEntity = spawnGridEntityWithVariant(nil, baseGridEntityType, baseGridEntityVariant, gridIndexOrPosition)
    assertDefined(nil, customGridEntity, "Failed to spawn a custom grid entity.")
    if gridCollisionClass ~= nil then
        customGridEntity.CollisionClass = gridCollisionClass
    end
    if anm2Path ~= nil then
        local sprite = customGridEntity:GetSprite()
        sprite:Load(anm2Path, true)
        local animationToPlay = defaultAnimation or sprite:GetDefaultAnimation()
        sprite:Play(animationToPlay, true)
    end
    local customGridEntityData = {
        gridEntityTypeCustom = gridEntityTypeCustom,
        roomListIndex = roomListIndex,
        gridIndex = gridIndex,
        anm2Path = anm2Path,
        defaultAnimation = defaultAnimation,
        gridCollisionClass = gridCollisionClass
    }
    local roomCustomGridEntities = v.level.customGridEntities:getAndSetDefault(roomListIndex)
    roomCustomGridEntities:set(gridIndex, customGridEntityData)
    return customGridEntity
end
__TS__DecorateLegacy({Exported}, CustomGridEntities.prototype, "spawnCustomGridEntity", true)
function CustomGridEntities.prototype.removeCustomGridEntity(self, gridIndexOrPositionOrGridEntity, updateRoom)
    if updateRoom == nil then
        updateRoom = true
    end
    local room = game:GetRoom()
    local roomListIndex = getRoomListIndex(nil)
    local decoration
    if type(gridIndexOrPositionOrGridEntity) == "number" then
        local gridIndex = gridIndexOrPositionOrGridEntity
        local gridEntity = room:GetGridEntity(gridIndex)
        if gridEntity == nil then
            return nil
        end
        decoration = gridEntity
    elseif isVector(nil, gridIndexOrPositionOrGridEntity) then
        local position = gridIndexOrPositionOrGridEntity
        local gridEntity = room:GetGridEntityFromPos(position)
        if gridEntity == nil then
            return nil
        end
        decoration = gridEntity
    else
        decoration = gridIndexOrPositionOrGridEntity
    end
    local gridIndex = decoration:GetGridIndex()
    local roomCustomGridEntities = v.level.customGridEntities:getAndSetDefault(roomListIndex)
    local exists = roomCustomGridEntities:has(gridIndex)
    if not exists then
        return nil
    end
    roomCustomGridEntities:delete(gridIndex)
    removeGridEntity(nil, decoration, updateRoom)
    return decoration
end
__TS__DecorateLegacy({Exported}, CustomGridEntities.prototype, "removeCustomGridEntity", true)
function CustomGridEntities.prototype.getCustomGridEntities(self)
    local roomListIndex = getRoomListIndex(nil)
    local roomCustomGridEntities = v.level.customGridEntities:get(roomListIndex)
    if roomCustomGridEntities == nil then
        return {}
    end
    local room = game:GetRoom()
    local customGridEntities = {}
    for ____, ____value in __TS__Iterator(roomCustomGridEntities) do
        local gridIndex = ____value[1]
        local data = ____value[2]
        local gridEntity = room:GetGridEntity(gridIndex)
        if gridEntity ~= nil then
            customGridEntities[#customGridEntities + 1] = {gridEntity = gridEntity, data = data}
        end
    end
    return customGridEntities
end
__TS__DecorateLegacy({Exported}, CustomGridEntities.prototype, "getCustomGridEntities", true)
function CustomGridEntities.prototype.getCustomGridEntityType(self, gridEntityOrGridIndex)
    if not self.initialized then
        return nil
    end
    local gridIndex = isInteger(nil, gridEntityOrGridIndex) and gridEntityOrGridIndex or gridEntityOrGridIndex:GetGridIndex()
    local roomListIndex = getRoomListIndex(nil)
    local roomCustomGridEntities = v.level.customGridEntities:get(roomListIndex)
    if roomCustomGridEntities == nil then
        return nil
    end
    for ____, ____value in __TS__Iterator(roomCustomGridEntities) do
        local _gridIndex = ____value[1]
        local data = ____value[2]
        if data.gridIndex == gridIndex then
            return data.gridEntityTypeCustom
        end
    end
    return nil
end
__TS__DecorateLegacy({Exported}, CustomGridEntities.prototype, "getCustomGridEntityType", true)
function CustomGridEntities.prototype.isCustomGridEntity(self, gridEntityOrGridIndex)
    local gridEntityTypeCustom = self:getCustomGridEntityType(gridEntityOrGridIndex)
    return gridEntityTypeCustom ~= nil
end
__TS__DecorateLegacy({Exported}, CustomGridEntities.prototype, "isCustomGridEntity", true)
return ____exports
