local LD = require("design.LevelDesignLibrary")
local ND = require("design.NarrativeDesignLibrary")
local timer = require("level.timer")
local collisionCheck = require("camera.collisioncheck")
local checkpoint = require("level.checkpoint")
local actor = require("narrative.actor")
local uiCalls = require("ui.uicalls")
local CCEC = require("camera.camera_cineentercamera")
local TUT = require("game.GlobalTutorials")
local thisObj, thisLevel, sonWarpMarker
local Player = game.Player.FindPlayer()
local kraActor, sonActor, son, pad, darkOne0, darkOne1, darkOne2, darkOne3, arrowProp
local bifrostTutorialPlayed = false
local cameraCineEnter, cameraCineEnter_BifrostArrowTutorial, cine_lights_242
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  son = game.AI.FindSon()
  sonWarpMarker = GameObjects.WarpPoint1
  pad = Player.Pad
  game.SubObject.Sleep(thisObj)
end
function OnStart(level, obj)
  HideProps()
  HideLights()
  if bifrostTutorialPlayed == false then
    local cineNum = game.Level.GetVariable("CompletedCineNumber")
    if 242 <= cineNum then
      SonBifrostTutorial()
    end
    GameObjects.POI_BifrostArrowTutorial.Child.Child.LuaObjectScript.GetInteractZone():SetRequiresCriticalBanterComplete(true)
  end
end
function OnUpdate(level, obj)
  if cameraCineEnter ~= nil then
    cameraCineEnter:Update()
  end
  if cameraCineEnter_BifrostArrowTutorial ~= nil then
    cameraCineEnter_BifrostArrowTutorial:Update()
  end
end
function OnSaveCheckpoint(level, obj)
  local savedInfo = {bifrostTutorialPlayed = bifrostTutorialPlayed}
  savedInfo.LevelState = checkpoint.Save()
  return savedInfo
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  checkpoint.Restore(savedInfo.LevelState)
  bifrostTutorialPlayed = savedInfo.bifrostTutorialPlayed
end
function SetupActors()
  kraActor = actor.Actor.New("OUT OF THE LIGHT: Kratos Actor", game.Player.FindPlayer)
  sonActor = actor.Actor.New("OUT OF THE LIGHT: Son Actor", game.AI.FindSon)
end
function HideProps()
  darkOne0 = GameObjects.DarkOneCine0.Child
  darkOne1 = GameObjects.DarkOneCine1.Child
  darkOne2 = GameObjects.DarkOneCine2.Child
  darkOne3 = GameObjects.DarkOneCine3.Child
  arrowProp = GameObjects.arrow00Prop.Child
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  if cineNum < 242 or 263 <= cineNum then
    darkOne0:Hide()
    darkOne1:Hide()
    darkOne2:Hide()
    darkOne3:Hide()
  else
    darkOne0:JumpAnimationToPercent(1, {
      Animation = "scnAlfheimLight110CineExit"
    })
    darkOne0:PauseAnimation()
    darkOne1:JumpAnimationToPercent(1, {
      Animation = "scnAlfheimLight110CineExit1"
    })
    darkOne1:PauseAnimation()
    darkOne2:JumpAnimationToPercent(1, {
      Animation = "scnAlfheimLight110CineExit2"
    })
    darkOne2:PauseAnimation()
    darkOne3:JumpAnimationToPercent(1, {
      Animation = "scnAlfheimLight110CineExit3"
    })
    darkOne3:PauseAnimation()
  end
  arrowProp:Hide()
end
function ShowDeadDarkOnes()
  darkOne0:Show()
  darkOne1:Show()
  darkOne2:Show()
  darkOne3:Show()
