local LD = require("design.LevelDesignLibrary")
local ND = require("design.NarrativeDesignLibrary")
local checkpoint = require("level.checkpoint")
local actor = require("narrative.actor")
local timer = require("level.timer")
local uiCalls = require("ui.uicalls")
local mpicon = require("ui.mpicon")
local TUT = require("game.GlobalTutorials")
local thisObj, thisLevel, player
local startStates = {NewGameOnly = 1, NewGameOrContinue = 2}
local startState, restart, kraActor, sonActor, logActor
local boolBoatReminder = false
local btrBoatReminder = "010_BoatReminder"
local kratosLongBandage, mistleToeBranch, cine_lights, cine_lightsB
local enableCineMode = false
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  player = game.Player:FindPlayer()
  game.SubObject.Sleep(obj)
end
function OnStart(level, obj)
  CreateActors()
  SetSpawnFunctions()
  CreateProps()
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  if 0 <= cineNumber and cineNumber < 10 then
    SetupGameStartState()
  end
end
function SetupGameStartState()
  SetSonAvailability()
  if restart == true then
    game.Cinematics.EnableCinematicMode()
    OpeningSequence_NewGame()
  else
    local validSaveGames = game.UI.GetSaveGames(false)
    if 0 < #validSaveGames then
      startState = startStates.NewGameOrContinue
      OpeningSequence_ContinueAvailable()
    else
      startState = startStates.NewGameOnly
      OpeningSequence_ContinueNotAvailable()
    end
  end
end
function OpeningSequence_ContinueAvailable()
  local seq = LD.CreateCineSequence(thisLevel, thisObj, "Opening Sequence (Continue Available)")
  seq:WaitForLoadCheck("For100_River")
  seq:Do(PlayCineLights)
  seq:ActorSync(kraActor, {
    Slaves = {
      {Actor = sonActor}
    },
    Branch = "BRA_OpeningCine_ContinueIdle",
    ReferenceJoint = "Opening_SynchJoint"
  })
  seq:Do(DeactivateBracersNGPlus)
  seq:StopPuppetingActor(kraActor)
  seq:StartSequence()
end
function DeactivateBracersNGPlus()
  local player = game.Player.FindPlayer()
  if player:PickupIsAcquired("Blades") then
    local equippedWrist = player:PickupGetPickupNameInSlot("ArmorWrist")
    if equippedWrist ~= "" then
      player:PickupDeactivate(equippedWrist)
    end
  end
end
function OpeningSequence_ContinueNotAvailable()
  game.Cinematics.EnableCinematicMode()
  OpeningSequence_NewGame()
end
function OnUpdate(level, obj)
  if enableCineMode == true then
    enableCineMode = false
    game.Cinematics.EnableCinematicMode()
    game.SubObject.Sleep(obj)
  end
end
function OnSaveCheckpoint(level, obj)
  local savedInfo = {playedSceneBool = boolBoatReminder}
  savedInfo.LevelState = checkpoint.Save()
  return savedInfo
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  checkpoint.Restore(savedInfo.LevelState)
  boolBoatReminder = savedInfo.playedSceneBool
  restart = true
end
function CreateActors()
  kraActor = actor.Actor.New("OPENING: Kratos Actor", game.Player.FindPlayer)
  sonActor = actor.Actor.New("OPENING: Son Actor", game.AI.FindSon)
  logActor = actor.Actor.New("OPENING: Log Actor")
end
function SetSpawnFunctions()
  logActor:SetSpawnFunction(function()
    return game.AI.Spawn(thisLevel, engine.Vector.New(-392, 41, -800), engine.Vector.New(1, 0, 0), "CRT_Log00")
  end)
end
function CreateProps()
  kratosLongBandage = GameObjects.kratosLongBandage00A.Child
  mistleToeBranch = GameObjects.mistletoeBranch00A.Child
  mistleToeBranch:StartAnim("narForOpeningScene090CineScene")
  mistleToeBranch:JumpAnimToFrame(0)
  mistleToeBranch:PauseAnim()
  mistleToeBranch:Hide()
  cine_lights = GameObjects.Cine_Start_10
  cine_lightsB = GameObjects.Cine_Start_10B
  cine_lightsB:Hide()
