local ____lualib = require("lualib_bundle")
local __TS__Class = ____lualib.__TS__Class
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
local __TS__DecorateLegacy = ____lualib.__TS__DecorateLegacy
local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
local ____exports = {}
local checkExecuteQueuedFunctions, checkExecuteIntervalFunctions
local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
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 ____array = require("functions.array")
local arrayRemoveInPlace = ____array.arrayRemoveInPlace
local ____run = require("functions.run")
local restart = ____run.restart
local ____Feature = require("classes.private.Feature")
local Feature = ____Feature.Feature
function checkExecuteQueuedFunctions(self, queuedFunctions, frameCount, newNumRoomsEntered)
    local firingFunctions = __TS__ArrayFilter(
        queuedFunctions,
        function(____, ____bindingPattern0)
            local frameCountToFire
            frameCountToFire = ____bindingPattern0.frameCountToFire
            return frameCount >= frameCountToFire
        end
    )
    for ____, firingFunction in ipairs(firingFunctions) do
        local func = firingFunction.func
        local cancelIfRoomChanges = firingFunction.cancelIfRoomChanges
        local numRoomsEntered = firingFunction.numRoomsEntered
        if not cancelIfRoomChanges or numRoomsEntered == newNumRoomsEntered then
            func(nil)
        end
        arrayRemoveInPlace(nil, queuedFunctions, firingFunction)
    end
