local ____lualib = require("lualib_bundle")
local Map = ____lualib.Map
local __TS__New = ____lualib.__TS__New
local __TS__Class = ____lualib.__TS__Class
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
local __TS__DecorateLegacy = ____lualib.__TS__DecorateLegacy
local __TS__Iterator = ____lualib.__TS__Iterator
local ____exports = {}
local getStoredPickupIndex
local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
local EntityType = ____isaac_2Dtypescript_2Ddefinitions.EntityType
local ModCallback = ____isaac_2Dtypescript_2Ddefinitions.ModCallback
local RoomType = ____isaac_2Dtypescript_2Ddefinitions.RoomType
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 ____entities = require("functions.entities")
local getEntityID = ____entities.getEntityID
local ____frames = require("functions.frames")
local onOrBeforeRoomFrame = ____frames.onOrBeforeRoomFrame
local ____roomData = require("functions.roomData")
local getRoomListIndex = ____roomData.getRoomListIndex
local ____stage = require("functions.stage")
local onAscent = ____stage.onAscent
local ____vector = require("functions.vector")
local vectorEquals = ____vector.vectorEquals
local ____DefaultMap = require("classes.DefaultMap")
local DefaultMap = ____DefaultMap.DefaultMap
local ____Feature = require("classes.private.Feature")
local Feature = ____Feature.Feature
function getStoredPickupIndex(self, pickup, pickupDescriptions)
    for ____, ____value in __TS__Iterator(pickupDescriptions) do
        local pickupIndex = ____value[1]
        local pickupDescription = ____value[2]
        if vectorEquals(nil, pickupDescription.position, pickup.Position) and pickupDescription.initSeed == pickup.InitSeed then
            return pickupIndex
        end
    end
    return nil
end
local v = {
    run = {
        pickupCounter = 0,
        pickupDataTreasureRooms = __TS__New(Map),
        pickupDataBossRooms = __TS__New(Map)
    },
    level = {pickupData = __TS__New(
        DefaultMap,
        function() return __TS__New(Map) end
    )},
    room = {pickupIndexes = __TS__New(Map)}
}
____exports.PickupIndexCreation = __TS__Class()
local PickupIndexCreation = ____exports.PickupIndexCreation
PickupIndexCreation.name = "PickupIndexCreation"
__TS__ClassExtends(PickupIndexCreation, Feature)
function PickupIndexCreation.prototype.____constructor(self, roomHistory, saveDataManager)
    Feature.prototype.____constructor(self)
    self.v = v
    self.postPickupInit = function(____, pickup)
        self:setPickupIndex(pickup)
    end
    self.postEntityRemovePickup = function(____, entity)
        self:checkDespawningFromPlayerLeavingRoom(entity)
    end
    self.featuresUsed = {ISCFeature.ROOM_HISTORY, ISCFeature.SAVE_DATA_MANAGER}
    self.callbacksUsed = {{ModCallback.POST_PICKUP_INIT, self.postPickupInit}, {ModCallback.POST_ENTITY_REMOVE, self.postEntityRemovePickup, {EntityType.PICKUP}}}
    self.roomHistory = roomHistory
    self.saveDataManager = saveDataManager
end
function PickupIndexCreation.prototype.setPickupIndex(self, pickup)
    local ptrHash = GetPtrHash(pickup)
    if v.room.pickupIndexes:has(ptrHash) then
        return
    end
    local pickupIndexFromLevelData = self:getPickupIndexFromPreviousData(pickup)
    local room = game:GetRoom()
    local isFirstVisit = room:IsFirstVisit()
    if pickupIndexFromLevelData ~= nil and not isFirstVisit and onOrBeforeRoomFrame(nil, 0) then
        v.room.pickupIndexes:set(ptrHash, pickupIndexFromLevelData)
        return
    end
    local ____v_run_0, ____pickupCounter_1 = v.run, "pickupCounter"
    ____v_run_0[____pickupCounter_1] = ____v_run_0[____pickupCounter_1] + 1
    v.room.pickupIndexes:set(ptrHash, v.run.pickupCounter)
