local LD = require("design.LevelDesignLibrary")
local timer = require("level.timer")
local checkpoint = require("level.checkpoint")
local actor = require("narrative.actor")
local CCOS = require("camera.camera_oneshot")
local monitors = require("level.MonitorLibrary")
local thisObj, thisLevel, player
local LOTakedownPlayed = false
local DOActor1, DOActor2, DOActor3, LightOne, DarkOne01, DarkOne02, darkOneSpear01, darkOneSpear02, animMonitorDO1, animMonitorDO2
local soundMonitorState = 0
local camOneShotLOTakedown, LOTakedownEnterSeq
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  game.SubObject.Sleep(thisObj)
  player = game.Player.FindPlayer()
end
function OnStart(level, obj)
  if LOTakedownPlayed == false then
    CreateActors()
    SetupSpawnCallbacks()
  end
end
function SetupSpawnCallbacks()
  local cineEncounter = _G.GetCineEncounter()
  cineEncounter:OnEnemySpawn(SetActor01_SpawnCallback, {wave = 1, element = 1})
  cineEncounter:OnEnemySpawn(SetActor02_SpawnCallback, {wave = 2, element = 1})
  cineEncounter:OnEnemySpawn(SetActor03_SpawnCallback, {wave = 2, element = 2})
end
local actor01_creature, actor02_creature, actor03_creature
function SetActor01_SpawnCallback(creature)
  actor01_creature = creature
  DOActor1:SetSpawnFunction(function()
    return actor01_creature
  end)
end
function SetActor02_SpawnCallback(creature)
  actor02_creature = creature
  DOActor2:SetSpawnFunction(function()
    return actor02_creature
  end)
end
function SetActor03_SpawnCallback(creature)
  actor03_creature = creature
  DOActor3:SetSpawnFunction(function()
    return actor03_creature
  end)
end
function CreateActors()
  DOActor1 = actor.Actor.New("LO TAKEDOWN: Dark One Actor 1")
  DOActor2 = actor.Actor.New("LO TAKEDOWN: Dark One Actor 2")
  DOActor3 = actor.Actor.New("LO TAKEDOWN: Dark One Actor 3")
  LightOne = GameObjects.LightOne_LOTakeDown.Child
  DarkOne01 = GameObjects.darkOneCine01.Child
  DarkOne02 = GameObjects.darkOneCine02.Child
  darkOneSpear01 = GameObjects.darkOneSpear01.Child
  darkOneSpear01:SetCharacterConfig("spear")
  darkOneSpear02 = GameObjects.darkOneSpear02.Child
  darkOneSpear02:SetCharacterConfig("spear")
  DarkOne01:AddMarker("strongLOTakedown_DarkOne01")
  DarkOne02:AddMarker("strongLOTakedown_DarkOne02")
  animMonitorDO1 = monitors.CreateAnimFrameMonitor(DarkOne01)
  animMonitorDO2 = monitors.CreateAnimFrameMonitor(DarkOne02)
end
function ShowLuaChars()
  LightOne:Show()
  DarkOne01:Show()
  DarkOne02:Show()
end
function HideLuaChars()
  DarkOne01:PauseAnim()
  DarkOne02:PauseAnim()
  DarkOne01:Hide()
  DarkOne02:Hide()
  darkOneSpear01:Hide()
  darkOneSpear02:Hide()
end
function LOTakedownENTERSequence()
  if LOTakedownPlayed == false then
    LOTakedownEnterSeq = LD.CreateCineSequence(thisLevel, thisObj, "Light One Takedown Setup")
    local LOTakedownEnter_ActorTable = {
      {
        Obj = DarkOne01,
        Anim = "envAlfStrongLightOneTakedown0101"
      },
      {
        Obj = DarkOne02,
        Anim = "envAlfStrongLightOneTakedown0102"
      },
      {
        Obj = LightOne,
        Anim = "envAlfStrongLightOneTakedown010"
      },
      {
        Obj = darkOneSpear01,
        Anim = "envAlfStrongLightOneTakedown0101"
      },
      {
        Obj = darkOneSpear02,
        Anim = "envAlfStrongLightOneTakedown0102"
      }
    }
    LOTakedownEnterSeq:Do(function()
      _G.GetCineEncounter():Start()
    end)
    LOTakedownEnterSeq:WaitForFunctionTrue(function()
      return actor01_creature ~= nil
    end)
    LOTakedownEnterSeq:SpawnActorAndWait(DOActor1)
    LOTakedownEnterSeq:Do(function()
      actor01_creature:AddMarker("LOTakedown_DarkOneMaster")
    end)
    LOTakedownEnterSeq:Do(ShowLuaChars)
    LOTakedownEnterSeq:Do(StartTakedownEnterMonitors)
    LOTakedownEnterSeq:RequestCineModeAndWait(DOActor1, thisObj, true)
    LOTakedownEnterSeq:ActorSync(DOActor1, {
      Slaves = LOTakedownEnter_ActorTable,
      Branch = "BRA_AlfStrongLightOneTakedown",
      ReferenceJoint = "LOTakedown_SynchJoint"
    })
    LOTakedownEnterSeq:Do(CameraActivateZoomDelay)
    LOTakedownEnterSeq:WaitForActorPlayingMove(DOActor1, "MOV_AlfStrongLightOneTakedownLoop")
    LOTakedownEnterSeq:Do(ChangeAnimMonitors)
    LOTakedownEnterSeq:StartSequence()
  end
