local LD = require("design.LevelDesignLibrary")
local timers = require("level.timer")
local uiCalls = require("ui.uicalls")
local CCOS = require("camera.camera_oneshot")
local thisLevel, player
local bBlockerBroken = false
local bQuestionAsked = false
local bAnswerFound = false
local cine_lights_440
local bAreaDiscovered = false
local atriumFrame = 1600
local bTriptychDiscovered = false
local bFirstTimeDrop = true
local bDemiGodToasting = false
local bComingUpFromBelow = false
local bSonWaitingAtTriptych = false
local normalSpeed = 1
local bCal200Hidden = false
local camOneShot_RunebowlPushIn, camOneShot_ElevatorRestricted
local elevatorState = "GoingDown"
function OnScriptLoaded(level)
  thisLevel = level
  player = game.Player.FindPlayer()
  cine_lights_440 = GameObjects.Cine_Start_440
end
function OnFirstStart(level)
  DisableSpline()
  GameObjects.NavGeo:Hide()
  GameObjects.dynamicNavGeo:Hide()
  GameObjects.guardRail:HideCollision()
  GameObjects.LoadCineUp:HideEntityVolume()
  GameObjects.SonLookAtInteract.LuaObjectScript.Disable()
  GameObjects.ElevatorRuneBowl_PostModi.LuaObjectScript.Disable()
  GameObjects.fx_elevator:Hide()
  GameObjects.SlowZone:HideEntityVolume()
  ShowCal200FromInside()
end
function OnStart(level)
  GameObjects.fx_elevator:Hide()
  SetBridgeAlignmentImmediate()
  if game.Level.GetVariable("CompletedCineNumber") == 365 then
    player:TriggerMoveEvent("kLE_CarrySonStand")
  end
  LD.RegisterForCineUpdate(level, {
    {
      at = 365,
      immediateFn = function()
        EnableSpline()
        GameObjects.Enter1.LuaObjectScript.Disable()
        GameObjects.Enter2.LuaObjectScript.Disable()
        GameObjects.ModiEnter1.LuaObjectScript.Disable()
        GameObjects.ModiEnter2.LuaObjectScript.Disable()
      end,
      fn = function()
        EnableSpline()
        GameObjects.Enter1.LuaObjectScript.Disable()
        GameObjects.Enter2.LuaObjectScript.Disable()
        GameObjects.ModiEnter1.LuaObjectScript.Disable()
        GameObjects.ModiEnter2.LuaObjectScript.Disable()
      end
    },
    {
      at = 366,
      immediateFn = function()
        DisableSpline()
        GameObjects.ElevatorRuneBowl_PostModi.LuaObjectScript.Enable()
        ShowCal200FromInside()
      end,
      fn = function()
        DisableSpline()
        GameObjects.ElevatorRuneBowl_PostModi.LuaObjectScript.Enable()
        ShowCal200FromInside()
      end
    },
    {
      at = 430,
      immediateFn = function()
        GameObjects.ElevatorRuneBowl_PostModi.LuaObjectScript.Disable()
        HideCal200FromInside()
      end,
      fn = function()
        GameObjects.ElevatorRuneBowl_PostModi.LuaObjectScript.Disable()
        HideCal200FromInside()
      end
    },
    {
      at = 431,
      immediateFn = function()
        EnableBowl()
      end,
      fn = function()
        EnableBowl()
      end
    },
    {
      at = 440,
      immediateFn = function()
        ShowCal200FromInside()
        EnableBowl()
      end,
      fn = function()
        ShowCal200FromInside()
        EnableBowl()
      end
    }
  })
  LD.RegisterForVariableUpdate(level, "BridgePosition", {
    immediateFn = SetBridgeAlignmentImmediate,
    fn = SetBridgeAlignment
  })
  if GameObjects.BasicElevatorManager.LuaObjectScript.GetState() == "Bottom" then
    GameObjects.lookAtDoor.LuaObjectScript.Disable()
  end
