local LD = require("design.LevelDesignLibrary")
local actor = require("narrative.actor")
local checkpoint = require("level.checkpoint")
local ND = require("design.NarrativeDesignLibrary")
local thisObj, thisLevel, kratosActor, sonActor, sindriActor, dragonActor
local actorTable = {}
local arrowObj, sindriObj
local spawnZoneStr = "SpawnZone_DragonFight"
local dragonFightZoneStr = "CineZone_DragonFight"
local leapAcrossRocksBranchStr = "BRA_LeapAcrossRocks"
local leapAcrossRocksJointStr = "LeapAcrossRocks_SynchJoint"
local lightObj
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  game.SubObject.Sleep(obj)
end
function OnStart(level, obj)
  SetupPropsAndLights()
  HidePropsAndLights()
  if game.Level.GetVariable("CompletedCineNumber") < 280 then
    GameObjects.DragonFightInteract.Child.LuaObjectScript.DisablePrompt()
    HideTraverseLink()
  end
end
local AdvanceDragonBossFight = function()
  local peak550 = game.FindLevel("Peak550_DragonArena")
  peak550:CallScript("LuaHook_Peak550_BossForwardState")
end
function HideTraverseLink()
  local seq = ND.CreateCineSequence(thisLevel, thisObj, "Hide Traverse Link")
  seq:WaitForFunctionTrue(function()
    return game.FindLevel("Peak520_PostDragonTunnel") ~= nil
  end)
  seq:Do(function()
    game.FindLevel("Peak520_PostDragonTunnel"):CallScript("HideEndTraverseLink")
  end)
  seq:StartSequence()
end
function ShowTraverseLink()
  local seq = ND.CreateCineSequence(thisLevel, thisObj, "Show Traverse Link")
  seq:WaitForFunctionTrue(function()
    return game.FindLevel("Peak520_PostDragonTunnel") ~= nil
  end)
  seq:Do(function()
    game.FindLevel("Peak520_PostDragonTunnel"):CallScript("ShowEndTraverseLink")
  end)
  seq:StartSequence()
end
function OnSaveCheckpoint(level, obj)
  return {}
end
function OnRestoreCheckpoint(level, obj, savedInfo)
end
function SetupPropsAndLights()
  arrowObj = GameObjects.arrow00A.Child
  lightObj = GameObjects.Cine_Start_280
end
function HidePropsAndLights()
  arrowObj:Hide()
  lightObj:Hide()
end
function ShowLights()
  lightObj:Show()
end
function ShowArrow()
  arrowObj:Show()
end
function PlayLights()
  lightObj:JumpAnimToFrame(0)
  lightObj:PlayAnimToEnd()
end
function FindOrSpawnSindri()
  local peak550wad = game.FindLevel("Peak550_DragonArena")
  local sindri = ND.FindSindri()
  if sindri == nil then
    sindri = ND.SpawnAIAtJoint(peak550wad, "Cine_DragonFight", "Sind_StartJoint", "CRT_Sindri00", "BRA_CineSpawnIdle", "Sindri")
  end
  return sindri
end
function FindEarthDragon()
  local dragonCreature
  for creature in game.Creature.IterateAllCreatures() do
    if creature:GetName() == "earthdragon00" then
      dragonCreature = creature
      break
    end
  end
  return dragonCreature
end
function SetupActors()
  kratosActor = actor.Actor.New("DRAGON FIGHT: Kratos Actor", game.Player.FindPlayer)
  sonActor = actor.Actor.New("DRAGON FIGHT: Son Actor", game.AI.FindSon)
  sindriActor = actor.Actor.New("DRAGON FIGHT: Sindri Actor")
  dragonActor = actor.Actor.New("DRAGON FIGHT: Dragon Actor", FindEarthDragon)
  actorTable = {
    {Actor = sonActor},
    {Actor = sindriActor},
    {Actor = dragonActor}
  }
  sindriActor:SetSpawnFunction(FindOrSpawnSindri)