end
function SetupCineSequence()
  SetupActors()
  game.Level.SetVariable("LightCineDone", true)
  game.Audio.StartCheckpointedMusic("SND_MX_ALF_follow_light_3")
  game.Level.SetVariable("ALF_NAR_AlfLightExit", true)
  local cineSeq = LD.CreateCineSequence(thisLevel, thisObj, "Out of the Light Sequence")
  cineSeq:SetCompletedCineNumber(241)
  local slaveTable = {
    {
      Actor = sonActor,
      Branch = "BRA_scnAlfheimLight110CineExit"
    },
    {
      Obj = darkOne0,
      Anim = "scnAlfheimLight110CineExit"
    },
    {
      Obj = darkOne1,
      Anim = "scnAlfheimLight110CineExit1"
    },
    {
      Obj = darkOne2,
      Anim = "scnAlfheimLight110CineExit2"
    },
    {
      Obj = darkOne3,
      Anim = "scnAlfheimLight110CineExit3"
    },
    {
      Obj = arrowProp,
      Anim = "scnAlfheimLight110CineExit1"
    }
  }
  cineSeq:SetPostSkipMusic("SND_MX_ALF_start_master")
  cineSeq:MarkAbleToSkip()
  cineSeq:RequestCineModeAndWait(kraActor, thisObj)
  cineSeq:Do(IncreaseKratosDeceleration)
  cineSeq:Do(StartCineEnter_OutOfTheLight)
  cineSeq:ActorForceApproachAndWait(kraActor, {
    Branch = "BRA_scnAlfheimLight110CineExit",
    ReferenceJoint = "OutOfTheLight_SynchJoint",
    speed = ND.KraWalkSpeed,
    stop = false,
    foot = game.Creature.Foot.kLeft,
    radius = ND.ArrivalRadius,
    weapon_state = "bare"
  })
  cineSeq:Do(function()
    local availabilityState = {
      AvailableForSync = true,
      AvailableForBanter = false,
      AvailableInLevel = true,
      AvailableForCombat = false
    }
    game.AI.FindSon():SetNewAvailabilityRequest("LevelDesignScript", availabilityState)
    son:Warp(sonWarpMarker:GetWorldPosition(), sonWarpMarker:GetWorldForward())
    GameObjects.BridgeSlowDownZone:PlayAnimToEnd()
  end)
  cineSeq:Do(function()
    game.UI.LoadCheck("Alf600_TempleInt", "Alf690_LakeLightLH")
  end)
  cineSeq:Do(function()
    game.AI.FindSon():RemoveMarker("SonInDoor")
  end)
  cineSeq:ActorSync(kraActor, {
    Slaves = slaveTable,
    Branch = "BRA_scnAlfheimLight110CineExit",
    ReferenceJoint = "OutOfTheLight_SynchJoint"
  })
  cineSeq:Do(HideJimFX)
  cineSeq:Do(ResumeAlfAmbience)
  cineSeq:Do(ShowDeadDarkOnes)
  cineSeq:Do(function()
    arrowProp:Show()
  end)
  cineSeq:Do(PlayCineLights)
  cineSeq:WaitUntilActorAnimPastPercentage(kraActor, 0.98)
  cineSeq:Do(function()
    game.Audio.PlayBanter("BifrostArrowIntro")
  end)
  cineSeq:WaitForAndCompleteCineMode(kraActor, thisObj)
  cineSeq:StopPuppetingActor(kraActor)
  cineSeq:Do(function()
    arrowProp:Hide()
  end)
  cineSeq:Do(ClearKratosDeceleration)
  cineSeq:Do(HideLights)
  cineSeq:SetCompletedCineNumber(242)
  cineSeq:Do(UnlockRealmTravel)
  cineSeq:Do(function()
    game.AI.FindSon():RemoveAvailabilityRequest("LevelDesignScript")
  end)
  cineSeq:Do(function()
    local bookmarks = require("design.Bookmarks")
    local tableEntry = bookmarks["BOOKMARK_" .. "06_Alfheim_060_TempleInterior"]
    game.World.StoreCheckpointAndBookmark(tableEntry)
  end)
  cineSeq:StartSequence()
end
function HideJimFX()
  GameObjects.Alf550FX:Hide()
  GameObjects.Alf551FX:Hide()
  GameObjects.Alf552FX:Hide()
  GameObjects.Alf553FX:Hide()
  GameObjects.Alf554FX:Hide()
  GameObjects.Alf555FX:Hide()
  GameObjects.Phase1_Foreground_Crumble:Hide()
end
function UnlockRealmTravel()
  game.Level.SetVariable("CAL_RealmTravelAvailable", true)
end
function SonBifrostTutorial()
  SetupActors()
  local cineSeqIdle = LD.CreateCineSequence(thisLevel, thisObj, "BifrostTutorialIdle")
  cineSeqIdle:ActorSync(sonActor, {
    Branch = "BRA_AlfBifrostArrowTutorialEnter",
    ReferenceJoint = "BifrostTutorial_SynchJoint"
  })
  cineSeqIdle:StartSequence()
end
function BifrostTutorial()
  SetupActors()
  local cineSeq2 = LD.CreateCineSequence(thisLevel, thisObj, "Bifrost Arrow Sequence")
  local slaveTable2 = {
    {
      Actor = sonActor,
      Branch = "BRA_AlfBifrostArrowTutorial"
    }
  }
  cineSeq2:SetPostSkipMusic("SND_MX_ALF_start_master")
  cineSeq2:MarkAbleToSkip()
  cineSeq2:RequestCineModeAndWait(kraActor, thisObj)
  cineSeq2:Do(IncreaseKratosDeceleration)
  cineSeq2:Do(StartCineEnter_BifrostArrowTutorial)
  cineSeq2:ActorForceApproachAndWait(kraActor, {
    Branch = "BRA_AlfBifrostArrowTutorial",
    ReferenceJoint = "BifrostTutorial_SynchJoint",
    speed = ND.KraWalkSpeed,
    stop = false,
    radius = ND.InteractStopDistance,
    weapon_state = "bare",
    strafe_distance = 1
  })
  cineSeq2:Do(ClearKratosDeceleration)
  cineSeq2:ActorSync(kraActor, {
    Slaves = slaveTable2,
    Branch = "BRA_AlfBifrostArrowTutorial",
    ReferenceJoint = "BifrostTutorial_SynchJoint"
  })
  cineSeq2:WaitForFunctionTrue(function()
    return game.AI.FindSon().AnimPercent >= 0.68
  end)
  cineSeq2:Do(function()
    cineSeq2:EndSkipIfActive()
  end)
  cineSeq2:Do(function()
    TUT.Alf600_LightArrow_Tutorial()
  end)
  cineSeq2:WaitForAndCompleteCineMode(kraActor, thisObj)
  cineSeq2:StopPuppetingActor(kraActor)
  cineSeq2:Do(function()
    uiCalls.UI_Event_Force_Combat_HUD_Clear()
  end)
  cineSeq2:Do(function()
    GameObjects.CA_Post_Up_Arrow_Upgrade_Tutorial.LuaObjectScript.Enable()
    son:AddMarker("PostUpNoCollision")
  end)
  cineSeq2:Do(UnlockLightArrows)
  cineSeq2:Do(function()
    GameObjects.POI_BifrostArrowTutorial:HideEntityVolume()
  end)
  cineSeq2:Do(function()
    LD.CallFunctionAfterDelay(function()
      game.Audio.PlayBanter("BifrostArrowTutorial", _G.StartTutorial)
    end, 0.5)
  end)
  cineSeq2:Do(function()
    bifrostTutorialPlayed = true
  end)
  cineSeq2:WaitForFunctionTrue(function()
    return game.AI.FindSon().AnimPercent >= 0.99
  end)
  cineSeq2:StopPuppetingActor(sonActor)
  cineSeq2:StartSequence()
