local LD = require("design.LevelDesignLibrary")
local ND = require("design.NarrativeDesignLibrary")
local actor = require("narrative.actor")
local CCEC = require("camera.camera_cineentercamera")
local timers = require("level.timer")
local uiCalls = require("ui.uicalls")
local kratosObj, freyaAiObj, boarAiObj, thisObj, kratosActor, sonActor, freyaActor, boarActor, boarMiniGameObject, thisLevel, cine_lights, vines00, vines01, cameraCineEnter_WitchIntro, cameraBridge_WitchIntroExit
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  kratosObj = game.Player.FindPlayer()
  boarMiniGameObject = GameObjects.BoarHealMiniGame
  game.SubObject.Sleep(thisObj)
  game.SubObject.SetForgetOnCheckpoint(thisObj)
end
function OnStart(level, obj)
  InitProps()
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  if cineNum < 150 then
    CreateActorsAndPositions()
    BuildWitchIntroSetup()
  elseif cineNum == 150 then
    SetVinesOpen()
  elseif 160 <= cineNum then
    SetVinesClosed()
  end
  HideLights()
end
function OnUpdate()
  if cameraCineEnter_WitchIntro ~= nil then
    cameraCineEnter_WitchIntro:Update()
  end
  if cameraBridge_WitchIntroExit ~= nil then
    cameraBridge_WitchIntroExit:Update()
  end
end
function CreateActorsAndPositions()
  kratosActor = actor.Actor.New("Kratos", game.Player.FindPlayer)
  sonActor = actor.Actor.New("Son", game.AI.FindSon)
  freyaActor = actor.Actor.New("Freya", ND.FindFreya)
  boarActor = actor.Actor.New("Boar", FindBoar)
end
function InitProps()
  cine_lights = GameObjects.Cine_Start_150
  vines00 = GameObjects.freyaCaveVines0.Child
  vines01 = GameObjects.freyaCaveVines1.Child
end
function HideLights()
  cine_lights:Hide()
end
function ShowLights()
  cine_lights:Show()
end
function BuildWitchIntroSetup()
  local seq = ND.CreateCineSequence(thisLevel, thisObj, "witchIntroIdle")
  local witchIntroIdle_actorTable = {
    {Actor = freyaActor},
    {Actor = boarActor}
  }
  seq:Do(SpawnFreya)
  seq:WaitForFunctionTrue(DoesFreyaExist)
  seq:WaitForFunctionTrue(DoesBoarExist)
  seq:ActorSync(sonActor, {
    Slaves = witchIntroIdle_actorTable,
    Branch = "BRA_WitchIntroIdle",
    ReferenceJoint = "WitchIntro_SyncJoint"
  })
  seq:StartSequence()
end
function BuildWitchIntroSeq()
  local seq = ND.CreateCineSequence(thisLevel, thisObj, "witchIntro")
  local witchIntro_actorTable = {
    {Actor = sonActor},
    {Actor = freyaActor},
    {Actor = boarActor},
    {
      Obj = vines00,
      Anim = "narWitchIntro030cineScene"
    },
    {
      Obj = vines01,
      Anim = "narWitchIntro030cineScene"
    }
  }
  seq:SetPostSkipMusic("SND_MX_RIV_start_master", "SND_MX_SonSick_master")
  seq:MarkAbleToSkip()
  seq:Do(CineMode_WithoutInteract)
  seq:Do(StartCineEnter_WitchIntro)
  seq:Do(function()
    kratosObj:CallScript("LuaHook_ForceCineRageModeExit")
  end)
  seq:ActorForceApproachAndWait(kratosActor, {
    Branch = "BRA_WitchIntroCine",
    ReferenceJoint = "WitchIntro_SyncJoint",
    speed = 6,
    stop = false,
    weapon_state = "bare_on_back",
    radius = 1.5
  })
  seq:Do(ShowLights)
  seq:Do(StartBoarGame)
  seq:Do(function()
    cine_lights:JumpAnimToFrame(0)
    cine_lights:PlayAnimToEnd()
  end)
  seq:ActorSync(kratosActor, {
    Slaves = witchIntro_actorTable,
    Branch = "BRA_WitchIntroCine",
    ReferenceJoint = "WitchIntro_SyncJoint"
  })
  seq:WaitForFunctionTrue(IsKratosNotPlayingEnterMove)
  seq:Do(function()
    if seq.skipping then
      SkipBoarGame()
    else
      seq:EndSkipIfActive()
    end
  end)
  seq:WaitForFunctionTrue(IsKratosPlayingExitMove)
  seq:Do(function()
    if not seq.skipping then
      seq:MarkAbleToSkip()
    end
  end)
  seq:WaitUntilActorAnimPastPercentage(kratosActor, 0.69)
  seq:Do(ShowForcedCamera_WitchIntroExit)
  seq:WaitForActorPuppeteerComplete(kratosActor)
  seq:WaitForLoadCheck("Riv575_FreyaVista")
  seq:WaitForLoadCheck("Riv480_c160_WitchHouseA")
  seq:Do(End_CineMode_WithoutInteract)
  seq:Do(HideLights)
  seq:StopPuppetingActor(sonActor)
  seq:StopPuppetingActor(kratosActor)
  seq:StopPuppetingActor(freyaActor)
  seq:StopPuppetingActor(boarActor)
  seq:SetCompletedCineNumber(150)
  seq:Do(HideForcedCamera_WitchIntroExit)
  seq:Do(function()
    kratosObj.Pad:DisableGameButton(tweaks.ePad.kPadR2)
  end)
  seq:Do(CompleteQuestObj430)
  seq:Do(SetCineComplete)
  seq:WaitUntilActorAnimPastPercentage(kratosActor, 0.965)
  seq:StartSequence()