end
function OnSaveCheckpoint(level)
  return {
    bAnswerFound = bAnswerFound,
    bAreaDiscovered = bAreaDiscovered,
    bQuestionAsked = bQuestionAsked,
    bFirstTimeDrop = bFirstTimeDrop,
    bComingUpFromBelow = bComingUpFromBelow,
    bCal200Hidden = bCal200Hidden,
    bTriptychDiscovered = bTriptychDiscovered
  }
end
function OnRestoreCheckpoint(level, savedInfo)
  bAnswerFound = savedInfo.bAnswerFound
  bFirstTimeDrop = savedInfo.bFirstTimeDrop
  bAreaDiscovered = savedInfo.bAreaDiscovered
  bQuestionAsked = savedInfo.bQuestionAsked
  bComingUpFromBelow = savedInfo.bComingUpFromBelow
  bCal200Hidden = savedInfo.bCal200Hidden
  bTriptychDiscovered = savedInfo.bTriptychDiscovered
end
function OnWadLoaded(level, newLevel)
  if game.Level.GetVariable("CompletedCineNumber") ~= 365 and newLevel.Name == "WAD_Cal100_Hub" then
    newLevel:CallScript("HideQuads")
    newLevel:CallScript("HideOutside")
  end
end
function BookmarkStart()
  if game.Level.GetVariable("CompletedCineNumber") == 400 then
    GameObjects.BOOKMARK_23_RuneVault_010_Start:HideEntityVolume()
    local bookmarks = require("design.Bookmarks")
    local tableEntry = bookmarks["BOOKMARK_" .. "23_RuneVault_010_Start"]
    tableEntry.OverrideObject = GameObjects.RunevaultStart_CheckpointOverride
    game.World.StoreCheckpointAndBookmark(tableEntry)
  end
end
function SetupEnter1()
  ComeIn()
  GameObjects.SlowZone:HideEntityVolume()
  if game.Level.GetVariable("CompletedCineNumber") > 365 then
    GameObjects.Enter1.LuaObjectScript.Enable()
    GameObjects.Enter2.LuaObjectScript.Disable()
    GameObjects.LookAtTriptych.LuaObjectScript.Disable()
  elseif not bTriptychDiscovered then
    GameObjects.ModiEnter1.LuaObjectScript.Enable()
    GameObjects.ModiEnter2.LuaObjectScript.Disable()
  else
    GameObjects.ModiEnter1.LuaObjectScript.Disable()
    GameObjects.ModiEnter2.LuaObjectScript.Disable()
    GameObjects.LookAtTriptych.LuaObjectScript.Disable()
    GameObjects.ObserveTriptych.LuaObjectScript.Disable()
    GameObjects.PreModi_CA_BeckonToMe.LuaObjectScript.Enable()
  end
end
function SetupEnter2()
  ComeIn()
  GameObjects.SlowZone:HideEntityVolume()
  if game.Level.GetVariable("CompletedCineNumber") > 365 then
    GameObjects.Enter2.LuaObjectScript.Enable()
    GameObjects.Enter1.LuaObjectScript.Disable()
    GameObjects.LookAtTriptych.LuaObjectScript.Disable()
  elseif not bTriptychDiscovered then
    GameObjects.ModiEnter2.LuaObjectScript.Enable()
    GameObjects.ModiEnter1.LuaObjectScript.Disable()
  else
    GameObjects.ModiEnter1.LuaObjectScript.Disable()
    GameObjects.ModiEnter2.LuaObjectScript.Disable()
    GameObjects.LookAtTriptych.LuaObjectScript.Disable()
    GameObjects.ObserveTriptych.LuaObjectScript.Disable()
    GameObjects.PreModi_CA_BeckonToMe.LuaObjectScript.Enable()
  end
end
function ComeIn()
  LD.CompleteQuest("Quest_Caldera_Objective310")
  GameObjects.guardRail:HideCollision()
  HideCal200FromInside()
  local cal050 = game.FindLevel("Cal050_Sound")
  if cal050 ~= nil then
    cal050:CallScript("ShowRuneVaultZones")
  end
  if not bAreaDiscovered then
    bAreaDiscovered = true
    uiCalls.UI_Event_DiscoverLocation("Caldera Bridge Interior")
  end
