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, brokActor, sindActor
local huldraReunionBranchStr = "BRA_HuldraReunion"
local synchJointStr = "HuldraReunion_SynchJoint"
local cinePropsObj, brokBrandObj, sindBrandObj, skapslagObj, sindriBagObj, keyObj, journalObj, hammerProp, bladeProp, shopInteract, cine_lights_510, cameraCineEnter_HuldraReunion
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  game.SubObject.Sleep(obj)
  game.SubObject.SetForgetOnCheckpoint(obj)
end
function OnStart(level, obj)
  InitializeVariables()
  cine_lights_510 = GameObjects.Cine_Start_510
  HideCineLights()
end
function OnUpdate()
  if cameraCineEnter_HuldraReunion ~= nil then
    cameraCineEnter_HuldraReunion:Update()
  end
end
function InitializeVariables()
  SetupProps()
  local currentCineNumber = game.Level.GetVariable("CompletedCineNumber")
  if currentCineNumber < 510 and 492 <= currentCineNumber then
    GameObjects.Btr_Cal120.LuaObjectScript.DisableTalkInteract()
    SetupActors()
  end
end
function TrySetup()
  if CanSeqFire() then
    SetupCinematicTrigger()
    SetupCineSequence()
  end
end
function SpawnBrok()
  return _G.LoadBrokVendor(true)
end
function SpawnSindri()
  return ND.SpawnAIAtJoint(thisLevel, "Cine_HuldraReunion", synchJointStr, "CRT_Sindri00", huldraReunionBranchStr, "sindri")
end
function SetupProps()
  cinePropsObj = thisObj:FindSingleGOByName("CineProps")
  brokBrandObj = cinePropsObj:FindSingleGOByName("brokBrandProp").Child
  sindBrandObj = cinePropsObj:FindSingleGOByName("sindriBrandProp").Child
  skapslagObj = cinePropsObj:FindSingleGOByName("skapslagProp").Child
  sindriBagObj = cinePropsObj:FindSingleGOByName("sindriMagicBagProp").Child
  keyObj = cinePropsObj:FindSingleGOByName("templeFlipKeyProp").Child
  journalObj = cinePropsObj:FindSingleGOByName("sonJournalProp").Child
  HideProps()
  hammerProp = GameObjects.brokHammerProp.Child
  bladeProp = GameObjects.workBlade.Child
end
function SetupCinematicTrigger()
  shopInteract = GameObjects.LargeShop:FindSingleGOByName("vendorInteract")
  shopInteract.LuaObjectScript.EnableCinematicTrigger()
end
function ClearCinematicTrigger()
  GameObjects.Btr_Cal120.LuaObjectScript.EnableTalkInteract(true)
  shopInteract.LuaObjectScript.DisableCinematicTrigger()
end
function SetupActors()
  kraActor = actor.Actor.New("HULDRA REUNION: Kratos Actor", game.Player.FindPlayer)
  sonActor = actor.Actor.New("HULDRA REUNION: Son Actor", game.AI.FindSon)
  brokActor = actor.Actor.New("HULDRA REUNION: Brok Actor")
  sindActor = actor.Actor.New("HULDRA REUNION: Sindri Actor")
  brokActor:SetSpawnFunction(SpawnBrok)
  sindActor:SetSpawnFunction(SpawnSindri)
