local LD = require("design.LevelDesignLibrary")
local ND = require("design.NarrativeDesignLibrary")
local timer = require("level.timer")
local checkpoint = require("level.checkpoint")
local actor = require("narrative.actor")
local color = require("core.color")
local CCEC = require("camera.camera_cineentercamera")
local uiCalls = require("ui.uicalls")
local thisObj, thisLevel, player, son, pad, kraActor, sonActor, candlesA, candlesB, candlesC, tableA, body, mistletoeleaves
local thor = GameObjects.Thor.Child
local thorHammer = GameObjects.thorHammer00_Top.Child
local kratosHouseWindow00, kratosHouseWindow01, cine_lights_620
local TriggerFade = GameObjects.Cine_GoToBed_FadeToBlack
local TriggerFade2 = GameObjects.Cine_Start_620_exposure
local cineEnterCamera_Epilogue
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  player = game.Player.FindPlayer()
  pad = player.Pad
  game.SubObject.Sleep(thisObj)
  SoundInit()
end
function OnStart(level, obj)
  SetupActors()
  HideThor()
  SetupWindows()
  SoundSetup()
  HideFadeToBlack2()
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  if 610 <= cineNum and cineNum < 620 then
    HideTable()
    EnableDoor()
    SetUpLights()
  else
    HideCineLights()
  end
end
function OnUpdate()
  if cineEnterCamera_Epilogue ~= nil then
    cineEnterCamera_Epilogue:Update()
  end
end
function SetupActors()
  kraActor = actor.Actor.New("OPENING: Kratos Actor", game.Player.FindPlayer)
  sonActor = actor.Actor.New("OPENING: Son Actor", game.AI.FindSon)
end
function EpilogueCine()
  local cloth = GameObjects.retrieveBladesCloth
  cloth:JumpAnimToFrame(0)
  cloth:PauseAnim()
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  local lateSoundFadeIn = false
  if 610 <= cineNum and cineNum < 620 then
    game.UI.LoadCheck("For200_c620_Epilogue")
    local doorObj = GameObjects.KratosHouseDoorA.Child
    kratosHouseWindow00 = GameObjects.kratosHouseWindow00_Top.Child
    kratosHouseWindow01 = GameObjects.kratosHouseWindow01_Top.Child
    local epilogueSeq = ND.CreateCineSequence(thisLevel, thisObj, "epilogue")
    local epilogue_ActorTable = {
      {
        Actor = sonActor,
        Branch = "BRA_EpilogueCine"
      },
      {
        Obj = doorObj,
        Anim = "narForEpilogue000CineScene"
      },
      {
        Obj = thor,
        Anim = "narForEpilogue000CineScene"
      },
      {
        Obj = thorHammer,
        Anim = "narForEpilogue000CineScene"
      },
      {
        Obj = kratosHouseWindow00,
        Anim = "narForEpilogue000CineScene"
      },
      {
        Obj = kratosHouseWindow01,
        Anim = "narForEpilogue000CineScene1"
      }
    }
    epilogueSeq:RequestCineModeAndWait(kraActor, thisObj)
    epilogueSeq:Do(ShowThor)
    epilogueSeq:Do(StartCineEnter_Epilogue)
    epilogueSeq:ActorForceApproachAndWait(kraActor, {
      Branch = "BRA_EpilogueCine",
      ReferenceJoint = "Epilogue_SynchJoint",
      speed = ND.KraWalkSpeed,
      stop = false,
      radius = ND.InteractStopDistance,
      should_strafe = true,
      weapon_state = "axe"
    })
    epilogueSeq:ActorSync(kraActor, {
      Slaves = epilogue_ActorTable,
      Branch = "BRA_EpilogueCine",
      ReferenceJoint = "Epilogue_SynchJoint"
    })
    epilogueSeq:SetPostSkipMusic("SND_MX_PRO_start_master")
    epilogueSeq:Do(function()
      epilogueSeq:MarkAbleToSkip()
    end)
    epilogueSeq:Do(YearsLaterOverlay)
    epilogueSeq:WaitUntilActorAnimPastPercentage(kraActor, 0.745)
    epilogueSeq:Do(function()
      epilogueSeq:EndSkipIfActive()
    end)
    epilogueSeq:Do(FadeToBlack_UI)
    epilogueSeq:WaitForFunctionTrue(function()
      return player:IsPlayingMove("MOV_EpilogueCine")
    end)
    epilogueSeq:Do(PlayFX)
    epilogueSeq:Do(PlaySoundOnThor)
    epilogueSeq:Do(PlayCineLights)
    epilogueSeq:WaitUntilActorAnimPastPercentage(kraActor, 0.05)
    epilogueSeq:Do(CrashfromBlack_UI)
    epilogueSeq:Do(function()
      epilogueSeq:MarkAbleToSkip()
    end)
    epilogueSeq:WaitUntilActorAnimPastPercentage(kraActor, 0.989)
    epilogueSeq:Do(function()
      if epilogueSeq.skipping then
        lateSoundFadeIn = true
      end
    end)
    epilogueSeq:Do(function()
      epilogueSeq:EndSkipIfActive(nil, true)
    end)
    epilogueSeq:Do(CrashToBlack_UI)
    epilogueSeq:WaitForActorNotPlayingMove(kraActor, "MOV_EpilogueCine")
    epilogueSeq:WaitUntilActorAnimPastPercentage(kraActor, 0.999)
    epilogueSeq:Do(HideCineLights)
    epilogueSeq:WaitForAndCompleteCineMode(kraActor, thisObj)
    epilogueSeq:StopPuppetingActor(kraActor)
    epilogueSeq:StopPuppetingActor(sonActor)
    epilogueSeq:Do(IdlePlayerAndSon)
    epilogueSeq:Do(HideThor)
    epilogueSeq:Do(SetupWindows)
    epilogueSeq:Do(HideFX)
    epilogueSeq:Do(SetRoofStates)
    epilogueSeq:Do(function()
      if lateSoundFadeIn then
        timer.StartLevelTimer(3, function()
          game.Audio.MusicFadeIn(1)
        end)
      end
    end)
    epilogueSeq:SetCompletedCineNumber(620)
    epilogueSeq:StartSequence()
  end