end
function SeeTriptych()
  GameObjects.LookAtTriptych.LuaObjectScript.Enable()
  GameObjects.ModiEnter1.LuaObjectScript.Disable()
  GameObjects.ModiEnter2.LuaObjectScript.Disable()
end
function OnElevatorAbove()
  if game.Level.GetVariable("CompletedCineNumber") > 365 then
    bComingUpFromBelow = false
    EnableBowl()
    if not GameObjects.ElevatorRuneBowl_PostModi.LuaObjectScript.IsRuneDiscovered() and not bDemiGodToasting then
      GameObjects.SonLookAtInteract.LuaObjectScript.Enable()
    end
  end
end
function ExitElevatorRoom()
  ShowCal200FromInside()
  GameObjects.ModiEnter1.LuaObjectScript.Disable()
  GameObjects.ModiEnter2.LuaObjectScript.Disable()
  GameObjects.Enter1.LuaObjectScript.Disable()
  GameObjects.Enter2.LuaObjectScript.Disable()
  bSonWaitingAtTriptych = false
  GameObjects.LookAtTriptych.LuaObjectScript.Disable()
end
function OffElevator()
end
function SetBridgeAlignment()
  local selBridgePosition = LD.GetBridgePosition()
  local frame = LD.GetRealmFrame(selBridgePosition)
  local rate = LD.GetCorrectedBridgeAnimRate(GameObjects.RuneElevator, selBridgePosition)
  if rate == 0 then
    GameObjects.RuneElevator:JumpAnimToFrame(frame)
    GameObjects.RuneElevator:PauseAnim()
    ElevatorAtAlignment()
  else
    GameObjects.RuneElevator:PlayAnimToFrame(frame, rate)
    GameObjects.RuneElevator:OnAnimationDone(thisLevel, "ElevatorAtAlignment", {Force = true})
  end
end
function SetBridgeAlignmentImmediate()
  local selBridgePosition = LD.GetBridgePosition()
  local frame = LD.GetRealmFrame(selBridgePosition)
  GameObjects.RuneElevator:JumpAnimToFrame(frame)
  GameObjects.RuneElevator:PauseAnim()
  ElevatorAtAlignment()
end
function ElevatorAtAlignment()
  GameObjects.RuneElevator:ClearAllAnimCallbacks()
end
function ExitWithSon_CrossThreshhold()
end
function ExitWithSon_CloseDoor()
  if game.Level.GetVariable("CompletedCineNumber") == 365 then
    GameObjects.ExitWithSon:HideEntityVolume()
    local bookmarks = require("design.Bookmarks")
    local tableEntry = bookmarks["BOOKMARK_" .. "15_Caldera_020_ModiAmbush"]
    game.World.StoreCheckpointAndBookmark(tableEntry)
  end
end
function HideCal200FromInside()
  bCal200Hidden = true
  game.EvaluateLoadZones()
end
function OnEvaluateLoadGroup_LoadGroup_Cal500()
  return elevatorState
end
function ShowCal200FromInside()
  game.UI.LoadCheck("Cal200_Shore")
  bCal200Hidden = false
  game.EvaluateLoadZones()
end
function OnEvaluateLoadGroup_LoadGroup_Cal200()
  if bCal200Hidden then
    return "HideCal200"
  else
    return "ShowCal200"
  end
end
function LoadCheckFromBelow()
  bComingUpFromBelow = true
  game.UI.LoadCheck("Cal100_Hub")
end
function LoadCheckFromAbove()
  game.UI.LoadCheck("Cal500_RuneVault")
end
function ShowQuads()
  local cal200 = game.FindLevel("cal200_Shore")
  if cal200 ~= nil then
    cal200:CallScript("ShowQuads")
  end
  local cal100 = game.FindLevel("cal100_Hub")
  if cal100 ~= nil then
    cal100:CallScript("ShowLoadBridgeXpl")
  end