end
function LOTakedownEXITSequence()
  soundMonitorState = 2
  ChangeAnimMonitors()
  if LOTakedownPlayed == false then
    local LOTakedownExitSeq = LD.CreateCineSequence(thisLevel, thisObj, "Light One Takedown Setup")
    local LOTakedownEnter_ActorTable = {
      {
        Actor = DOActor2,
        Branch = "BRA_AlfStrongLightOneTakedownExit1"
      },
      {
        Actor = DOActor3,
        Branch = "BRA_AlfStrongLightOneTakedownExit2"
      },
      {
        Obj = LightOne,
        Anim = "envAlfStrongLightOneTakedown030Exit"
      }
    }
    LOTakedownExitSeq:CancelSequence(LOTakedownEnterSeq)
    LOTakedownExitSeq:Do(function()
      _G.GetCineEncounter():StartWave(2)
    end)
    LOTakedownExitSeq:WaitForFunctionTrue(function()
      return actor02_creature ~= nil and actor03_creature ~= nil
    end)
    LOTakedownExitSeq:SpawnActorAndWait(DOActor2)
    LOTakedownExitSeq:SpawnActorAndWait(DOActor3)
    LOTakedownExitSeq:Do(HideLuaChars)
    LOTakedownExitSeq:RequestCineModeAndWait(DOActor1, thisObj, true)
    LOTakedownExitSeq:ActorSync(DOActor1, {
      Slaves = LOTakedownEnter_ActorTable,
      Branch = "BRA_AlfStrongLightOneTakedownExit",
      ReferenceJoint = "LOTakedown_SynchJoint2"
    })
    LOTakedownExitSeq:Do(function()
      LOTakedownPlayed = true
    end)
    LOTakedownExitSeq:WaitForAndCompleteCineMode(DOActor1, thisObj)
    LOTakedownExitSeq:StopPuppetingActor(DOActor1)
    LOTakedownExitSeq:StopPuppetingActor(DOActor2)
    LOTakedownExitSeq:StopPuppetingActor(DOActor3)
    LOTakedownExitSeq:StartSequence()
  end
end
function CameraActivateZoomDelay()
  timer.StartLevelTimer(8, CameraActivateZoom)
end
function CameraActivateZoom()
  game.SubObject.Wake(thisObj)
  camOneShotLOTakedown = CCOS.OneShotCamera.New("PLYR_CrackClimb_AlfRing_LightOne_Zoom", 6, nil)
  camOneShotLOTakedown:Start()
  camOneShotLOTakedown:SetCallback(DestroyCamera)
end
function DestroyCamera()
  game.SubObject.Sleep(thisObj)
  camOneShotLOTakedown = nil
end
function StartTakedownEnterMonitors()
end
function StartTakedownLoopMonitors()
end
function ChangeAnimMonitors()
  if soundMonitorState == 0 then
    soundMonitorState = 1
    animMonitorDO1:Stop()
    animMonitorDO2:Stop()
    animMonitorDO1:Terminate()
    animMonitorDO2:Terminate()
    animMonitorDO1 = nil
    animMonitorDO2 = nil
    animMonitorDO1 = monitors.CreateAnimFrameMonitor(DarkOne01)
    animMonitorDO2 = monitors.CreateAnimFrameMonitor(DarkOne02)
    StartTakedownLoopMonitors()
  elseif soundMonitorState == 2 then
    animMonitorDO1:Stop()
    animMonitorDO2:Stop()
    animMonitorDO1:Terminate()
    animMonitorDO2:Terminate()
    animMonitorDO1 = nil
    animMonitorDO2 = nil
  end
end
function OnUpdate(level, obj)
  if camOneShotLOTakedown ~= nil and game.World.IsInsideCameraZone(player.WorldPosition, "CamZone_HalfLife_LookAt") then
    camOneShotLOTakedown:Update()
  end
end
function OnSaveCheckpoint(level, obj)
  local savedInfo = {
    LOTakedownPlayed = LOTakedownPlayed,
    LevelState = checkpoint.Save()
  }
  return savedInfo
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  checkpoint.Restore(savedInfo.LevelState)
  LOTakedownPlayed = savedInfo.LOTakedownPlayed
end