end
function FadeToBlack_UI()
  uiCalls.UI_Event_Fade_To_Black(1)
end
function YearsLaterOverlay()
  game.UI.Anim(GameObjects.TimeSkipMessageTO, 0, "", 1, 0)
end
function CrashToBlack_UI()
  uiCalls.UI_Event_Fade_To_Black(0)
  game.Audio.SetWwiseState("Credits", "in")
  LD.CallFunctionAfterDelay(function()
    local EVT_UI_Control = 300
    local PlayCreditsScrollID = 1234
    game.Audio.StartMusic("SND_MX_credits_roll_02_in")
    game.UI.SendEvent("Credits", EVT_UI_Control, PlayCreditsScrollID)
  end, 11)
end
function IdlePlayerAndSon()
  game.UI.Idle(true)
  local availabilityState = {
    AvailableForSync = false,
    AvailableForBanter = false,
    AvailableInLevel = false,
    AvailableForCombat = false
  }
  game.AI.FindSon():SetNewAvailabilityRequest("LevelDesignScript", availabilityState)
  pad:DisableGameButton(tweaks.ePad.kPadUp)
  pad:DisableGameButton(tweaks.ePad.kPadRightStickX)
  pad:DisableGameButton(tweaks.ePad.kPadRightStickY)
end
function FadefromBlack_UI()
  uiCalls.UI_Event_Fade_In(1.5)
end
function CrashfromBlack_UI()
  uiCalls.UI_Event_Fade_In(0)
end
function PlayFX()
  local cineWad = game.FindLevel("For200_c620_Epilogue")
  if cineWad ~= nil then
    cineWad:CallScript("PlayFX")
  end
end
function SetRoofStates()
  GameObjects.House_Roof_Hires_Pristine:Show()
  GameObjects.SCRIPTED_House_Roof_Hires_Broken_Section:Hide()
end
function HideFX()
  local cineWad = game.FindLevel("For200_c620_Epilogue")
  if cineWad ~= nil then
    cineWad:CallScript("HideFX")
  end
end
function PostCineFixUp()
  LD.CallFunctionAfterDelay(function()
    GameObjects.KratosHouseDoorA.Child.LuaObjectScript.Enable()
    game.Audio.PlayBanter("Post Game")
  end, 3.5)
  local cineWad = game.FindLevel("For200_c620_Epilogue")
  if cineWad ~= nil then
    cineWad:CallScript("ResetRoof")
  end
  _G.HideTrapDoorRug()
end
function HideIdleBanterZone()
  GameObjects.EntZn_HouseIntCineArea:HideEntityVolume()
