local LD = require("design.LevelDesignLibrary")
local monitors = require("level.MonitorLibrary")
local thisLevel, player, spinnerSystem
local spinnerVelocitys = {min = -6, max = 6}
local spikeJumpSpeed = {min = -14, max = 14}
local spikeHall_CombatColl = {}
local spikeFront, spikeBack, backInstantKill, frontInstantKill, spikeFront_Monitor, spikeBack_Monitor
function OnScriptLoaded(level)
  player = game.Player.FindPlayer()
  spikeHall_CombatColl = {
    "Left_2B_Front",
    "Right_2B_Front",
    "Left_2B_Back",
    "Right_2B_Back"
  }
  for i = 1, #spikeHall_CombatColl do
    spikeHall_CombatColl[i] = GameObjects["CombatCollision_" .. spikeHall_CombatColl[i]]
  end
  spinnerSystem = GameObjects.SpinnableSystem2
  if spinnerSystem.IsRefNode then
    spinnerSystem = spinnerSystem.Child
  end
  spikeFront = GameObjects.SpikeHall2B_Front
  spikeBack = GameObjects.SpikeHall2B_Back
  SoundInit()
end
function OnStart(level)
  spinnerVelocitys.min = spinnerSystem.LuaObjectScript.minVelocity
  spinnerVelocitys.max = spinnerSystem.LuaObjectScript.maxVelocity
  spikeFront_Monitor = monitors.CreateAnimFrameMonitor(spikeFront)
  spikeBack_Monitor = monitors.CreateAnimFrameMonitor(spikeBack)
  spikeFront_Monitor:OnFrameBackward(120, OnRewind)
  spikeFront_Monitor:OnFrameForward(10, EnableFrontSpikes)
  spikeBack_Monitor:OnFrameBackward(spikeBack.AnimLengthFrames - 10, EnableBackSpikes)
  spikeFront_Monitor:OnFrameBackward(0, DisableFrontSpikes)
  spikeBack_Monitor:OnFrameForward(spikeBack.AnimLengthFrames, DisableBackSpikes)
  DisableFrontSpikes()
  LD.GiveLightArrow()
  if ValidateBreakable(GameObjects.breakable_wood_crate_ref, "Breakable_Wood_Crate") then
    GameObjects.TraversePath_CrawlSecretEnter:HideTraversePath()
  else
    GameObjects.TraversePath_CrawlSecretEnter:ShowTraversePath()
  end
end
function OnUpdate(level)
end
function OnForward()
  local frame = spikeBack.AnimFrame
  spikeHall_CombatColl[1].LuaObjectScript.SetToInstantKill(false)
  spikeHall_CombatColl[2].LuaObjectScript.SetToInstantKill(false)
  backInstantKill = 255 <= frame
  spikeHall_CombatColl[3].LuaObjectScript.SetToInstantKill(backInstantKill)
  spikeHall_CombatColl[4].LuaObjectScript.SetToInstantKill(backInstantKill)
  if backInstantKill then
    spinnerSystem.LuaObjectScript.maxVelocity = spikeJumpSpeed.max
    spinnerSystem.LuaObjectScript.currentVelocity = spikeJumpSpeed.max
  end
end
function OnRewind()
  local frame = spikeFront.AnimFrame
  frontInstantKill = 70 <= frame and frame <= 120
  spikeHall_CombatColl[1].LuaObjectScript.SetToInstantKill(frontInstantKill)
  spikeHall_CombatColl[2].LuaObjectScript.SetToInstantKill(frontInstantKill)
  if frontInstantKill then
    spinnerSystem.LuaObjectScript.minVelocity = spikeJumpSpeed.min
    spinnerSystem.LuaObjectScript.currentVelocity = spikeJumpSpeed.min
  end
  spikeHall_CombatColl[3].LuaObjectScript.SetToInstantKill(false)
  spikeHall_CombatColl[4].LuaObjectScript.SetToInstantKill(false)
  PlaySoundSpikeQuickRewind()
