local EC = require("design.Encounter")
local LD = require("design.LevelDesignLibrary")
local monitors = require("level.MonitorLibrary")
local uiCalls = require("ui.uicalls")
local CamCheck = require("camera.collisioncheck")
local TIMERS = require("level.timer")
local checkpoint = require("level.checkpoint")
local TUT = require("game.GlobalTutorials")
thisLevel = nil
player = nil
son = nil
local marker_LookUpWatchOut, bCanDoLookUpWatchOut, timer_LookUpWatchOut, bCamZone_UphillSet, bCamZone_DownhillSet, fightComplete, inputMask, axeIntroReady, EnemyLookatMonitor, Area_1_Encounter_1, Area_2_Encounter_1, Draugr_HealthMonitor, DraugrLookatMonitor, SpawnDraugrWave, Repop_A1E1
local enemiesKilled = 0
function OnScriptLoaded(level)
  thisLevel = level
  player = game.Player.FindPlayer()
  son = game.AI.FindSon()
  Draugr_Intro_Area_1_Fight_1()
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  if 375 < cineNumber then
    Repop_Area_1_Fight_1()
  end
  bCanDoLookUpWatchOut = false
  marker_LookUpWatchOut = level:GetGameObject("Marker_LookUpWatchOut")
  timer_LookUpWatchOut = TIMERS.StartLevelTimer(1.4)
  timer_LookUpWatchOut:Stop()
  bCamZone_UphillSet = false
  bCamZone_DownhillSet = false
  GameObjects.EntZn_TriggerSonExit:HideEntityVolume()
end
function OnFirstStart(level)
  marker_LookUpWatchOut:Hide()
end
function OnStart()
  GameObjects.IC_ArenaExit:HideCollision()
end
function OnStartGameFromThisLevel()
  local seq = LD.CreateCineSequence(thisLevel, thisLevel, "turnOnLTW")
  seq:WaitForFunctionTrue(DoesSkyExist)
  seq:Do(EnableLTW)
  seq:StartSequence()
end
function DoesSkyExist()
  return game.FindLevel("For000_Sky")
end
function EnableLTW()
  game.FindLevel("For000_Sky"):GetGameObject("ForestLeadTheWay").Child:CallScript("Enable")
  game.FindLevel("For000_Sky"):GetGameObject("ForestYouShallNotPass").Child:CallScript("Enable")
end
function OnUpdate(level)
  CameraLevelUpdate()
end
function OnSaveCheckpoint(level)
  return {
    levelstate = checkpoint.Save(),
    axeIntroReady = axeIntroReady
  }
end
function OnRestoreCheckpoint(level, savedInfo)
  checkpoint.Restore(savedInfo.levelstate)
  axeIntroReady = savedInfo.axeIntroReady
  if axeIntroReady then
    print("OnRestoreCheckpoint")
    GameObjects.Cine_AxeIntro_Group.LuaObjectScript.AxeIntro_SetupSon()
  end
end
function ShowRopeTutorialMsg()
  TUT.Rope_Tutorial()
end
function CameraLevelUpdate()
  if game.World.IsInsideCameraZone(player.WorldPosition, "CZ_ShowMarker_LookUpWatchOut") then
    local zonetohide = thisLevel:GetGameObject("CZ_ShowMarker_LookUpWatchOut")
    zonetohide:HideCameraVolume()
    bCanDoLookUpWatchOut = true
  end
  if game.World.IsInsideCameraZone(player.WorldPosition, "CZ_StabilizeTop") then
    local camerazone = thisLevel:GetGameObject("CZ_TopOfRope")
    camerazone:ShowCameraVolume()
    camerazone = thisLevel:GetGameObject("CZ_StabilizeTop")
    camerazone:HideCameraVolume()
    bCamZone_DownhillSet = false
  end
  if game.World.IsInsideCameraZone(player.WorldPosition, "CZ_TopOfRope") and bCamZone_DownhillSet == false then
    local camerazone = thisLevel:GetGameObject("CZ_StabilizeTop")
    camerazone:ShowCameraVolume()
    camerazone = thisLevel:GetGameObject("CZ_BottomOfRope")
    camerazone:HideCameraVolume()
    camerazone = thisLevel:GetGameObject("CZ_MiddleOfRope")
    camerazone:HideCameraVolume()
    camerazone = thisLevel:GetGameObject("CZ_TopOfRope")
    camerazone:HideCameraVolume()
    bCamZone_DownhillSet = true
  end
  if game.World.IsInsideCameraZone(player.WorldPosition, "CZ_BottomOfRope") and bCamZone_UphillSet == false then
    local camerazone = thisLevel:GetGameObject("CZ_MiddleOfRope")
    camerazone:ShowCameraVolume()
    camerazone = thisLevel:GetGameObject("CZ_TopOfRope")
    camerazone:HideCameraVolume()
    camerazone = thisLevel:GetGameObject("CZ_StabilizeTop")
    camerazone:ShowCameraVolume()
    bCamZone_UphillSet = true
  end
  if game.World.IsInsideCameraZone(player.WorldPosition, "CZ_ActivateZone_BottomOfRope") then
    local camerazone = thisLevel:GetGameObject("CZ_BottomOfRope")
    camerazone:ShowCameraVolume()
    bCamZone_UphillSet = false
  end
  if game.World.IsInsideCameraZone(player.WorldPosition, "CZ_LookUpWatchOut") and bCanDoLookUpWatchOut == true then
    local bIsInView = CamCheck.isTargetInFrustum(marker_LookUpWatchOut:GetWorldPosition(), 0, 0, 0.45, true)
    if bIsInView == true then
      local zonetohide = thisLevel:GetGameObject("CZ_LookUpWatchOut")
      zonetohide:HideCameraVolume()
      bCanDoLookUpWatchOut = false
      timer_LookUpWatchOut:Start()
    end
  end
  if timer_LookUpWatchOut.running == true and timer_LookUpWatchOut.fired == false then
    game.Camera.SubmitCameraByName("PLYR_LookUpWatchOut")
  end