end
function HideThor()
  thor:Hide()
  if thor:GetAnimationName() ~= nil then
    thor:PauseAnim()
  end
  thorHammer:Hide()
end
function ShowThor()
  thor:Show()
  thorHammer:Show()
end
function PlayFadeToBlack()
  TriggerFade:Show()
  TriggerFade:JumpAnimToFrame(0)
  TriggerFade:PlayAnimToEnd()
  game.UI.Anim(GameObjects.TimeSkipMessageTO, 0, "", 1, 0)
end
function PresentDayText()
  game.UI.Anim(GameObjects.PresentDayMessageTO, 0, "", 1, 0)
end
function PlayFadeToBlack2()
  TriggerFade2:Show()
  TriggerFade2:JumpAnimToFrame(0)
  TriggerFade2:PlayAnimToEnd()
end
function HideFadeToBlack2()
  TriggerFade2:Hide()
end
function HideTable()
  candlesA = GameObjects.mothersCandles00A.Child
  candlesB = GameObjects.mothersCandles00B.Child
  candlesC = GameObjects.smallCandle00A.Child
  tableA = GameObjects.mothersTable00A.Child
  body = GameObjects.motherBody00A.Child
  mistletoeleaves = GameObjects.mistletoeLeaves00A.Child
  candlesA:Hide()
  candlesB:Hide()
  candlesC:Hide()
  tableA:Hide()
  body:Hide()
  mistletoeleaves:Hide()
end
function EnableDoor()
  print("========= ENABLE DOOR FROM EPILOGUE ========")
  local kratosHouseDoor = GameObjects.KratosHouseDoorA.Child
  kratosHouseDoor.LuaObjectScript.Enable()
end
function SetupWindows()
  kratosHouseWindow00 = GameObjects.kratosHouseWindow00_Top.Child
  kratosHouseWindow01 = GameObjects.kratosHouseWindow01_Top.Child
  kratosHouseWindow00:StartAnim("narForEpilogue000CineScene")
  kratosHouseWindow01:StartAnim("narForEpilogue000CineScene1")
  kratosHouseWindow00:JumpAnimToFrame(50)
  kratosHouseWindow01:JumpAnimToFrame(50)
  kratosHouseWindow00:PauseAnim()
  kratosHouseWindow01:PauseAnim()
end
function SetUpLights()
  print("=========== SET UP CINE LIGHTS 620 ===========")
  cine_lights_620 = GameObjects.Cine_Start_620
  cine_lights_620:Show()
  cine_lights_620:JumpAnimToFrame(0)
  cine_lights_620:PauseAnim()
end
function PlayCineLights()
  print("=========== PLAY LIGHTS 620 ===========")
  cine_lights_620:JumpAnimToFrame(0)
  cine_lights_620:PlayAnimToEnd()
end
function HideCineLights()
  print("=========== HIDE CINE LIGHTS 620 ===========")
  cine_lights_620 = GameObjects.Cine_Start_620
  cine_lights_620:Hide()
  TriggerFade:Hide()
end
local soundEmitter
local soundEvents = {
  isLooping = false,
  OnThor = "SND_CINE_EpilogueTeaser_Thor_Foley_Stem"
}
function SoundInit()
  soundEmitter = GameObjects.SNDGrpEpilogueTeaser:FindSingleSoundEmitterByName("SNDEpilogueTeaser")
end
function SoundSetup(sounds)
  if sounds ~= nil then
    if sounds.SoundEmitter ~= nil then
      soundEmitter = thisObj:FindSingleSoundEmitterByName(sounds.SoundEmitter)
    end
    for key in pairs(soundEvents) do
      for newKey, newValue in pairs(sounds) do
        if newKey == key and newValue ~= nil and newValue ~= "" then
          soundEvents[key] = newValue
        end
      end
    end
  end
end
function PlaySoundOnThor()
  LD.PlaySound(soundEmitter, soundEvents.OnThor)
end
function StartCineEnter_Epilogue()
  game.SubObject.Wake(thisObj)
  cineEnterCamera_Epilogue = CCEC.CineEnterCamera.New("ENV_CineEnter_Epilogue", 7)
  cineEnterCamera_Epilogue:SetCallback(DestroyCineEnter_Epilogue)
  cineEnterCamera_Epilogue:Start()
end
function DestroyCineEnter_Epilogue()
  cineEnterCamera_Epilogue = nil
  game.SubObject.Sleep(thisObj)
end