end
function ResetSpinner()
  for i = 1, #spikeHall_CombatColl do
    spikeHall_CombatColl[i].LuaObjectScript.SetToInstantKill(false)
  end
  frontInstantKill = false
  backInstantKill = false
  spinnerSystem.LuaObjectScript.currentVelocity = 0
  spinnerSystem.LuaObjectScript.maxVelocity = spinnerVelocitys.max
  spinnerSystem.LuaObjectScript.minVelocity = spinnerVelocitys.min
end
function EnableFrontSpikes()
  for i = 1, 2 do
    spikeHall_CombatColl[i].LuaObjectScript.Enable()
    spikeHall_CombatColl[i].LuaObjectScript.SetToInstantKill(false)
  end
end
function EnableBackSpikes()
  for i = 3, 4 do
    spikeHall_CombatColl[i].LuaObjectScript.Enable()
    spikeHall_CombatColl[i].LuaObjectScript.SetToInstantKill(false)
  end
end
function DisableFrontSpikes()
  spikeHall_CombatColl[1].LuaObjectScript.Disable()
  spikeHall_CombatColl[2].LuaObjectScript.Disable()
end
function DisableBackSpikes()
  spikeHall_CombatColl[3].LuaObjectScript.Disable()
  spikeHall_CombatColl[4].LuaObjectScript.Disable()
end
function SpikeSet1_Fwd()
  GameObjects.SpikeSet1A_Room:PlayAnimToEnd()
  GameObjects.SpikeSet1C_UnderSecret:PlayAnimToEnd()
end
function SpikeSet1_Rwd()
  GameObjects.SpikeSet1A_Room:PlayAnimToEnd(-1)
  GameObjects.SpikeSet1C_UnderSecret:PlayAnimToEnd(-1)
end
function ValidateBreakable(breakableRefnode, childBreakableName)
  local breakableRef = breakableRefnode:FindSingleGOByName(childBreakableName)
  if breakableRef ~= nil and breakableRef.LuaObjectScript ~= nil then
    local breakableComponent = breakableRef:GetBreakable()
    if breakableComponent ~= nil and breakableComponent.Broken == false then
      return true
    end
  end
  return false
end
function EnableCrawlSecret()
  GameObjects.TraversePath_CrawlSecretEnter:ShowTraversePath()
end
function EnableCubbyHole()
  GameObjects.CubbyHoleManager.LuaObjectScript.Enable()
end
function SCA_RopeDown_Down_Enable()
  GameObjects.SCA_RopeDown_Down.LuaObjectScript.Enable()
end
function SCA_CrawlReturnHelper_Enable()
  GameObjects.SCA_CrawlReturnHelper.LuaObjectScript.Enable()
  RopeDropClearSCAs()
end
function SCA_CrawlExit_Enable()
  GameObjects.SCA_CrawlExit.LuaObjectScript.Enable()
end
function RopeDropClearSCAs()
  GameObjects.SCA_CrawlExit.LuaObjectScript.Interrupt()
  GameObjects.SCA_CrawlExit.LuaObjectScript.Disable()
end
function DisableResurrection()
  player:CallScript("LuaHook_DisableRevive", true)
end
function EnableResurrection()
  player:CallScript("LuaHook_DisableRevive", false)
end
function OnEvaluateLoadGroup_AIWads()
  if game.Level.GetVariable("PEAK_ChimneyPhase") == 1 and game.Level.GetVariable("CompletedCineNumber") < 450 then
    return "AIWadsFirstEntry"
  elseif game.Level.GetVariable("PEAK_ChimneyPhase") == 2 and game.Level.GetVariable("CompletedCineNumber") < 450 then
    return "AIWadsRoller"
  elseif game.Level.GetVariable("CompletedCineNumber") >= 450 then
    return "AIWadsReturn"
  end