end
function HideQuads()
  local cal200 = game.FindLevel("cal200_Shore")
  if cal200 ~= nil then
    cal200:CallScript("HideQuads")
  end
  local cal100 = game.FindLevel("cal100_Hub")
  if cal100 ~= nil then
    cal100:CallScript("HideLoadBridgeXpl")
  end
end
function SolveStart()
  local cal500 = game.FindLevel("cal500_RuneVault")
  if cal500 ~= nil and GameObjects.BasicElevatorManager.LuaObjectScript.GetState() == "Bottom" then
    cal500:CallScript("LockFrontDoor")
  end
  GameObjects.guardRail:ShowCollision()
  GameObjects.fx_elevator:Show()
  PlayMagicCircleSound()
end
function SolveComplete()
  GameObjects.fx_elevator:Hide()
  GameObjects.RunToPOI_GOP.LuaObjectScript.Enable()
  game.SubmitActivityFeedStory("09_RuneVault")
  DropElevator()
  game.Compass.SetDesignerForcedHide(true)
  timers.StartLevelTimer(1, function()
    GameObjects.SlowZone:HideEntityVolume()
    GameObjects.POI_GodOfPeace.LuaObjectScript.ElevatorDescending()
    ForceDisableBowl()
    CameraRestricted_Elevator()
  end)
end
function Reuse()
  GameObjects.fx_elevator:Hide()
  LD.PlayMove(player, GameObjects.dummyObj, "MOV_CineDoNotMoveExit")
  timers.StartLevelTimer(8, function()
    DisableBowl()
    if player:InsideZone("EnteredElevatorAbove") then
      DropElevator()
      CameraRestricted_Elevator()
    else
      elevatorState = "GoingUp"
      game.EvaluateLoadZones()
      GameObjects.BasicElevatorManager.LuaObjectScript.MoveToFrame(atriumFrame)
      GameObjects.BasicElevatorManager.LuaObjectScript.StopLoopingSoundOnFrame(atriumFrame, "forward")
      CameraRestricted_Elevator()
    end
  end)
end
function AtBottom()
  LD.CompleteQuest("Quest_Caldera_Objective315")
  game.Compass.SetDesignerForcedHide(false)
  local cal500 = game.FindLevel("cal500_RuneVault")
  cal500:CallScript("UnlockFrontDoor")
  GameObjects.lookAtDoor.LuaObjectScript.Enable()
  DisableBowl()
  if bFirstTimeDrop then
    bFirstTimeDrop = false
  else
    EnableBowl()
    GameObjects.BasicElevatorManager.LuaObjectScript.UpdateMoveSpeed(normalSpeed, normalSpeed)
  end
end
function DropElevator()
  if bFirstTimeDrop then
    GameObjects.BasicElevatorManager.LuaObjectScript.UpdateMoveSpeed(0.4, 0.4)
  end
  local cal200 = game.FindLevel("cal200_Shore")
  if cal200 ~= nil then
    cal200:CallScript("HideQuads")
  end
  local cal100 = game.FindLevel("cal100_Hub")
  if cal100 ~= nil then
    cal100:CallScript("HideWater")
  end
  GameObjects.BasicElevatorManager.LuaObjectScript.MoveDown()
  elevatorMusic()
  elevatorState = "GoingDown"
  game.EvaluateLoadZones()
end
function CheckIfElevatorIsAtBottom(level, doorObj)
  if GameObjects.BasicElevatorManager.LuaObjectScript.GetState() == "Bottom" then
    doorObj:CallScript("Enable")
  end
end
function BuildDemigodToastSequence()
  bComingUpFromBelow = true
  bDemiGodToasting = true
  GameObjects.Cine_DemigodToast.LuaObjectScript.BuildDemigodToastSequence()
