local timers = require("level.timer")
local LD = require("design.LevelDesignLibrary")
local CSL = require("camera.shakelibrary")
local thisObj, ringInner, ringMiddle, ringOuter, light, lightRotate, lightIntensity, activeRing, shield
local bInitialized = false
local SNDSphereCenter
local bEmptyTrapPlayed = false
local innerRingSounds = {
  OnSpin = "SND_MAG_RuneVault_Rings_Sml_LP",
  OnIntro = ""
}
local middleRingSounds = {
  OnSpin = "SND_MAG_RuneVault_Rings_Med_LP",
  OnIntro = ""
}
local outerRingSounds = {
  OnSpin = "SND_MAG_RuneVault_Rings_Lrg_LP",
  OnIntro = ""
}
local banners = {}
function OnScriptLoaded(level, obj)
  thisObj = obj
  ringOuter = thisObj:FindSingleGOByName("Ring_Outer").Child
  ringMiddle = thisObj:FindSingleGOByName("Ring_Middle").Child
  ringInner = thisObj:FindSingleGOByName("Ring_Inner").Child
  shield = thisObj:FindSingleGOByName("Sphere_Shield"):FindSingleGOByName("Shield")
  light = thisObj:FindSingleGOByName("lightAnim")
  lightRotate = thisObj:FindSingleGOByName("lightRotate")
  lightIntensity = thisObj:FindSingleGOByName("lightIntensity")
  banners = level:FindGameObjects("runebanner*")
  game.SubObject.Sleep(obj)
end
function OnFirstStart(level, obj)
  thisObj:StartAnimation({Animation = "Intro"})
  thisObj:PlayAnimationToFrame(20)
  HideShield()
  GameObjects.Cal130_AfterGlow_Point:Hide()
  GameObjects.Cal130_AfterGlow_Spot:Hide()
  light:Show()
  light:PlayAnimationCycle()
  lightIntensity:JumpAnimationToFrame(1)
  lightIntensity:PauseAnimation()
end
function OnStart()
  if bInitialized then
    InitializeCallbacks()
  end
  SoundOnStart()
end
function StartFloorAnim()
  GameObjects.RSV_FloorReveal:Show()
  GameObjects.RSV_FloorReveal:PlayAnimationToFrame(200)
  GameObjects.RSV_FloorReveal:OnAnimationDone(thisObj, "TriggerIntro")
end
function TriggerIntro()
  GameObjects.RSV_FloorReveal:PlayAnimationToEnd()
  GameObjects.BOOKMARK_23_RuneVault_020_EnterVault:HideEntityVolume()
  GameObjects.calderaDiagonalChain00:StartAnimation({Animation = "Intro"})
  ringInner.LuaObjectScript.Intro()
  ringMiddle.LuaObjectScript.Intro()
  ringOuter.LuaObjectScript.Intro()
  PlaySoundSphereCenter()
  PlayerCameraShakeAndRumble()
  thisObj:StartAnimation({Animation = "Intro"})
  ringInner:StartAnimation({Animation = "Intro"})
  ringOuter:StartAnimation({Animation = "Intro"})
  ringMiddle:StartAnimation({Animation = "Intro"})
  thisObj:OnAnimationDone(thisObj, "TurnOnRings")
  ringOuter:HideCollision()
  lightRotate:PlayAnimationCycle()
  lightIntensity:PlayAnimationToFrame(240)
  GameObjects.Scraps_All:PlayAnimationToFrame(600)
  BeginScrapAnimation(GameObjects.Scraps_a)
  BeginScrapAnimation(GameObjects.Scraps_b)
  BeginScrapAnimation(GameObjects.Scraps_c)
  timers.StartLevelTimer(6, function()
    game.Audio.PlayBanter("050_RuneAhead_02")
  end)
end
function BeginScrapAnimation(newScrap)
  local scriptChildren = newScrap.Children
  for _, child in ipairs(scriptChildren) do
    child:PlayAnimationToFrame(700)
    game.Compass.SetDesignerForcedHide(true)
  end
end
function EndScrapAnimation(newScrap)
  local scriptChildren = newScrap.Children
  for _, child in ipairs(scriptChildren) do
    child:JumpAnimationToFrame(700)
    child:PlayAnimationToEnd()
  end