end
function DebugSpeedUp_Spinner()
  if spinnerSystem.LuaObjectScript.currentVelocity == 0 then
    spinnerSystem.LuaObjectScript.currentVelocity = 1
  end
  spinnerSystem.LuaObjectScript.currentVelocity = spikeJumpSpeed.max
end
local soundEmitterSpinDriver, soundEmitterSpikeBR, soundEmitterSpikeBL, soundEmitterSpikeFR, soundEmitterSpikeFL, soundEmitterSpikeFC
local spikesoundEvents = {
  OnMovement = "SND_TRAP_Metal_Spikes_Movement_LP",
  OnSwitchDirection = "SND_TRAP_Metal_Spikes_Change_Direction",
  OnClose = "SND_TRAP_Metal_Spikes_Close",
  OnRetract = "SND_TRAP_Metal_Spikes_Retract"
}
function SoundInit()
  soundEmitterSpinDriver = GameObjects.SpinnableDriver2.Child.SoundEmitters[1]
  soundEmitterSpikeFR = GameObjects.SpikeHall2B_Front:FindSingleSoundEmitterByName("SNDSpikeHall2B_FrontRight")
  soundEmitterSpikeFL = GameObjects.SpikeHall2B_Front:FindSingleSoundEmitterByName("SNDSpikeHall2B_FrontLeft")
  soundEmitterSpikeFC = GameObjects.SpikeHall2B_Front:FindSingleSoundEmitterByName("SNDSpikeHall2B_FrontCenter")
  soundEmitterSpikeBR = GameObjects.SpikeHall2B_Back:FindSingleSoundEmitterByName("SNDSpikeHall2B_BackRight")
  soundEmitterSpikeBL = GameObjects.SpikeHall2B_Back:FindSingleSoundEmitterByName("SNDSpikeHall2B_BackLeft")
end
function OnSpikeReachStart()
  StopSoundSpikeMovementLoops()
end
function OnSpikeReachEnd()
  StopSoundSpikeMovementLoops()
end
function OnSpikeAddImpulse()
  PlaySoundSpikeMovementLoops()
end
function OnSpikeRewindStart()
  LD.PlaySound(soundEmitterSpikeFR, spikesoundEvents.OnSwitchDirection)
  LD.PlaySound(soundEmitterSpikeFL, spikesoundEvents.OnSwitchDirection)
  LD.PlaySound(soundEmitterSpikeBR, spikesoundEvents.OnSwitchDirection)
  LD.PlaySound(soundEmitterSpikeBL, spikesoundEvents.OnSwitchDirection)
  LD.CallFunctionAfterDelay(PlaySoundSpikeMovementLoops, 0.35)
end
function PlaySoundSpikeQuickRewind()
  LD.PlaySound(soundEmitterSpinDriver, "SND_MECH_Spike_Ceiling_Spindle_Hit_Success")
  LD.PlaySound(soundEmitterSpikeFC, spikesoundEvents.OnClose)
  LD.PlaySound(soundEmitterSpikeBR, spikesoundEvents.OnRetract)
  LD.PlaySound(soundEmitterSpikeBL, spikesoundEvents.OnRetract)
end
function PlaySoundSpikeMovementLoops()
  LD.PlaySound(soundEmitterSpikeFR, spikesoundEvents.OnMovement)
  LD.PlaySound(soundEmitterSpikeFL, spikesoundEvents.OnMovement)
  LD.PlaySound(soundEmitterSpikeBR, spikesoundEvents.OnMovement)
  LD.PlaySound(soundEmitterSpikeBL, spikesoundEvents.OnMovement)
end
function StopSoundSpikeMovementLoops()
  LD.StopSound(soundEmitterSpikeFR, spikesoundEvents.OnMovement)
  LD.StopSound(soundEmitterSpikeFL, spikesoundEvents.OnMovement)
  LD.StopSound(soundEmitterSpikeBR, spikesoundEvents.OnMovement)
  LD.StopSound(soundEmitterSpikeBL, spikesoundEvents.OnMovement)
end
