local LD = require("design.LevelDesignLibrary")
local ND = require("design.NarrativeDesignLibrary")
local actor = require("narrative.actor")
local CCEC = require("camera.camera_cineentercamera")
local thisObj, thisLevel, kraActor, sonActor, sindriActor, hammerProp, gearProp, flintProp, wrenchProp, extraKnife
local cineProps = {}
local lightObj, cameraCineEnter_SindriGetsServed
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  game.SubObject.Sleep(obj)
  game.SubObject.SetForgetOnCheckpoint(obj)
end
function OnStart(level, obj)
  SetupActors()
  SetupProps()
  SetupLights()
end
function OnUpdate()
  if cameraCineEnter_SindriGetsServed ~= nil then
    cameraCineEnter_SindriGetsServed:Update()
  end
end
function SpawnOrFindSindri()
  local sindri = ND.FindSindri()
  if sindri == nil then
    local jointFace = thisObj:GetWorldJointForward(thisObj:GetJointIndex("Sind_StartJoint"))
    local jointPos = thisObj:GetWorldJointPosition(thisObj:GetJointIndex("Sind_StartJoint"))
    return game.AI.Spawn(game.FindLevel("Foot120_CS450"), jointPos, jointFace, "CRT_Sindri00")
  end
  return sindri
end
function RunFunctionOnObjectsInTable(obj_table, func_name, ...)
  for _, this_obj in ipairs(obj_table) do
    this_obj[func_name](this_obj, ...)
  end
end
function SetupProps()
  gearProp = GameObjects.gearProp.Child
  hammerProp = GameObjects.sindriHammerProp.Child
  flintProp = GameObjects.flintProp.Child
  wrenchProp = GameObjects.wrenchProp.Child
  extraKnife = GameObjects.extraKnifeProp.Child
  cineProps = {
    gearProp,
    hammerProp,
    flintProp,
    wrenchProp,
    extraKnife
  }
  HideAllProps()
end
function SetupActors()
  kraActor = actor.Actor.New("SINDRI GETS SERVED: Kratos Actor", game.Player.FindPlayer)
  sonActor = actor.Actor.New("SINDRI GETS SERVED: Son Actor", game.AI.FindSon)
  sindriActor = actor.Actor.New("SINDRI GETS SERVED: Sindri Actor")
  sindriActor:SetSpawnFunction(SpawnOrFindSindri)
end
function SetupLights()
  lightObj = GameObjects.Cine_Start_450
  lightObj:Hide()
end
function ShowLights()
  lightObj:Show()
  lightObj:JumpAnimToFrame(0)