end
function TurnOnRings()
  RaiseBanners()
  PlayActivationSwayAndRumble()
  ringOuter:ShowCollision()
  thisObj:StartAnimation({Animation = "Idle"})
  thisObj:PlayAnimationCycle()
  ringInner.LuaObjectScript.StartSpin()
  ShowShield()
  shield:PlayAnimationToFrame(50, {Rate = 2})
  timers.StartLevelTimer(3, TurnOnMiddle)
  GameObjects.sonContext_control.LuaObjectScript.StartHint1Timer()
end
function TurnOnMiddle()
  ringMiddle.LuaObjectScript.StartSpin()
  PlayActivationSwayAndRumble()
  shield:PlayAnimationToFrame(100, {Rate = 2})
  timers.StartLevelTimer(3, TurnOnOuter)
  PlayToMid(0.5)
end
function TurnOnOuter()
  OuterDone()
  timers.StartLevelTimer(3, StartLevelObjective)
  shield:PlayAnimationToFrame(150, {Rate = 2})
  PlayToLarge(0.4)
  PlayActivationSwayAndRumble()
  game.Audio.PlayBanter("050_RuneAhead_03", EnableCrystalHint)
end
function EnableCrystalHint()
  timers.StartLevelTimer(5, function()
    if not GameObjects.sonContext_control.LuaObjectScript.FirstCrystalDrained() and not bEmptyTrapPlayed then
      GameObjects.Btr_EagleRinger:ShowEntityVolume()
    end
  end)
end
function OuterDone()
  ringOuter.LuaObjectScript.StartSpin()
  bInitialized = true
  InitializeDrain()
  InitializeCallbacks()
  RingLit(ringOuter)
  timers.StartLevelTimer(2, function()
    GameObjects.Door1.LuaObjectScript.ForceDoorOpen()
  end)
  timers.StartLevelTimer(4, function()
    GameObjects.EagleRinger_EmptyTrap:ShowEntityVolume()
  end)
end
function InitializeDrain()
  ringOuter.LuaObjectScript.InitializeDrain()
  ringMiddle.LuaObjectScript.InitializeDrain()
  ringInner.LuaObjectScript.InitializeDrain()
end
function InitializeCallbacks()
  ringOuter.LuaObjectScript.InitializeDrainCallbacks(function()
    RingLit(ringOuter)
  end, RingDrained_Outer)
  ringMiddle.LuaObjectScript.InitializeDrainCallbacks(function()
    RingLit(ringMiddle)
  end, RingDrained_Middle)
  ringInner.LuaObjectScript.InitializeDrainCallbacks(function()
    RingLit(ringInner)
  end, RingDrained_Inner)
end
function OnSaveCheckpoint(level, obj)
  return {bInitialized = bInitialized, bEmptyTrapPlayed = bEmptyTrapPlayed}
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  bInitialized = savedInfo.bInitialized
  bEmptyTrapPlayed = savedInfo.bEmptyTrapPlayed
end
function RingLit(ring)
  if ring == activeRing then
    return
  end
  if activeRing ~= nil then
    activeRing.LuaObjectScript.DeactivateShield()
  end
  activeRing = ring
  activeRing.LuaObjectScript.ActivateShield()
  activeRing.LuaObjectScript.StartSpin()
  if ring == ringInner then
    PlayToSmall()
  elseif ring == ringMiddle then
    PlayToMid()
  elseif ring == ringOuter then
    PlayToLarge()
  end
end
function RingDrained_Outer()
  ringOuter.LuaObjectScript.DeactivateShield()
  ringOuter.LuaObjectScript.StopSpin()
  if ringMiddle.LuaObjectScript.IsLit() then
    activeRing = ringMiddle
    PlayToMid()
  elseif ringInner.LuaObjectScript.IsLit() then
    activeRing = ringInner
    PlayToSmall()
  else
    activeRing = nil
    HideShield()
  end
  if activeRing then
    activeRing.LuaObjectScript.ActivateShield()
  end
  GameObjects.RuneVault_Btr_Group.LuaObjectScript.PlayMoveLikeHel()