end
function DropElevatorToAtrium()
  GameObjects.BasicElevatorManager.LuaObjectScript.UpdateMoveSpeed(normalSpeed, normalSpeed)
  GameObjects.BasicElevatorManager.LuaObjectScript.MoveToFrame(atriumFrame)
  GameObjects.guardRail:HideCollision()
end
function SnapElevatorToAtrium()
  if game.Level.GetVariable("CompletedCineNumber") > 365 then
    GameObjects.BasicElevatorManager.LuaObjectScript.JumpToFrame(atriumFrame)
    GameObjects.BasicElevatorManager.LuaObjectScript.UpdateMoveSpeed(normalSpeed, normalSpeed)
    GameObjects.guardRail:HideCollision()
  end
end
function DisableBowl()
  GameObjects.ElevatorRuneBowl_PostModi.Child.LuaObjectScript.Disable()
end
function ForceDisableBowl()
  GameObjects.ElevatorRuneBowl_PostModi.Child.LuaObjectScript.ForcedDisable()
end
function EnableBowl()
  if not bDemiGodToasting then
    GameObjects.ElevatorRuneBowl_PostModi.Child.LuaObjectScript.Enable()
  end
end
function AtTop()
  bDemiGodToasting = false
end
function RuneDiscovered()
  CameraLookAt_RunebowlPushIn()
  GameObjects.SlowZone:ShowEntityVolume()
  GameObjects.guardRail:ShowCollision()
end
function EnableSpline()
  GameObjects.SonCarryController.LuaObjectScript.Enable()
end
function DisableSpline()
  GameObjects.SonCarryController.LuaObjectScript.Disable()
end
function PlayCineLights()
  cine_lights_440:Show()
  cine_lights_440:JumpAnimToFrame(0)
  cine_lights_440:PlayAnimToEnd()
end
function HideCineLights()
  cine_lights_440:Hide()
end
function SonArrivesAtTriptych()
  if player:IsInsideEntityZone("ApproachTriptych") then
    SonReadsTriptych()
  else
    bSonWaitingAtTriptych = true
  end
end
function SonLeavesTriptych()
  bSonWaitingAtTriptych = false
end
function ApproachTriptych()
  if bSonWaitingAtTriptych then
    SonReadsTriptych()
  end
end
function SonReadsTriptych()
  if not bTriptychDiscovered then
    GameObjects.LookAtTriptych.LuaObjectScript.Interrupt()
    GameObjects.LookAtTriptych.LuaObjectScript.Disable()
    GameObjects.ObserveTriptych.LuaObjectScript.Enable()
    game.Audio.PlayBanter("020_BrokenTriptych", TriptychBanterComplete)
    bTriptychDiscovered = true
  end
end
function TriptychBanterComplete()
  if game.Level.GetVariable("CompletedCineNumber") < 360 then
    game.Level.SetVariable("CompletedCineNumber", 360)
  end
  GameObjects.ObserveTriptych.LuaObjectScript.Interrupt()
  GameObjects.ObserveTriptych.LuaObjectScript.Disable()
  if game.Level.GetVariable("CompletedCineNumber") <= 360 then
    GameObjects.PreModi_CA_BeckonToMe.LuaObjectScript.Enable()
  else
    engine.Error("Attempting to turn on Modi2 Context Action at an incorrect cine number ", game.Level.GetVariable("CompletedCineNumber"))
  end
end
function PickUpSon()
  timers.StartLevelTimer(5, function()
    EnableSpline()
    local cineWad = game.FindLevel("Cal590_c365_ModiAmbush")
    if cineWad then
      cineWad:CallScript("SetupScene")
    end
    SonSickPathSetup()
  end)
end
function SonSickPathSetup()
  LD.SetEntityVariable("CAL_SonSick", true)
  local cal100 = game.FindLevel("Cal100_Hub")
  if cal100 ~= nil then
    cal100:CallScript("EnableSonSickBlockers")
    print("Cal590_ModiAmbush calling son sick blockers on bridge")
  end
  local cal200 = game.FindLevel("Cal200_Shore")
  if cal200 ~= nil then
    cal200:CallScript("EnableSonSickBlockers")
    print("Cal200 calling son sick blockers on lake")
  end