end
function SetupCineSequence()
  local cineSeq = LD.CreateCineSequence(thisLevel, thisObj, "Huldra Reunion Sequence")
  local slaveTab = {
    {Actor = sonActor},
    {Actor = brokActor},
    {Actor = sindActor},
    {Obj = brokBrandObj},
    {Obj = sindBrandObj},
    {Obj = skapslagObj},
    {Obj = sindriBagObj},
    {Obj = keyObj},
    {Obj = journalObj},
    {Obj = hammerProp}
  }
  cineSeq:SetPostSkipMusic("SND_MX_CAL_start_master", "SND_MX_SonSick_master", "SND_MX_CAL_snake_belly_master")
  cineSeq:MarkAbleToSkip()
  cineSeq:WaitForLoadCheck("Cal120_AI_HuldraReunion")
  cineSeq:Do(_G.HuldraReunionStart)
  cineSeq:SpawnActorAndWait(brokActor)
  cineSeq:Do(function()
    brokActor:GetCreature():EndInteract()
  end)
  cineSeq:RequestCineModeAndWait(kraActor, thisObj)
  cineSeq:Do(StartCineEnter_HuldraReunion)
  cineSeq:SpawnActorAndWait(sindActor)
  cineSeq:ActorForceApproachAndWait(kraActor, {
    Branch = huldraReunionBranchStr,
    ReferenceJoint = synchJointStr,
    speed = ND.KraWalkSpeed,
    stop = false,
    radius = ND.StopTurnRadius,
    weapon_state = "bare",
    strafe_distance = 1
  })
  cineSeq:Do(PlayCineLights)
  cineSeq:Do(ShowAndAlignProps)
  cineSeq:ActorSync(kraActor, {
    Slaves = slaveTab,
    Branch = huldraReunionBranchStr,
    ReferenceJoint = synchJointStr
  })
  cineSeq:WaitUntilActorAnimPastPercentage(brokActor, 0.04173)
  cineSeq:Do(HideBlade)
  cineSeq:WaitUntilActorAnimPastPercentage(brokActor, 0.991)
  cineSeq:StopPuppetingActor(brokActor)
  cineSeq:StopPuppetingActor(sindActor)
  cineSeq:Do(SetupShopSpawnSync)
  cineSeq:Do(HideProps)
  cineSeq:Do(ShowBladeHideHammer)
  cineSeq:WaitForAndCompleteCineMode(kraActor, thisObj)
  cineSeq:StopPuppetingActor(kraActor)
  cineSeq:Do(function()
    cineSeq:EndSkipIfActive()
  end)
  cineSeq:StopPuppetingActor(sonActor)
  cineSeq:SetCompletedCineNumber(510)
  cineSeq:Do(EnableHorn)
  cineSeq:WaitSeconds(2)
  cineSeq:Do(_G.HuldraReunionDone)
  cineSeq:Do(HideCineLights)
  cineSeq:Do(ClearCinematicTrigger)
  cineSeq:WaitForFunctionTrue(PlayerIsNotInTheShopMenu)
  cineSeq:Do(StartDoorObjective)
  cineSeq:Do(SaveBookmark)
  cineSeq:StartSequence()
end
function PlayerIsNotInTheShopMenu()
  return game.Player.FindPlayer():GetCurrentInteractObject() == nil
end
function CanSeqFire()
  local currentCineNumber = game.Level.GetVariable("CompletedCineNumber")
  return currentCineNumber < 510 and 500 <= currentCineNumber and LD.GetCurrentRealm() == "Midgard"
end
function ShowAndAlignProps()
  cinePropsObj:Show()
  hammerProp:Show()
  local jointIndex = thisObj:GetJointIndex(synchJointStr)
  local jointFace = thisObj:GetWorldJointForward(jointIndex)
  local jointPos = thisObj:GetWorldJointPosition(jointIndex)
  hammerProp:SetWorldPosition(jointPos)
  hammerProp:SetWorldFacing(jointFace)
end
function HideProps()
  cinePropsObj:Hide()
end
function HideBlade()
  bladeProp:Hide()
end
function ShowBladeHideHammer()
  bladeProp:Show()
  hammerProp:Hide()
end
function SetupShopSpawnSync()
  GameObjects.LargeShop.LuaObjectScript.BrokRequestHammerSync()
  local respawnSeq = LD.CreateCineSequence(thisLevel, thisObj, "Respawn Sindri after HuldraReunion Seq")
  respawnSeq:DespawnActor(sindActor)
  respawnSeq:WaitForFunctionTrue(function()
    return ND.FindSindri() == nil
  end)
  respawnSeq:WaitFrames(1)
  respawnSeq:Do(_G.LoadSindriVendor)
  respawnSeq:StartSequence()
end
function PlayCineLights()
  cine_lights_510:Show()
  cine_lights_510:JumpAnimToFrame(0)
  cine_lights_510:PlayAnimToEnd()
end
function HideCineLights()
  cine_lights_510:Hide()
end
function EnableHorn()
  local cal100 = game.FindLevel("Cal100_Hub")
  if cal100 ~= nil then
    cal100:CallScript("Horn_Enable")
  end
end
function StartDoorObjective()
  game.QuestManager.ProposeQuestState("Quest_Caldera_Objective680", "Complete")
end
function SaveBookmark()
  local bookmarks = require("design.Bookmarks")
  local tableEntry = bookmarks["BOOKMARK_" .. "29_Caldera_030_TempleKeyObtained"]
  game.World.StoreCheckpointAndBookmark(tableEntry)
end
function StartCineEnter_HuldraReunion()
  game.SubObject.Wake(thisObj)
  cameraCineEnter_HuldraReunion = CCEC.CineEnterCamera.New("ENV_CineEnter_HuldraReunion", 7)
  cameraCineEnter_HuldraReunion:SetCallback(DestroyCineEnter_HuldraReunion)
  cameraCineEnter_HuldraReunion:Start()
end
function DestroyCineEnter_HuldraReunion()
  cameraCineEnter_HuldraReunion = nil
  game.SubObject.Sleep(thisObj)
end