end
function SetupCineSequence()
  if game.Level.GetVariable("CompletedCineNumber") < 280 then
    local cineSeq = LD.CreateCineSequence(thisLevel, thisObj, "Dragon Fight Sequence")
    SetupActors()
    cineSeq:SetPostSkipMusic("SND_MX_PEAK_start_master")
    cineSeq:MarkAbleToSkip()
    cineSeq:WaitForLoadCheck("Peak550_DragonArena")
    cineSeq:SpawnActorAndWait(sindriActor)
    cineSeq:Do(AdvanceDragonBossFight)
    cineSeq:RequestCineModeAndWait(kratosActor, thisObj)
    cineSeq:Do(ShowLights)
    cineSeq:ActorForceApproachAndWait(kratosActor, {
      Branch = "BRA_DragonFightCine",
      ReferenceJoint = "DragonFight_SynchJoint",
      speed = ND.KraWalkSpeed,
      stop = false,
      radius = ND.StopTurnRadius,
      weapon_state = "bare"
    })
    cineSeq:ActorSync(kratosActor, {
      Slaves = actorTable,
      Branch = "BRA_DragonFightCine",
      ReferenceJoint = "DragonFight_SynchJoint"
    })
    cineSeq:Do(PlayLights)
    cineSeq:WaitUntilActorAnimPastPercentage(kratosActor, 0.95)
    cineSeq:Do(ManualCineModeDisable)
    cineSeq:Do(function()
      cineSeq:EndSkipIfActive()
    end)
    cineSeq:StopPuppetingActor(kratosActor)
    cineSeq:Do(HidePropsAndLights)
    cineSeq:Do(ShowTraverseLink)
    cineSeq:SetCompletedCineNumber(280)
    cineSeq:Do(function()
      local bookmarks = require("design.Bookmarks")
      local tableEntry = bookmarks["BOOKMARK_" .. "09_PeaksPass_040_DragonFight"]
      game.Audio.StartCheckpointedMusic("SND_MX_PEAK_dragon_boss_flank")
      game.World.StoreCheckpointAndBookmark(tableEntry)
    end)
    cineSeq:Do(SetupLeapAcrossRocksSequence)
    cineSeq:StartSequence()
  end
end
function ManualCineModeDisable()
  game.Cinematics.DisableCinematicMode()
  game.Player.FindPlayer().Pad:EnableGameButton(tweaks.ePad.kPadUp)
  if game.Compass.OnWarp then
    game.Compass.OnWarp()
  end
end
function IsKratosPlayingMantle()
  local kratos = game.Player.FindPlayer()
  return kratos:IsPlayingMove("MOV_Mantle_2m_Enter_Mirrored") or kratos:IsPlayingMove("MOV_Mantle_2m_Idle_Exit") or kratos:IsPlayingMove("MOV_Mantle_2m_Enter")
end
function HideSelfZone()
  thisObj:HideEntityVolume()
end
function SetupLeapAcrossRocksSequence()
  local leapSeq = LD.CreateCineSequence(thisLevel, thisObj, "Leap Across Rocks Sequence")
  if sindriActor == nil or dragonActor == nil then
    SetupActors()
    leapSeq:WaitForLoadCheck("Peak550_DragonArena")
    leapSeq:SpawnActorAndWait(sindriActor)
  end
  local slaveTable = {
    {Actor = sindriActor},
    {Actor = dragonActor}
  }
  leapSeq:Do(ShowArrow)
  leapSeq:Do(function()
    game.Audio.PlayBanter("393_HeyUgly")
  end)
  leapSeq:ActorSync(sonActor, {
    Slaves = slaveTable,
    Branch = leapAcrossRocksBranchStr,
    ReferenceJoint = leapAcrossRocksJointStr
  })
  leapSeq:WaitForSyncStart(sonActor:GetCreature())
  leapSeq:Do(function()
    GameObjects.SonLeapBreakObj.Child:PlayAnimToEnd()
  end)
  leapSeq:StopPuppetingActor(sonActor)
  leapSeq:StopPuppetingActor(sindriActor)
  leapSeq:StopPuppetingActor(dragonActor)
  leapSeq:StartSequence()
end