end
function CloseDoors()
  local door1 = GameObjects.ChiselDoor_Hero1:FindSingleGOByName("SpreadDoor")
  if door1.IsRefNode then
    door1 = door1.Child
  end
  door1.LuaObjectScript.ForceDoorClose()
  local door2 = GameObjects.ChiselDoor_Hero1:FindSingleGOByName("SpreadDoor")
  if door2.IsRefNode then
    door2 = door2.Child
  end
  door2.LuaObjectScript.ForceDoorClose()
end
function SonSickDisableDocks()
  local cal100 = game.FindLevel("Cal100_Hub")
  if cal100 ~= nil then
    cal100:CallScript("SonSickDisableDocks")
  end
end
function EnterBelow()
  if GameObjects.BasicElevatorManager.LuaObjectScript.GetState() == "Bottom" then
    if game.Level.GetVariable("CompletedCineNumber") == 430 then
      GameObjects.PostModi_CA_BeckonToMe.LuaObjectScript.Enable()
      GameObjects.DemiGodToast_Interact.LuaObjectScript.Enable()
      GameObjects.DemiGodToast_Interact.LuaObjectScript.GetInteractZone():SetInteractFrontAngle(0)
      GameObjects.DemiGodToast_Interact.LuaObjectScript.GetInteractZone():SetHintXZRange(20)
      DisableBowl()
    elseif game.Level.GetVariable("CompletedCineNumber") > 430 then
      GameObjects.Son_RunIntoElevator.LuaObjectScript.Enable()
      EnableBowl()
    else
      GameObjects.Son_RunIntoElevator.LuaObjectScript.Enable()
    end
  end
end
function TurnOnDemiGodInteract()
  GameObjects.DemiGodToast_Interact.LuaObjectScript.GetInteractZone():SetInteractFrontAngle(30)
end
function ExitBelow()
  GameObjects.lookAtDoor.LuaObjectScript.Disable()
end
function elevatorMusic()
  if game.Level.GetVariable("CompletedCineNumber") >= 400 and game.Level.GetVariable("CompletedCineNumber") < 425 then
    game.Audio.StartMusic("SND_MX_CAL_vault_elevator_descend_in")
  end
end
function PlayMagicCircleSound()
  local ElevatorObject = GameObjects.BasicElevator_root
  local ElevatorEmitter = ElevatorObject:FindSingleSoundEmitterByName("SNDBasicElevator")
  LD.PlaySound(ElevatorEmitter, "SND_MAG_RuneVault_Elevator_LP")
  LD.StopSoundAfterDelay(ElevatorEmitter, "SND_MAG_RuneVault_Elevator_LP", 7)
end
function OnUpdate(level)
  if camOneShot_RunebowlPushIn ~= nil then
    camOneShot_RunebowlPushIn:Update()
  end
  if camOneShot_ElevatorRestricted ~= nil then
    camOneShot_ElevatorRestricted:Update()
  end
end
function DestroyOneShot_RunebowlPushIn()
  camOneShot_RunebowlPushIn = nil
end
function CameraLookAt_RunebowlPushIn()
  camOneShot_RunebowlPushIn = CCOS.OneShotCamera.New("PLYR_NAR_Runebowl_Solved", 12)
  camOneShot_RunebowlPushIn:SetCallback(DestroyOneShot_RunebowlPushIn)
  camOneShot_RunebowlPushIn:Start()
end
function DestroyOneShot_ElevatorRestricted()
  camOneShot_ElevatorRestricted = nil
end
function CameraRestricted_Elevator()
  camOneShot_ElevatorRestricted = CCOS.OneShotCamera.New("PLYR_Elevator_LimitedUp_RuneVault", 40)
  camOneShot_ElevatorRestricted:SetCallback(DestroyOneShot_ElevatorRestricted)
  camOneShot_ElevatorRestricted:Start()
end