end
function CompleteQuestObj430()
  LD.CompleteQuest("Quest_RiverPass_Objective430")
end
function QuestObj430UI()
  uiCalls.UI_Event_SendMsgToQuestLog({
    Category = 10250,
    Header = 9086,
    Body = 690,
    MessageType = tweaks.tQuestUiMessage.eMessageType.kQMS_Default,
    Quest = "Quest_RiverPass_Objective455"
  })
end
function StartBoarGame()
  boarMiniGameObject.LuaObjectScript.StartMiniGame(true)
end
function SkipBoarGame()
  boarMiniGameObject.LuaObjectScript.AbortMinigame()
end
function CineMode_WithoutInteract()
  local pad = kratosObj.Pad
  pad:DisableGameButton(tweaks.ePad.kPadUp)
  game.Cinematics.EnableCinematicMode()
  pad:DisableGameButton(tweaks.ePad.kPadSquare)
end
function End_CineMode_WithoutInteract()
  local pad = kratosObj.Pad
  pad:EnableGameButton(tweaks.ePad.kPadUp)
  game.Cinematics.DisableCinematicMode()
end
function SetVinesClosed()
  vines00:StartAnim("narWitchIntro030cineScene")
  vines01:StartAnim("narWitchIntro030cineScene")
  vines00:JumpAnimToFrame(0)
  vines01:JumpAnimToFrame(0)
  vines00:PauseAnim()
  vines01:PauseAnim()
end
function SetVinesOpen()
  vines00:StartAnim("narWitchIntro030cineScene")
  vines01:StartAnim("narWitchIntro030cineScene")
  vines00:JumpAnimToFrame(vines00.AnimLengthFrames)
  vines01:JumpAnimToFrame(vines01.AnimLengthFrames)
  vines00:PauseAnim()
  vines01:PauseAnim()
  GameObjects.FreyaDoor:JumpAnimToFrame(GameObjects.FreyaDoor.AnimLengthFrames)
  GameObjects.FreyaDoor:HideParticleEmitter()
end
function SpawnFreya()
  if LD.FindFreya() == nil then
    local spawnPosVector = LD.GetWorldJointPosition("Cine_WitchIntro", "FreyaSpawn")
    local spawnDirVector = LD.GetWorldJointForward("Cine_WitchIntro", "FreyaSpawn")
    local seq = ND.CreateCineSequence(thisLevel, thisLevel, "SPAWN FREYA FROM RIV455")
    seq:WaitForFunctionTrue(function()
      return game.FindLevel("FreyaLvl100_Global")
    end)
    seq:Do(function()
      ND.SpawnFreyaAtVector(spawnPosVector, spawnDirVector)
    end)
    seq:StartSequence()
  end
end
function IsKratosPlayingExitMove()
  return kratosObj:IsPlayingMove("MOV_WitchIntroMiniGame_Exit")
end
function IsKratosNotPlayingEnterMove()
  return not kratosObj:IsPlayingMove("MOV_WitchIntroCineEnter")
end
function DoesFreyaExist()
  local freyaAiObject
  freyaAiObject = ND.CatchFreyaReference(freyaAiObject)
  if freyaAiObject ~= nil then
    return true
  else
    return false
  end
end
function FindBoar()
  local boarReference
  local objArray = game.World.FindGameObjectsByMarker("WitchHouseBoar")
  if 1 < #objArray then
    error("Warning: there are multiple boars, getting reference will be unpredictable.")
    return boarReference
  else
    for _, obj in ipairs(objArray) do
      if obj:GetCreature() ~= nil and obj:GetCreature():GetAI() ~= nil then
        boarReference = obj:GetCreature():GetAI()
      end
    end
    return boarReference
  end
end
function DoesBoarExist()
  local boarVariable = FindBoar()
  if boarVariable ~= nil then
    return true
  else
    return false
  end
end
function SetCineComplete()
  local riv475 = game.FindLevel("Riv475_FreyaHouseExt")
  if riv475 then
    game.UI.LoadCheck("Riv480_c160_WitchHouseA")
    timers.StartLevelTimer(0.1, function()
      riv475:GetGameObject("POI_FirstHeimili"):CallScript("BoarsRunAway")
    end)
  end
  timers.StartLevelTimer(6.5, QuestObj430UI)
  game.World.StoreCheckpoint()
  if riv475 then
    riv475:CallScript("EnableLTW")
  end
end
function DisableLeadTheWay()
  local riv475 = game.FindLevel("Riv475_FreyaHouseExt")
  if riv475 then
    riv475:CallScript("DisableLTW")
  end
end
function StartCineEnter_WitchIntro()
  game.SubObject.Wake(thisObj)
  cameraCineEnter_WitchIntro = CCEC.CineEnterCamera.New("ENV_CineEnter_WitchIntro", 8)
  cameraCineEnter_WitchIntro:SetCallback(DestroyCineEnter_WitchIntro)
  cameraCineEnter_WitchIntro:Start()
end
function DestroyCineEnter_WitchIntro()
  cameraCineEnter_WitchIntro = nil
  game.SubObject.Sleep(thisObj)
end
function ShowForcedCamera_WitchIntroExit()
  GameObjects.CamZone_Forced_WitchIntroExit:ShowCameraVolume()
end
function HideForcedCamera_WitchIntroExit()
  timers.StartLevelTimer(18, function()
    GameObjects.CamZone_Forced_WitchIntroExit:HideCameraVolume()
  end)
end