end
function PickupIndexCreation.prototype.getPickupIndexFromPreviousData(self, pickup)
    local roomListIndex = getRoomListIndex(nil)
    local pickupDescriptions = v.level.pickupData:getAndSetDefault(roomListIndex)
    local pickupIndex = getStoredPickupIndex(nil, pickup, pickupDescriptions)
    if pickupIndex == nil then
        pickupIndex = self:getPostAscentPickupIndex(pickup)
    end
    return pickupIndex
end
function PickupIndexCreation.prototype.checkDespawningFromPlayerLeavingRoom(self, entity)
    local ptrHash = GetPtrHash(entity)
    local pickupIndex = v.room.pickupIndexes:get(ptrHash)
    if pickupIndex == nil then
        return
    end
    if not self.roomHistory:isLeavingRoom() then
        return
    end
    self:trackDespawningPickupMetadata(entity, pickupIndex)
end
function PickupIndexCreation.prototype.trackDespawningPickupMetadata(self, entity, pickupIndex)
    local previousRoomDescription = self.roomHistory:getLatestRoomDescription()
    if previousRoomDescription == nil then
        return
    end
    local previousRoomListIndex = previousRoomDescription.roomListIndex
    local pickupDescriptions = v.level.pickupData:getAndSetDefault(previousRoomListIndex)
    local pickupDescription = {position = entity.Position, initSeed = entity.InitSeed}
    pickupDescriptions:set(pickupIndex, pickupDescription)
    local pickupDataMapForCurrentRoom = self:getPickupDataMapForCurrentRoom()
    if pickupDataMapForCurrentRoom ~= nil then
        pickupDataMapForCurrentRoom:set(pickupIndex, pickupDescription)
    end
    if self.saveDataManager:saveDataManagerInMenu() then
        self.saveDataManager:saveDataManagerSave()
    end
end
function PickupIndexCreation.prototype.getPickupDataMapForCurrentRoom(self)
    if onAscent(nil) then
        return nil
    end
    local room = game:GetRoom()
    local roomType = room:GetType()
    repeat
        local ____switch20 = roomType
        local ____cond20 = ____switch20 == RoomType.TREASURE
        if ____cond20 then
            do
                return v.run.pickupDataTreasureRooms
            end
        end
        ____cond20 = ____cond20 or ____switch20 == RoomType.BOSS
        if ____cond20 then
            do
                return v.run.pickupDataBossRooms
            end
        end
        do
            do
                return nil
            end
        end
    until true
end
function PickupIndexCreation.prototype.getPostAscentPickupIndex(self, pickup)
    if not onAscent(nil) then
        return nil
    end
    local room = game:GetRoom()
    local roomType = room:GetType()
    repeat
        local ____switch26 = roomType
        local ____cond26 = ____switch26 == RoomType.TREASURE
        if ____cond26 then
            do
                return getStoredPickupIndex(nil, pickup, v.run.pickupDataTreasureRooms)
            end
        end
        ____cond26 = ____cond26 or ____switch26 == RoomType.BOSS
        if ____cond26 then
            do
                return getStoredPickupIndex(nil, pickup, v.run.pickupDataBossRooms)
            end
        end
        do
            do
                return nil
            end
        end
    until true
end
function PickupIndexCreation.prototype.getPickupIndex(self, pickup)
    local ptrHash = GetPtrHash(pickup)
    local pickupIndexInitial = v.room.pickupIndexes:get(ptrHash)
    if pickupIndexInitial ~= nil then
        return pickupIndexInitial
    end
    self:setPickupIndex(pickup)
    local pickupIndex = v.room.pickupIndexes:get(ptrHash)
    if pickupIndex ~= nil then
        return pickupIndex
    end
    local entityID = getEntityID(nil, pickup)
    error("Failed to generate a new pickup index for pickup: " .. entityID)
end
__TS__DecorateLegacy({Exported}, PickupIndexCreation.prototype, "getPickupIndex", true)
return ____exports