end
function Draugr_Intro_Area_1_Fight_1()
  Area_1_Encounter_1 = EC.NewEncounter(thisLevel, "[Area 1]EC:1 Draugrs For550", {
    CheckpointOnComplete = false,
    StopMusic = "SND_MX_PRO_fight_1_out"
  })
  Area_1_Encounter_1:AddWave({
    {
      spawners = "Draugr_L_E3",
      markerID = "Draugr_Intro",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  Area_1_Encounter_1:AddWave({
    triggerWaveFromScript = true,
    {
      spawners = "Draugr_L_SFA",
      spawnLocators = "A1_B_Loc_1",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  Area_1_Encounter_1:AddWave({
    triggerWaveFromScript = true,
    {
      spawners = "Draugr_L_SFG",
      spawnLocators = "A1_A_Loc_8",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 1
    }
  })
  Area_1_Encounter_1:AddWave({
    triggerWaveFromScript = true,
    {
      spawners = "Draugr_L_SRFE",
      spawnLocators = "A1_B_Loc_2",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  Area_1_Encounter_1:AddWave({
    triggerWaveFromScript = true,
    {
      spawners = "Draugr_L_SFG",
      spawnLocators = "A1_A_Loc_9",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "Draugr_L_SFG",
      spawnLocators = "A1_A_Loc_10",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 2
    }
  })
  Area_1_Encounter_1:AddWave({
    triggerWaveFromScript = true,
    {
      spawners = "Draugr_L_SFA",
      spawnLocators = "A1_B_Loc_1",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "Draugr_L_SFG",
      spawnLocators = "A1_A_Loc_8",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 4
    }
  })
  Area_1_Encounter_1:OnEnemyDeath(function()
    Area_1_Encounter_1:StartWave(3)
  end, {count = 1})
  Area_1_Encounter_1:OnEnemyDeath(function()
    Area_1_Encounter_1:StartWave(4)
    uiCalls.UI_Event_TurnOffDesignerMessage()
  end, {count = 2})
  Area_1_Encounter_1:OnEnemyDeath(function()
    LD.CallFunctionAfterDelay(function()
      Area_1_Encounter_1:StartWave(5)
    end, 4.5)
    LD.CallFunctionAfterDelay(function()
      Tutorial_Block()
    end, 1.5)
  end, {count = 4})
  Area_1_Encounter_1:OnEnemyDeath(function()
    Area_1_Encounter_1:StartWave(6)
  end, {count = 5})
  Area_1_Encounter_1:OnStart(function()
    local For500 = game.FindLevel("For500_ForestEntry")
    For500:CallScript("HideTraverseLinkForBrokenForest")
    game.FindLevel("For000_Sky"):CallScript("EnableLeadTheWay")
    game.FindLevel("For000_Sky"):CallScript("DisableNoPass")
    LD.CallFunctionAfterDelay(function()
      GameObjects.TurnOnOffSlide:ShowCollision()
    end, 3.5)
  end)
  Area_1_Encounter_1:OnComplete(function()
    LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_Draugr_Base")
    local For500 = game.FindLevel("For500_ForestEntry")
    For500:CallScript("ShowTraverseLinkForBrokenForest")
    axeIntroReady = false
    LD.CallFunctionAfterDelay(function()
      uiCalls.UI_Event_TurnOffDesignerMessage()
    end, 0.25)
    LD.CallFunctionAfterDelay(function()
      GameObjects.EntZn_TriggerSonExit:ShowEntityVolume()
    end, 2.5)
    local For050snd = game.FindLevel("For050_Sound")
    For050snd:CallScript("spireMusVarChange")
  end)
  Area_1_Encounter_1:OnStart(FirstFightStarted)
  Area_1_Encounter_1:OnComplete(FirstFightEnded)
  Area_1_Encounter_1:OnEnemySpawn(Draugr_Health_Encounter, {
    markerID = "Draugr_Intro"
  })
end
function SonExitDraugrIdle()
  local for550 = game.FindLevel("For550_BrokenForest")
  local cineObj
  if for550 ~= nil then
    cineObj = for550:FindSingleGameObject("Cine_AxeIntro_Group")
    cineObj:CallScript("SonExitDraugrFight")
  end
end
function Tutorial_Block()
  print("Tutorial_Block")
  TUT.BlockAndEvade_Tutorial()
end
local Draugr_Next = function()
  Area_1_Encounter_1:StartWave(2)
  game.Audio.PlayBanter("130_DraugrSurprise_Above")
end
function Draugr_Health_Encounter(Enemy)
  if Enemy ~= nil then
    local Draugr_Health = Enemy:GetHitPoints()
    Draugr_HealthMonitor = monitors.CreateHealthMonitor(Enemy)
    local Health_Phase_1 = Draugr_Health * 0.25
    Draugr_HealthMonitor:OnHealthLessThan(Health_Phase_1, Draugr_Next)
  end
end
function Repop_Area_1_Fight_1()
  local powerLevel01, powerLevel02
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  if 375 <= cineNumber and cineNumber <= 599 then
    powerLevel01 = 4
    powerLevel02 = 5
  elseif 600 <= cineNumber then
    powerLevel01 = 5
    powerLevel02 = 6
  end
  Repop_A1E1 = EC.NewEncounter(thisLevel, "[Repop Area 1]EC:1 For550", {
    CheckpointOnComplete = false,
    LeashZone = "NavLeashRepop",
    RepopulationEncounter = true,
    MustHaveCompletedList = {
      "[Area 1]EC:1 Draugrs For550"
    }
  })
  Repop_A1E1:AddWave({
    prioritizeOnScreenSpawners = true,
    requireSpawnersInRange = {4, 20},
    {
      spawners = "T4_Draugr_M_SFG",
      spawnLocators = "A1_A_Loc_*",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0,
      powerLevel = powerLevel01
    },
    {
      spawners = "T4_Draugr_M_SFG",
      spawnLocators = "A1_A_Loc_*",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 2,
      powerLevel = powerLevel01
    },
    {
      spawners = "T4_Draugr_M_SFG",
      spawnLocators = "A1_A_Loc_*",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 4,
      powerLevel = powerLevel02
    }
  })
  Repop_A1E1:SetStartZone(GameObjects.EntZn_Repop_Area_1)
end
function StartSonLookatMonitor()
  if 0 < game.Camera.GetViewPenetration(engine.Vector.New(-98, 54.25, -788), 0, 0) then
    SonExitDraugrIdle()
  else
    EnemyLookatMonitor = monitors.CreateLookAtMonitor(engine.Vector.New(-98, 54.25, -788))
    EnemyLookatMonitor:OnLookAt(SonExitDraugrIdle)
  end
end
function SonExitDraugrIdle()
  if EnemyLookatMonitor then
    EnemyLookatMonitor:Stop()
  end
  GameObjects.Cine_AxeIntro_Group.LuaObjectScript.SonExitDraugrFight()
  game.FindLevel("For500_ForestEntry"):CallScript("ShowTraverseLinkForBrokenForest")
  game.World.StoreCheckpoint({
    OverrideObject = GameObjects.ChkOvr_Draugr.Child
  })
end
function FirstFightStarted()
  TIMERS.StartLevelTimer(5, function()
    TUT.AxeMelee_Tutorial()
  end)
  GetInputMask():CallScript("Melee_Step_1")
end
function GetInputMask()
  if inputMask == nil then
    local lvl = game.FindLevel("For000_Sky")
    if lvl then
      inputMask = lvl:GetGameObject("InputMask")
    end
  end
  return inputMask
end
function SonOutOfFightSpace()
  if not fightComplete then
    GameObjects.IC_ArenaExit:ShowCollision()
  end
end
function FirstFightEnded()
  fightComplete = true
  GameObjects.CA_Idle_NoFight_AxeTut.LuaObjectScript.Disable()
end
function StartFirstFight()
  Area_1_Encounter_1:Start()
end
function setAxeIntroReady()
  axeIntroReady = true
end