end
function PlayCineLights()
  cine_lights:Show()
  cine_lights:JumpAnimToFrame(0)
  cine_lights:PauseAnimation()
end
function PlayCineLightsB()
  cine_lightsB:Show()
  cine_lightsB:JumpAnimToFrame(0)
  cine_lights:PlayAnimToEnd()
  cine_lightsB:PlayAnimToEnd()
end
function HideCineLights()
  cine_lights:Hide()
  cine_lightsB:Hide()
  mistleToeBranch:Hide()
end
function OpeningSequence_NewGame()
  local openingCineSeq = LD.CreateCineSequence(thisLevel, thisObj, "Opening Sequence")
  local opening_ActorTable = {
    {
      Actor = sonActor,
      Branch = "BRA_OpeningCine"
    },
    {
      Actor = logActor,
      Branch = "BRA_OpeningCine"
    },
    {
      Obj = kratosLongBandage,
      Anim = "narForOpeningScene090CineScene"
    },
    {
      Obj = mistleToeBranch,
      Anim = "narForOpeningScene090CineScene"
    },
    {
      Obj = kratosLongBandage,
      Anim = "narForOpeningScene090CineScene"
    }
  }
  openingCineSeq:SetPostSkipMusic("SND_MX_PRO_start_master")
  openingCineSeq:SetMusicClearingOnSkip(false)
  openingCineSeq:WaitForLoadCheck("For100_River")
  if restart == true then
    openingCineSeq:Do(ShowIntroPrompt)
    openingCineSeq:Do(DeactivateBracersNGPlus)
  else
    openingCineSeq:Do(function()
      openingCineSeq:MarkAbleToSkip()
    end)
  end
  openingCineSeq:SpawnActorAndWait(logActor)
  local treeInteract = thisLevel:FindGameObject("treeInteract").Child
  player:RequestInteract(treeInteract)
  openingCineSeq:Do(PlayCineLights)
  if startState ~= startStates.NewGameOrContinue then
    openingCineSeq:ActorSync(kraActor, {
      Slaves = opening_ActorTable,
      Branch = "BRA_OpeningCine",
      ReferenceJoint = "Opening_SynchJoint"
    })
    openingCineSeq:WaitForFunctionTrue(function()
      return player:IsPlayingMove("MOV_OpeningCineEnter")
    end)
  else
    openingCineSeq:ActorSync(kraActor, {
      Slaves = opening_ActorTable,
      Branch = "BRA_OpeningCineEnter",
      ReferenceJoint = "Opening_SynchJoint"
    })
  end
  if restart == true then
    openingCineSeq:Do(HideIntroPrompt)
    openingCineSeq:Do(function()
      openingCineSeq:MarkAbleToSkip()
    end)
  end
  openingCineSeq:WaitForFunctionTrue(function()
    return player:IsPlayingMove("MOV_OpeningIntAxeIdle01")
  end)
  openingCineSeq:Do(function()
    openingCineSeq:EndSkipIfActive()
  end)
  openingCineSeq:WaitForFunctionTrue(function()
    return player:IsPlayingMove("MOV_OpeningCineExit")
  end)
  openingCineSeq:SetMusicClearingOnSkip(true)
  openingCineSeq:Do(function()
    openingCineSeq:MarkAbleToSkip()
  end)
  openingCineSeq:Do(function()
    LD.CallFunctionAfterDelay(function()
      mistleToeBranch:Show()
    end, 30)
  end)
  openingCineSeq:Do(PlayCineLightsB)
  openingCineSeq:WaitForActorPuppeteerComplete(sonActor)
  openingCineSeq:StopPuppetingActor(sonActor)
  openingCineSeq:WaitUntilActorAnimPastFrame(kraActor, 2385)
  openingCineSeq:Do(function()
    GameObjects.CA_Idle_PostCine.LuaObjectScript.Enable()
    game.AI.FindSon():ClearMaxSpeedOverride()
  end)
  openingCineSeq:WaitUntilActorAnimPastPercentage(kraActor, 0.95)
  openingCineSeq:Do(function()
    openingCineSeq:SetMaxSkipSpeedup(2)
  end)
  openingCineSeq:WaitUntilActorAnimPastPercentage(kraActor, 0.99)
  openingCineSeq:Do(function()
    openingCineSeq:EndSkipIfActive()
  end)
  openingCineSeq:WaitForAndCompleteCineMode(kraActor, thisObj)
  openingCineSeq:WaitForActorMoveComplete(kraActor)
  openingCineSeq:StopPuppetingActor(kraActor)
  openingCineSeq:StopPuppetingActor(logActor)
  openingCineSeq:Do(HideCineLights)
  openingCineSeq:Do(TUT.BasicMove_Tutorial)
  openingCineSeq:Do(function()
    game.AI.FindSon():CallScript("LuaHook_DisableAutonomousSon")
  end)
  openingCineSeq:Do(function()
    GameObjects.LogCarry_PlayerNavCurve_010.LuaObjectScript.Enable()
  end)
  openingCineSeq:WaitForLoadCheck("For000_Sky")
  openingCineSeq:Do(function()
    game.FindLevel("For000_Sky"):GetGameObject("InputMask"):CallScript("AxtTut_Step_0")
  end)
  openingCineSeq:Do(function()
    game.AI.FindSon():CallScript("SetOneOffTimerActivation", false)
  end)
  openingCineSeq:Do(function()
    LD.DisableContextBehaviorBanter()
  end)
  openingCineSeq:SetCompletedCineNumber(10)
  openingCineSeq:StartSequence()
