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__Iterator = ____lualib.__TS__Iterator
local ____exports = {}
local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
local ModCallback = ____isaac_2Dtypescript_2Ddefinitions.ModCallback
local ____ISCFeature = require("enums.ISCFeature")
local ISCFeature = ____ISCFeature.ISCFeature
local ____ModCallbackCustom = require("enums.ModCallbackCustom")
local ModCallbackCustom = ____ModCallbackCustom.ModCallbackCustom
local ____gridEntities = require("functions.gridEntities")
local getGridEntitiesMap = ____gridEntities.getGridEntitiesMap
local isGridEntityBroken = ____gridEntities.isGridEntityBroken
local ____Feature = require("classes.private.Feature")
local Feature = ____Feature.Feature
local v = {room = {initializedGridEntities = __TS__New(Map)}}
____exports.GridEntityUpdateDetection = __TS__Class()
local GridEntityUpdateDetection = ____exports.GridEntityUpdateDetection
GridEntityUpdateDetection.name = "GridEntityUpdateDetection"
__TS__ClassExtends(GridEntityUpdateDetection, Feature)
function GridEntityUpdateDetection.prototype.____constructor(self, postGridEntityInit, postGridEntityCustomInit, postGridEntityUpdate, postGridEntityCustomUpdate, postGridEntityRemove, postGridEntityCustomRemove, postGridEntityStateChanged, postGridEntityCustomStateChanged, postGridEntityBroken, postGridEntityCustomBroken, customGridEntities)
    Feature.prototype.____constructor(self)
    self.v = v
    self.postUpdate = function()
        local gridEntitiesMap = getGridEntitiesMap(nil)
        self:checkGridEntitiesRemoved(gridEntitiesMap)
        for ____, ____value in __TS__Iterator(gridEntitiesMap) do
            local gridIndex = ____value[1]
            local gridEntity = ____value[2]
            self:checkGridEntityStateChanged(gridIndex, gridEntity)
            self:checkNewGridEntity(gridIndex, gridEntity)
            local gridEntityTypeCustom = self.customGridEntities:getCustomGridEntityType(gridIndex)
            if gridEntityTypeCustom == nil then
                self.postGridEntityUpdate:fire(gridEntity)
            else
                self.postGridEntityCustomUpdate:fire(gridEntity, gridEntityTypeCustom)
            end
        end
    end
    self.postNewRoomReordered = function()
        local gridEntitiesMap = getGridEntitiesMap(nil)
        for ____, ____value in __TS__Iterator(gridEntitiesMap) do
            local gridIndex = ____value[1]
            local gridEntity = ____value[2]
            self:checkNewGridEntity(gridIndex, gridEntity)
        end
    end
    self.featuresUsed = {ISCFeature.RUN_IN_N_FRAMES}
    self.callbacksUsed = {{ModCallback.POST_UPDATE, self.postUpdate}}
    self.customCallbacksUsed = {{ModCallbackCustom.POST_NEW_ROOM_REORDERED, self.postNewRoomReordered}}
    self.postGridEntityInit = postGridEntityInit
    self.postGridEntityCustomInit = postGridEntityCustomInit
    self.postGridEntityUpdate = postGridEntityUpdate
    self.postGridEntityCustomUpdate = postGridEntityCustomUpdate
    self.postGridEntityRemove = postGridEntityRemove
    self.postGridEntityCustomRemove = postGridEntityCustomRemove
    self.postGridEntityStateChanged = postGridEntityStateChanged
    self.postGridEntityCustomStateChanged = postGridEntityCustomStateChanged
    self.postGridEntityBroken = postGridEntityBroken
    self.postGridEntityCustomBroken = postGridEntityCustomBroken
    self.customGridEntities = customGridEntities
end
function GridEntityUpdateDetection.prototype.checkGridEntitiesRemoved(self, gridEntitiesMap)
    for ____, ____value in __TS__Iterator(v.room.initializedGridEntities) do
        local gridIndex = ____value[1]
        local gridEntityTuple = ____value[2]
        local storedGridEntityType, storedGridEntityVariant = table.unpack(gridEntityTuple)
        local gridEntity = gridEntitiesMap:get(gridIndex)
        if gridEntity == nil or gridEntity:GetType() ~= storedGridEntityType then
            v.room.initializedGridEntities:delete(gridIndex)
            local gridEntityTypeCustom = self.customGridEntities:getCustomGridEntityType(gridIndex)
            if gridEntityTypeCustom == nil then
                self.postGridEntityRemove:fire(gridIndex, storedGridEntityType, storedGridEntityVariant)
            else
                self.postGridEntityCustomRemove:fire(gridIndex, gridEntityTypeCustom)
            end
        end
    end
end
function GridEntityUpdateDetection.prototype.checkGridEntityStateChanged(self, gridIndex, gridEntity)
    local gridEntityTuple = v.room.initializedGridEntities:get(gridIndex)
    if gridEntityTuple == nil then
        return
    end
    local _gridEntityType, _gridEntityVariant, oldState = table.unpack(gridEntityTuple)
    local newState = gridEntity.State
    if oldState ~= newState then
        self:updateTupleInMap(gridEntity)
        local gridEntityTypeCustom = self.customGridEntities:getCustomGridEntityType(gridEntity)
        if gridEntityTypeCustom == nil then
            self.postGridEntityStateChanged:fire(gridEntity, oldState, newState)
        else
            self.postGridEntityCustomStateChanged:fire(gridEntity, gridEntityTypeCustom, oldState, newState)
        end
        if isGridEntityBroken(nil, gridEntity) then
            if gridEntityTypeCustom == nil then
                self.postGridEntityBroken:fire(gridEntity)
            else
                self.postGridEntityCustomBroken:fire(gridEntity, gridEntityTypeCustom)
            end
        end
    end
end
function GridEntityUpdateDetection.prototype.checkNewGridEntity(self, gridIndex, gridEntity)
    local gridEntityType = gridEntity:GetType()
    local gridEntityTuple = v.room.initializedGridEntities:get(gridIndex)
    if gridEntityTuple == nil or gridEntityTuple[1] ~= gridEntityType then
        self:updateTupleInMap(gridEntity)
        local gridEntityTypeCustom = self.customGridEntities:getCustomGridEntityType(gridEntity)
        if gridEntityTypeCustom == nil then
            self.postGridEntityInit:fire(gridEntity)
        else
            self.postGridEntityCustomInit:fire(gridEntity, gridEntityTypeCustom)
        end
    end
end
function GridEntityUpdateDetection.prototype.updateTupleInMap(self, gridEntity)
    local gridEntityType = gridEntity:GetType()
    local variant = gridEntity:GetVariant()
    local gridIndex = gridEntity:GetGridIndex()
    local newTuple = {gridEntityType, variant, gridEntity.State}
    v.room.initializedGridEntities:set(gridIndex, newTuple)
end
return ____exports