end
function UnlockLightArrows()
  LD.GiveLightArrow()
  IdleKratos()
  game.World.StoreCheckpoint()
end
function IdleKratos()
  LD.SetEntityVariable("ALF_InputMaskStage", 600)
  pad:EnableGameButton(tweaks.ePad.kPadSquare)
  pad:EnableGameButton(tweaks.ePad.kPadL2)
  pad:DisableGameButton(tweaks.ePad.kPadCircle)
  pad:DisableGameButton(tweaks.ePad.kPadTriangle)
  pad:DisableGameButton(tweaks.ePad.kPadDown)
  pad:DisableGameButton(tweaks.ePad.kPadRight)
  pad:DisableGameButton(tweaks.ePad.kPadL1)
  pad:DisableGameButton(tweaks.ePad.kPadL3)
  pad:DisableGameButton(tweaks.ePad.kPadR1)
  pad:DisableGameButton(tweaks.ePad.kPadR2)
  pad:DisableGameButton(tweaks.ePad.kPadR3)
  pad:DisableGameButton(tweaks.ePad.kPadLeftStickX)
  pad:DisableGameButton(tweaks.ePad.kPadLeftStickY)
end
function HideLights()
  cine_lights_242 = GameObjects.Cine_Start_242
  cine_lights_242:Hide()
  cine_lights_242:HideLights()
end
function ResumeAlfAmbience()
  local Alf050 = game.FindLevel("Alf050_Sound")
  if Alf050 ~= nil then
    Alf050:CallScript("AudioTime", thisLevel)
    Alf050:CallScript("PulseOffOn", thisLevel)
    Alf050:CallScript("HideLightZone")
    Alf050:CallScript("ShowTempleZones")
  end
end
function PlayCineLights()
  cine_lights_242:Show()
  cine_lights_242:JumpAnimToFrame(0)
  cine_lights_242:PlayAnimToEnd()
  local alf510 = game.FindLevel("Alf510_HiveIntCine")
  if alf510 ~= nil then
    alf510:CallScript("PlayExposure555")
  end
end
function IncreaseKratosDeceleration()
  game.Player.FindPlayer():SetDecelerationOverride(1.2)
  game.Player.FindPlayer():SetAccelerationOverride(1.2)
end
function ClearKratosDeceleration()
  game.Player.FindPlayer():ClearDecelerationOverride()
  game.Player.FindPlayer():ClearAccelerationOverride()
end
function StartCineEnter_OutOfTheLight()
  game.SubObject.Wake(thisObj)
  cameraCineEnter = CCEC.CineEnterCamera.New("ENV_CineEnter_OutOfTheLight", 12)
  cameraCineEnter:SetCallback(DestroyCineEnter_OutOfTheLight)
  cameraCineEnter:Start()
end
function DestroyCineEnter_OutOfTheLight()
  cameraCineEnter = nil
end
function EnableSplineCamera()
  local level_Alf600 = game.FindLevel("Alf600_TempleInt")
  assert(level_Alf600, "Can't find Alf600 to enable the spline tutorial camera")
  level_Alf600:CallScript("EnableSplineCamera")
end
function StartCineEnter_BifrostArrowTutorial()
  game.SubObject.Wake(thisObj)
  EnableSplineCamera()
  cameraCineEnter_BifrostArrowTutorial = CCEC.CineEnterCamera.New("ENV_CineEnter_BifrostArrowTutorial", 7)
  cameraCineEnter_BifrostArrowTutorial:SetCallback(DestroyCineEnter_BifrostArrowTutorial)
  cameraCineEnter_BifrostArrowTutorial:Start()
end
function DestroyCineEnter_BifrostArrowTutorial()
  cameraCineEnter_BifrostArrowTutorial = nil
end