end
function checkExecuteIntervalFunctions(self, intervalFunctions, frameCount, newNumRoomsEntered)
    local firingFunctions = __TS__ArrayFilter(
        intervalFunctions,
        function(____, ____bindingPattern0)
            local frameCountToFire
            frameCountToFire = ____bindingPattern0.frameCountToFire
            return frameCount >= frameCountToFire
        end
    )
    for ____, firingFunction in ipairs(firingFunctions) do
        local func = firingFunction.func
        local cancelIfRoomChanges = firingFunction.cancelIfRoomChanges
        local numRoomsEntered = firingFunction.numRoomsEntered
        local numIntervalFrames = firingFunction.numIntervalFrames
        local returnValue = false
        if not cancelIfRoomChanges or numRoomsEntered == newNumRoomsEntered then
            returnValue = func(nil)
        end
        arrayRemoveInPlace(nil, intervalFunctions, firingFunction)
        if returnValue then
            local newIntervalFunction = {
                func = func,
                frameCountToFire = frameCount + numIntervalFrames,
                numRoomsEntered = numRoomsEntered,
                cancelIfRoomChanges = cancelIfRoomChanges,
                numIntervalFrames = numIntervalFrames
            }
            intervalFunctions[#intervalFunctions + 1] = newIntervalFunction
        end
    end
end
local v = {run = {queuedGameFunctions = {}, queuedRenderFunctions = {}, intervalGameFunctions = {}, intervalRenderFunctions = {}}}
____exports.RunInNFrames = __TS__Class()
local RunInNFrames = ____exports.RunInNFrames
RunInNFrames.name = "RunInNFrames"
__TS__ClassExtends(RunInNFrames, Feature)
function RunInNFrames.prototype.____constructor(self, roomHistory)
    Feature.prototype.____constructor(self)
    self.v = v
    self.vConditionalFunc = function() return false end
    self.postUpdate = function()
        local gameFrameCount = game:GetFrameCount()
        local numRoomsEntered = self.roomHistory:getNumRoomsEntered()
        checkExecuteQueuedFunctions(nil, v.run.queuedGameFunctions, gameFrameCount, numRoomsEntered)
        checkExecuteIntervalFunctions(nil, v.run.intervalGameFunctions, gameFrameCount, numRoomsEntered)
    end
    self.postRender = function()
        local renderFrameCount = Isaac.GetFrameCount()
        local numRoomsEntered = self.roomHistory:getNumRoomsEntered()
        checkExecuteQueuedFunctions(nil, v.run.queuedRenderFunctions, renderFrameCount, numRoomsEntered)
        checkExecuteIntervalFunctions(nil, v.run.intervalRenderFunctions, renderFrameCount, numRoomsEntered)
    end
    self.featuresUsed = {ISCFeature.ROOM_HISTORY}
    self.callbacksUsed = {{ModCallback.POST_UPDATE, self.postUpdate}, {ModCallback.POST_RENDER, self.postRender}}
    self.roomHistory = roomHistory
end
function RunInNFrames.prototype.restartNextRenderFrame(self, character)
    self:runNextRenderFrame(function()
        restart(nil, character)
    end)
end
__TS__DecorateLegacy({Exported}, RunInNFrames.prototype, "restartNextRenderFrame", true)
function RunInNFrames.prototype.runInNGameFrames(self, func, numGameFrames, cancelIfRoomChanges)
    if cancelIfRoomChanges == nil then
        cancelIfRoomChanges = false
    end
    local gameFrameCount = game:GetFrameCount()
    local numRoomsEntered = self.roomHistory:getNumRoomsEntered()
    local frameCountToFire = gameFrameCount + numGameFrames
    local queuedFunction = {func = func, frameCountToFire = frameCountToFire, numRoomsEntered = numRoomsEntered, cancelIfRoomChanges = cancelIfRoomChanges}
    local ____v_run_queuedGameFunctions_0 = v.run.queuedGameFunctions
    ____v_run_queuedGameFunctions_0[#____v_run_queuedGameFunctions_0 + 1] = queuedFunction
end
__TS__DecorateLegacy({Exported}, RunInNFrames.prototype, "runInNGameFrames", true)
function RunInNFrames.prototype.runInNRenderFrames(self, func, numRenderFrames, cancelIfRoomChanges)
    if cancelIfRoomChanges == nil then
        cancelIfRoomChanges = false
    end
    local renderFrameCount = Isaac.GetFrameCount()
    local numRoomsEntered = self.roomHistory:getNumRoomsEntered()
    local frameCountToFire = renderFrameCount + numRenderFrames
    local queuedFunction = {func = func, frameCountToFire = frameCountToFire, numRoomsEntered = numRoomsEntered, cancelIfRoomChanges = cancelIfRoomChanges}
    local ____v_run_queuedRenderFunctions_1 = v.run.queuedRenderFunctions
    ____v_run_queuedRenderFunctions_1[#____v_run_queuedRenderFunctions_1 + 1] = queuedFunction
end
__TS__DecorateLegacy({Exported}, RunInNFrames.prototype, "runInNRenderFrames", true)
function RunInNFrames.prototype.runNextGameFrame(self, func, cancelIfRoomChanges)
    if cancelIfRoomChanges == nil then
        cancelIfRoomChanges = false
    end
    self:runInNGameFrames(func, 1, cancelIfRoomChanges)
end
__TS__DecorateLegacy({Exported}, RunInNFrames.prototype, "runNextGameFrame", true)
function RunInNFrames.prototype.runNextRenderFrame(self, func, cancelIfRoomChanges)
    if cancelIfRoomChanges == nil then
        cancelIfRoomChanges = false
    end
    self:runInNRenderFrames(func, 1, cancelIfRoomChanges)
end
__TS__DecorateLegacy({Exported}, RunInNFrames.prototype, "runNextRenderFrame", true)
function RunInNFrames.prototype.setIntervalGameFrames(self, func, numGameFrames, runImmediately, cancelIfRoomChanges)
    if cancelIfRoomChanges == nil then
        cancelIfRoomChanges = false
    end
    if runImmediately then
        local returnValue = func(nil)
        if not returnValue then
            return
        end
    end
    local gameFrameCount = game:GetFrameCount()
    local numRoomsEntered = self.roomHistory:getNumRoomsEntered()
    local intervalFunction = {
        func = func,
        frameCountToFire = gameFrameCount + numGameFrames,
        numRoomsEntered = numRoomsEntered,
        cancelIfRoomChanges = cancelIfRoomChanges,
        numIntervalFrames = numGameFrames
    }
    local ____v_run_intervalGameFunctions_2 = v.run.intervalGameFunctions
    ____v_run_intervalGameFunctions_2[#____v_run_intervalGameFunctions_2 + 1] = intervalFunction
end
__TS__DecorateLegacy({Exported}, RunInNFrames.prototype, "setIntervalGameFrames", true)
function RunInNFrames.prototype.setIntervalRenderFrames(self, func, numRenderFrames, runImmediately, cancelIfRoomChanges)
    if cancelIfRoomChanges == nil then
        cancelIfRoomChanges = false
    end
    if runImmediately then
        local returnValue = func(nil)
        if not returnValue then
            return
        end
    end
    local renderFrameCount = Isaac.GetFrameCount()
    local numRoomsEntered = self.roomHistory:getNumRoomsEntered()
    local intervalFunction = {
        func = func,
        frameCountToFire = renderFrameCount + numRenderFrames,
        numRoomsEntered = numRoomsEntered,
        cancelIfRoomChanges = cancelIfRoomChanges,
        numIntervalFrames = numRenderFrames
    }
    local ____v_run_intervalRenderFunctions_3 = v.run.intervalRenderFunctions
    ____v_run_intervalRenderFunctions_3[#____v_run_intervalRenderFunctions_3 + 1] = intervalFunction
end
__TS__DecorateLegacy({Exported}, RunInNFrames.prototype, "setIntervalRenderFrames", true)
return ____exports