end
function RingDrained_Middle()
  ringOuter.LuaObjectScript.SetPoweredOnAnim("PowerOnB")
  ringMiddle.LuaObjectScript.DeactivateShield()
  ringMiddle.LuaObjectScript.StopSpin()
  activeRing = ringInner
  activeRing.LuaObjectScript.ActivateShield()
  if ringInner.LuaObjectScript.IsLit() then
    PlayToSmall()
  else
    HideShield()
  end
  GameObjects.RuneVault_Btr_Group.LuaObjectScript.PlayerAcquiredMiddleRing()
end
function RingDrained_Inner()
  ringInner.LuaObjectScript.DeactivateShield()
  ringInner.LuaObjectScript.StopSpin()
  activeRing = nil
  HideShield()
  GameObjects.RuneVault_Btr_Group.LuaObjectScript.PlayerDrainedCenterRing()
end
function EmptyTrapPlayed()
  bEmptyTrapPlayed = true
end
function GetRingInnerLit()
  return ringInner.LuaObjectScript.IsLit()
end
function GetRingMiddleLit()
  return ringMiddle.LuaObjectScript.IsLit()
end
function GetRingOuterLit()
  return ringOuter.LuaObjectScript.IsLit()
end
function StartSlam()
  thisObj:StartAnimation({Animation = "Slam"})
  thisObj:PlayAnimationToFrame(70)
  GameObjects.Scraps_All:JumpAnimationToFrame(600)
  GameObjects.Scraps_All:PlayAnimationToEnd()
  EndScrapAnimation(GameObjects.Scraps_a)
  EndScrapAnimation(GameObjects.Scraps_b)
  EndScrapAnimation(GameObjects.Scraps_c)
end
function SlamDown()
  lightRotate:PauseAnimation()
  lightIntensity:JumpAnimationToFrame(240)
  lightIntensity:PlayAnimationToFrame(300)
  thisObj:PlayAnimationToEnd({Rate = 0.5})
  DropBanners()
end
function StartLevelObjective()
  LD.CompleteQuest("Quest_Caldera_Objective450")
  game.Compass.SetDesignerForcedHide(false)
end
function HideCore()
  thisObj:FindSingleGOByName("DispelCore"):Hide()
  thisObj:FindSingleGOByName("lightIntensity"):Hide()
end
function PlayToSmall(speed)
  local animSpeed = speed or 1
  ShowShield()
  shield:JumpAnimationToFrame(200, {Rate = animSpeed})
  shield:PlayAnimationToFrame(250, {Rate = animSpeed})
end
function PlayToMid(speed)
  local animSpeed = speed or 1
  ShowShield()
  if shield.AnimFrame == 50 or shield.AnimFrame == 250 then
    shield:JumpAnimationToFrame(50, {Rate = animSpeed})
    shield:PlayAnimationToFrame(100, {Rate = animSpeed})
  else
    shield:JumpAnimationToFrame(150, {Rate = animSpeed})
    shield:PlayAnimationToFrame(200, {Rate = animSpeed})
  end
end
function PlayToLarge(speed)
  local animSpeed = speed or 1
  ShowShield()
  if shield.AnimFrame == 50 or shield.AnimFrame == 250 then
    shield:JumpAnimationToFrame(250, {Rate = animSpeed})
    shield:PlayAnimationToFrame(300, {Rate = animSpeed})
  else
    shield:JumpAnimationToFrame(100, {Rate = animSpeed})
    shield:PlayAnimationToFrame(150, {Rate = animSpeed})
  end
  GameObjects.RuneVault_Btr_Group.LuaObjectScript.CleverHelPlayed()
end
function RaiseBanners()
  for _, banner in ipairs(banners) do
    banner.LuaObjectScript.StartRise()
  end
end
function DropBanners()
  for _, banner in ipairs(banners) do
    banner.LuaObjectScript.StartDrop()
  end
end
function PulseLight()
  lightIntensity:JumpAnimationToFrame(300)
  lightIntensity:PlayAnimationToEnd()
end
function HideShield()
  shield:Hide()
  GameObjects.Cal130_AfterGlow_Point:Show()
  GameObjects.Cal130_AfterGlow_Spot:Show()
end
function ShowShield()
  shield:Show()
  light:Show()
  GameObjects.Cal130_AfterGlow_Point:Hide()
  GameObjects.Cal130_AfterGlow_Spot:Hide()