end
function SetupCineSequence()
  local doorObj = GameObjects.Door_FromCal.Child
  local cineSeq = LD.CreateCineSequence(thisLevel, thisObj, "Sindri Gets Served Sequence")
  local actorTable = {
    {Actor = sonActor},
    {Actor = sindriActor},
    {
      Obj = gearProp,
      Anim = "narFootSindriGetsServed000CineScene"
    },
    {
      Obj = hammerProp,
      Anim = "narFootSindriGetsServed000CineScene"
    },
    {
      Obj = flintProp,
      Anim = "narFootSindriGetsServed000CineScene"
    },
    {
      Obj = wrenchProp,
      Anim = "narFootSindriGetsServed000CineScene"
    },
    {
      Obj = extraKnife,
      Anim = "narFootSindriGetsServed000CineScene1"
    },
    {
      Obj = doorObj,
      Anim = "narFootSindriGetsServed000CineScene"
    },
    {Obj = lightObj, Anim = "default"}
  }
  doorObj.LuaObjectScript.EnableCinematicTrigger()
  game.FindLevel("Foot100_Base"):CallScript("Hide_DoorCheckpoint")
  cineSeq:SetPostSkipMusic("SND_MX_FOOT_start_master")
  cineSeq:MarkAbleToSkip()
  cineSeq:WaitForLoadCheck("Foot120_CS450")
  cineSeq:SpawnActorAndWait(sindriActor)
  cineSeq:Do(ShowAllProps)
  cineSeq:RequestCineModeAndWait(kraActor, thisObj)
  cineSeq:Do(StartCineEnter_SindriGetsServed)
  cineSeq:ActorForceApproachAndWait(kraActor, {
    Branch = "BRA_SindriGetsServed",
    ReferenceJoint = "SindriGetsServed_SynchJoint",
    speed = ND.KraWalkSpeed,
    stop = false,
    radius = ND.StopTurnRadius,
    weapon_state = "bare"
  })
  cineSeq:ActorSync(kraActor, {
    Slaves = actorTable,
    Branch = "BRA_SindriGetsServed",
    ReferenceJoint = "SindriGetsServed_SynchJoint"
  })
  cineSeq:Do(ShowLights)
  cineSeq:WaitUntilActorAnimPastFrame(kraActor, 1750)
  cineSeq:Do(SetSoundStateFoothillsStorm)
  cineSeq:WaitUntilActorAnimPastFrame(kraActor, 2084)
  cineSeq:Do(PlaySoundLightningStrike)
  cineSeq:WaitUntilActorAnimPastFrame(kraActor, 2100)
  cineSeq:Do(PlaySoundLightningStrike)
  cineSeq:WaitUntilActorAnimPastFrame(kraActor, 2109)
  cineSeq:Do(StartRedStorm)
  cineSeq:WaitUntilActorAnimPastFrame(kraActor, 2340)
  cineSeq:Do(PlaySoundLightningStrike)
  cineSeq:Do(function()
    GameObjects.Door_FromCal.LuaObjectScript.Lock()
  end)
  cineSeq:WaitForAndCompleteCineMode(kraActor, thisObj)
  cineSeq:Do(function()
    lightObj:Hide()
  end)
  cineSeq:Do(HideAllProps)
  cineSeq:StopPuppetingActor(kraActor)
  cineSeq:StopPuppetingActor(sonActor)
  cineSeq:SetCompletedCineNumber(450)
  cineSeq:Do(function()
    if not cineSeq.skipping then
      cineSeq:EndSkipIfActive()
    end
  end)
  cineSeq:WaitUntilActorAnimPastPercentage(sindriActor, 0.999)
  cineSeq:StopPuppetingActor(sindriActor)
  cineSeq:Do(BranchSindriToTableIdle)
  cineSeq:WaitSeconds(1)
  cineSeq:Do(function()
    cineSeq:EndSkipIfActive()
  end)
  cineSeq:Do(function()
    game.Audio.StartCheckpointedMusic("SND_MX_FOOT4_explore1_in")
  end)
  cineSeq:Do(function()
    game.FindLevel("Foot100_Base"):CallScript("Show_DoorCheckpoint")
  end)
  cineSeq:Do(function()
    local bookmarks = require("design.Bookmarks")
    local tableEntry = bookmarks["BOOKMARK_" .. "25_Foothills_010_ReturnWithStone"]
    game.World.StoreCheckpointAndBookmark(tableEntry)
  end)
  cineSeq:StartSequence()
end
function BranchSindriToTableIdle()
  game.FindLevel("Foot100_Base"):CallScript("LuaFunctionForwarding_StartCounterRequest", sindriActor:GetCreature())
end
function StartRedStorm()
  local foot075 = game.FindLevel("Foot075_Lighting")
  if foot075 == nil then
    error("foot075_Lighting is not loaded so red storm cannot be triggered")
  else
    local SkyManager = foot075:GetGameObject("SkyFxManager")
    SkyManager:CallScript("StormySky")
  end
  local foot100 = game.FindLevel("Foot100_Base")
  if foot100 == nil then
    error("foot100_Lighting is not loaded so red storm cannot be triggered")
  else
    local SkyManager = foot100:GetGameObject("SkyFxManager")
    SkyManager:CallScript("StormySky")
  end
end
function ShowAllProps()
  RunFunctionOnObjectsInTable(cineProps, "Show")
end
function HideAllProps()
  RunFunctionOnObjectsInTable(cineProps, "Hide")
end
function PlaySoundLightningStrike()
  local foot050 = game.FindLevel("Foot050_Sound")
  if foot050 ~= nil then
    foot050:CallScript("PlaySoundLightningStrike")
  end
end
function SetSoundStateFoothillsStorm()
  local foot050 = game.FindLevel("Foot050_Sound")
  if foot050 ~= nil then
    foot050:CallScript("SetFoothillsStormSoundState", true)
  end
end
function CanSeqFire()
  return game.Level.GetVariable("CompletedCineNumber") < 450 and game.Level.GetVariable("CompletedCineNumber") >= 440
end
function StartCineEnter_SindriGetsServed()
  game.SubObject.Wake(thisObj)
  cameraCineEnter_SindriGetsServed = CCEC.CineEnterCamera.New("ENV_CineEnter_SindriGetsServed", 8)
  cameraCineEnter_SindriGetsServed:SetCallback(DestroyCineEnter_SindriGetsServed)
  cameraCineEnter_SindriGetsServed:Start()
end
function DestroyCineEnter_SindriGetsServed()
  cameraCineEnter_SindriGetsServed = nil
  game.SubObject.Sleep(thisObj)
end