end
function ShowIntroPrompt()
  mpicon.level.Create(GameObjects.IntroPrompt, "WORLD_INTERACT", "promptJoint")
end
function HideIntroPrompt()
  mpicon.level.Off(GameObjects.IntroPrompt, "WORLD_INTERACT")
end
function SetSonAvailability()
  local son = game.AI.FindSon()
  local availabilityState = {
    AvailableForSync = true,
    AvailableForBanter = true,
    AvailableInLevel = true,
    AvailableForCombat = false
  }
  son:SetNewAvailabilityRequest("LevelDesignScript", availabilityState)
  son:CallScript("EnterBehaviorContext", "SAD_BEHAVIOR_CONTEXT_CONFIG")
  son:SetMaxSpeedOverride(0)
end
function NewGameSelected()
  print("GRATTAN - new game")
  if startState == startStates.NewGameOrContinue then
    enableCineMode = true
    game.SubObject.Wake(thisObj)
    local newGameSelSeq = LD.CreateCineSequence(thisLevel, thisObj, "Opening Sequence (New Game Selected)")
    newGameSelSeq:ActorSync(kraActor, {
      Slaves = {
        {Actor = sonActor}
      },
      Branch = "BRA_OpeningCineIdle_NewGameSelected",
      ReferenceJoint = "Opening_SynchJoint"
    })
    newGameSelSeq:WaitForFunctionTrue(function()
      return player:IsPlayingMove("MOV_OpeningIntIdle_Fake")
    end)
    newGameSelSeq:StopPuppetingActor(kraActor)
    newGameSelSeq:Do(OpeningSequence_NewGame)
    newGameSelSeq:StartSequence()
  end
end
function ContinueSelected()
  print("GRATTAN - continue")
  local continueSelSeq = LD.CreateCineSequence(thisLevel, thisObj, "Opening Sequence (Continue Selected)")
  continueSelSeq:ActorSync(kraActor, {
    Slaves = {},
    Branch = "BRA_OpeningCineIdle_ContinueSelected",
    ReferenceJoint = "Opening_SynchJoint"
  })
  continueSelSeq:StopPuppetingActor(kraActor)
  continueSelSeq:StartSequence()
end