end
function HideLights()
  light:Hide()
end
function SoundOnStart()
  SNDSphereCenter = thisObj.SoundEmitters[1]
  ringInner.LuaObjectScript.SoundSetup(innerRingSounds)
  ringMiddle.LuaObjectScript.SoundSetup(middleRingSounds)
  ringOuter.LuaObjectScript.SoundSetup(outerRingSounds)
  if not ringInner.LuaObjectScript.Disabled() then
    ringInner.LuaObjectScript.RingSpinSound()
  else
    ringInner.LuaObjectScript.RingSpinStopSound()
  end
  if not ringMiddle.LuaObjectScript.Disabled() then
    ringMiddle.LuaObjectScript.RingSpinSound()
  else
    ringMiddle.LuaObjectScript.RingSpinStopSound()
  end
  if not ringOuter.LuaObjectScript.Disabled() then
    ringOuter.LuaObjectScript.RingSpinSound()
  else
    ringOuter.LuaObjectScript.RingSpinStopSound()
  end
end
function PlaySoundSphereCenter()
  LD.PlaySound(SNDSphereCenter, "SND_MAG_RuneVault_Rings_Main_LP")
end
function StopSoundSphereCenter()
  LD.StopSound(SNDSphereCenter, "SND_MAG_RuneVault_Rings_Main_LP")
end
function PlayerCameraShakeAndRumble()
  CSL.PlayShake("FFB_GENERIC_RUMBLE_MEDIUM", 0.1, 0, 1)
  game.Blender.Trigger({
    Name = "FSE_SWAY_CATCH",
    Duration = 2,
    TweenIn = {Time = 0.2},
    TweenOut = {Time = 4},
    Weight = 0.1
  })
  timers.StartLevelTimer(3.4, function()
    CSL.PlayShake("FFB_GENERIC_HIT_SMALL", 0.1, 0, 2)
    game.Blender.Trigger({
      Name = "FSE_SWAY_CATCH",
      Duration = 2,
      TweenIn = {Time = 0.2},
      TweenOut = {Time = 1.2},
      Weight = 0.2
    })
  end)
  timers.StartLevelTimer(6.9, function()
    CSL.PlayShake("FFB_GENERIC_HIT_SMALL", 0.1, 0, 1)
    game.Blender.Trigger({
      Name = "FSE_SWAY_CATCH",
      Duration = 2,
      TweenIn = {Time = 0.1},
      TweenOut = {Time = 1.2},
      Weight = 0.3
    })
  end)
  timers.StartLevelTimer(10.4, function()
    CSL.PlayShake("FFB_GENERIC_RUMBLE_MEDIUM", 0.1, 0, 2)
    game.Blender.Trigger({
      Name = "FSE_SWAY_CATCH",
      Duration = 2,
      TweenIn = {Time = 0},
      TweenOut = {Time = 1},
      Weight = 0.6
    })
  end)
  timers.StartLevelTimer(11.9, function()
    CSL.PlayShake("FFB_GENERIC_RUMBLE_LOW", 0.1, 0, 3)
    game.Blender.Trigger({
      Name = "FSE_SWAY_CATCH",
      Duration = 2,
      TweenIn = {Time = 0},
      TweenOut = {Time = 1},
      Weight = 0.4
    })
  end)
  timers.StartLevelTimer(13, function()
    game.Blender.Trigger({
      Name = "FFB_GENERIC_RUMBLE_LOW",
      Duration = 6,
      TweenIn = {Time = 1},
      TweenOut = {Time = 5},
      Weight = 0.1
    })
    game.Blender.Trigger({
      Name = "FSE_SWAY_KEEPALIVE_WATERTRAP_MILD",
      Duration = 6,
      TweenIn = {Time = 1},
      TweenOut = {Time = 5},
      Weight = 1,
      Priority = 2000
    })
  end)
end
function PlayActivationSwayAndRumble()
  CSL.PlayShake("FFB_GENERIC_HIT_SMALL", 0.1, 0, 1)
  CSL.PlayShakeOG("FSE_SHAKE_GENERIC_LARGE", 1.2, 0, 0.2)
end
