local LD = require("design.LevelDesignLibrary")
local EC = require("design.Encounter")
local monitors = require("level.MonitorLibrary")
local checkpoint = require("level.checkpoint")
local timer = require("level.timer")
local timers = require("level.timer")
local uiCalls = require("ui.uicalls")
local delayTimers = require("level.timer")
local Player, thisLevel, LightOn_01, LightOn_02, LightOn_03, Area_1_Encounter_1, AlfDgn210_DespawnMonitor, Area_2_Encounter_1, Area_3_Encounter_1, Area_3_Encounter_2, Area_4_Encounter_1
local PirateTendrilsDissipated = 0
local Rift_Challenge_Duration = 10
local Challenge_Started = false
local ecTimer, ec_TimeRequirement, hudTimeRemaining
local delayDestruction = false
local delayDestruction_T = {}
function OnScriptLoaded(level)
  Player = game.Player.FindPlayer()
  thisLevel = level
  Area_1_Fight_1()
  Area_2_Fight_1()
  Area_3_Fight_1()
  Area_3_Fight_2_Repop()
  if game.GetNewGamePlus() then
    New_Game_Plus_Area_4_Fight_1()
  else
    Area_4_Fight_1()
  end
end
function OnStart(level)
  if LD.GetEntityVariable("ALF_PocketRiftOn") == false then
    GameObjects.LootPocketRift210.LuaObjectScript.Disable()
  end
  if Area_1_Encounter_1:WasRunning() then
    Area_1_Encounter_1:Start()
  end
  if Area_2_Encounter_1:WasRunning() then
    Area_2_Encounter_1:Start()
  end
  if Area_3_Encounter_1:WasRunning() then
    Area_3_Encounter_1:Start()
  end
end
function OnUpdate(level)
  UpdateCreatureDestruction()
  if Challenge_Started then
    Encounter_Timer()
  end
end
function OnFirstStart(level)
  GameObjects.TraverseGapJump:HideTraverseLink()
  LightOn_01 = false
  LightOn_02 = false
  LightOn_03 = false
end
function PirateTendrilBreak()
  GameObjects.chest_common_tier1_alfdgn210_1.LuaObjectScript.Enable()
  GameObjects.PirateCoveLootDrop:PlayAnimToEnd()
  timer.StartLevelTimer(0.5, function()
    GameObjects.TraverseGapJump:ShowTraverseLink()
  end)
  if game.Level.GetVariable("CompletedCineNumber") ~= 245 then
    timer.StartLevelTimer(1.25, function()
      GameObjects.Reaction_PirateTendril.LuaObjectScript.Trigger()
    end)
  end
  for _, x in pairs(GameObjects.PirateCoveHive.Children) do
    x.Child.LuaObjectScript.StartDecay()
  end
end
function TendrilPirate_01()
  GameObjects.TraverseGapJump:ShowTraverseLink()
end
function TendrilPirate_01_regrow()
  GameObjects.TraverseGapJump:HideTraverseLink()
end
function TendrilPirate_02()
  LD.SetEntityVariable("TendrilPirate_02", true)
end
function TendrilPirate_02_OFF()
  LD.SetEntityVariable("TendrilPirate_02", false)
end
function RuneSymbol_1()
  LightOn_01 = true
  CheckLights()
end
function RuneSymbol_2()
  LightOn_02 = true
  CheckLights()
end
function RuneSymbol_3()
  LightOn_03 = true
  CheckLights()
end
function CheckLights()
  if LightOn_01 and LightOn_02 and LightOn_03 and not Area_4_Encounter_1:IsComplete() then
    GetPartyStarted()
    LD.SetEntityVariable("ALF_PocketRiftOn", true)
    LD.SetMarkerState("ALF_300_RightBeachFight", 1)
  else
    LD.SetMarkerState("ALF_300_RightBeachFight", 0)
  end
end
function GetPartyStarted()
  GameObjects.LootPocketRift210.LuaObjectScript.Enable()
  GameObjects.RespawnRift210Zone:ShowEntityVolume()
end
function StartFightRift210()
  timer.StartLevelTimer(3, function()
    Area_4_Encounter_1:Start()
  end)
  timer.StartLevelTimer(3, function()
    GameObjects.Reaction_Threat_High.LuaObjectScript.Trigger()
  end)
  timer.StartLevelTimer(8, function()
    GameObjects.LootPocketRift210.LuaObjectScript.SpawningDone()
  end)
end
function StopFightRift210()
  GameObjects.LootPocketRift210.LuaObjectScript.StopCombatState()
end
function RespawnRift210()
  if Area_4_Encounter_1 ~= nil and not Area_4_Encounter_1:IsComplete() and not Area_4_Encounter_1:IsRunning() then
    GameObjects.LootPocketRift210.LuaObjectScript.ResetCombatState()
  end
end
function PlaySoundEnemySpawnFightRift210()
  GameObjects.LootPocketRift210.LuaObjectScript.PlaySoundCombatPortalEnemySpawn()
end
function Area_1_Fight_1()
  local powerLevel01, powerLevel02
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  if 375 <= cineNumber and cineNumber <= 599 then
    powerLevel01 = 3
    powerLevel02 = 4
  elseif 600 <= cineNumber then
    powerLevel01 = 4
    powerLevel02 = 5
  end
  Area_1_Encounter_1 = EC.NewEncounter(thisLevel, "[Area 1]EC:1 Beach Crawlers Alf210", {
    CheckpointOnComplete = true,
    LeashZone = "LeashZoneDgn211",
    StartMusic = "SND_MX_ALF_secret_beach_explore_in",
    StopMusic = "SND_MX_ALF_secret_beach_explore_out"
  })
  Area_1_Encounter_1:AddWave({
    {
      spawners = "Crawler_N_SFG",
      spawnLocators = "A1_O_Loc_1",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0,
      powerLevel = powerLevel01
    },
    {
      spawners = "Crawler_N_SFG",
      spawnLocators = "A1_O_Loc_2",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.5,
      powerLevel = powerLevel02
    }
  })
  Area_1_Encounter_1:SetStartZone(GameObjects.EntZn_Area_1_Attack)
  Area_1_Encounter_1:OnComplete(function()
    GameObjects.IdleContext_OnAlert.LuaObjectScript.Disable()
  end)
  AlfDgn210_DespawnMonitor = monitors.CreateEntityZoneMonitor(Player, thisLevel:GetGameObject("EntZn_Area_DespawnAll"))
  AlfDgn210_DespawnMonitor:OnEnter(function()
  end)
end
function Area_2_Fight_1()
  local powerLevel01
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  if 375 <= cineNumber and cineNumber <= 599 then
    powerLevel01 = 3
  elseif 600 <= cineNumber then
    powerLevel01 = 4
  end
  Area_2_Encounter_1 = EC.NewEncounter(thisLevel, "[Area 2]EC:1 Flyer Patrol Alf210", {
    CheckpointOnComplete = false,
    LeashZone = "LeashZoneDgn210"
  })
  Area_2_Encounter_1:AddWave({
    {
      spawners = "Flyer_Patrol*",
      spawnLocators = "A2_O_Loc_3",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0,
      powerLevel = powerLevel01
    },
    {
      spawners = "Flyer_Idle",
      spawnLocators = "A2_O_Loc_7",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0,
      powerLevel = powerLevel01
    }
  })
  Area_2_Encounter_1:SetStartZone(GameObjects.EntZn_Area_2_Attack)
  Area_2_Encounter_1:OnComplete(function()
    GameObjects.IdleContext_OnAlert.LuaObjectScript.Disable()
    LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_Nightmare_Blind")
  end)
  AlfDgn210_DespawnMonitor = monitors.CreateEntityZoneMonitor(Player, thisLevel:GetGameObject("EntZn_Area_DespawnAll"))
  AlfDgn210_DespawnMonitor:OnEnter(function()
  end)
end
function Area_3_Fight_1()
  local powerLevel01
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  if 375 <= cineNumber and cineNumber <= 599 then
    powerLevel01 = 3
  elseif 600 <= cineNumber then
    powerLevel01 = 4
  end
  Area_3_Encounter_1 = EC.NewEncounter(thisLevel, "[Area 3]EC:1 Draugr Patrol Alf210", {
    CheckpointOnComplete = false,
    LeashZone = "LeashZoneDgn210"
  })
  Area_3_Encounter_1:AddWave({
    {
      spawners = "H_Draugr_2_PATROL",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0,
      powerLevel = powerLevel01
    }
  })
  Area_3_Encounter_1:SetStartZone(GameObjects.EntZn_Area_3_Attack)
  Area_3_Encounter_1:OnComplete(function()
    GameObjects.IdleContext_OnAlert.LuaObjectScript.Disable()
  end)
end
function Area_3_Fight_2_Repop()
  Area_3_Encounter_2 = EC.NewEncounter(thisLevel, "[Area 3]EC:1 Draugr Patrol Alf210 Repop", {
    CheckpointOnComplete = false,
    LeashZone = "LeashZoneDgn210",
    RepopulationEncounter = true,
    MustHaveCompletedList = {
      "[Area 3]EC:1 Draugr Patrol Alf210"
    }
  })
  Area_3_Encounter_2:AddWave({
    {
      spawners = "H_Draugr_6_PATROL",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "Draugr_L_6_UNAWARE",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0.2
    }
  })
  Area_3_Encounter_2:SetStartZone(GameObjects.EntZn_Area_3_Attack, {
    cineRequirement = {375, 900}
  })
end
function Area_4_Fight_1()
  Area_4_Encounter_1 = EC.NewEncounter(thisLevel, "[Area 3]EC:1 Dual Wield Draugr Rift Alf210", {
    CheckpointOnComplete = true,
    LeashZone = "LeashZoneDgn210"
  })
  Area_4_Encounter_1:AddWave({
    {
      spawners = "DW_Draugr_L3_RIFT",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "DW_Draugr_L3_RIFT",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 3
    }
  })
  Area_4_Encounter_1:OnComplete(StopFightRift210)
  Area_4_Encounter_1:OnComplete(function()
    LD.SetMarkerState("ALF_300_RightBeachFight", 0)
  end)
  Area_4_Encounter_1:OnEnemySpawn(PlaySoundEnemySpawnFightRift210)
end
function New_Game_Plus_Area_4_Fight_1()
  Area_4_Encounter_1 = EC.NewEncounter(thisLevel, "[Area 3]EC:1 NPlus Dual Wield Draugr Rift Alf210", {
    CheckpointOnComplete = true,
    LeashZone = "LeashZoneDgn210"
  })
  Area_4_Encounter_1:AddWave({
    {
      spawners = "DW_Draugr_L3_RIFT",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    },
    {
      spawners = "DW_Draugr_L3_RIFT",
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 3
    }
  })
  Area_4_Encounter_1:OnStart(function()
    Set_Encounter_Timer(60, Area_4_Encounter_1)
    Start_Timer()
  end)
  Area_4_Encounter_1:OnComplete(StopFightRift210)
  Area_4_Encounter_1:OnComplete(function()
    LD.SetMarkerState("ALF_300_RightBeachFight", 0)
    Event_Complete()
  end)
  Area_4_Encounter_1:OnEnemySpawn(PlaySoundEnemySpawnFightRift210)
end
function EnableChiselMarker()
  LD.SetMarkerState("ALF_210_ChiselEntrance", 1)
  LD.UpdateMap("ALF_210_ChiselEntrance", 2)
  ChiselQuest()
end
function DisableChiselMarker()
  LD.SetMarkerState("ALF_210_ChiselEntrance", 0)
end
function ChiselQuest()
  local questState = game.QuestManager.GetQuestState("Quest_Labor_ChiselDungeon_Find_Alf")
  if questState ~= "Complete" then
    LD.ActivateQuest("Quest_Labor_ChiselDungeons_Parent")
    LD.CompleteQuest("Quest_Labor_ChiselDungeon_Find_Alf")
    game.QuestManager.IncrementQuestProgress("Quest_Labor_ChiselDungeon_Find", 1)
  end
end
function idleMusic()
  game.Audio.StartMusic("SND_MX_TRANS_TO_IDLE")
end
function restoreMusic()
  local alf050 = game.FindLevel("Alf050_Sound")
  if alf050 ~= nil and game.Level.GetVariable("CompletedCineNumber") >= 610 then
    alf050:CallScript("revisitMusic")
  end
end
function OnSaveCheckpoint(level)
  return {
    levelstate = checkpoint.Save()
  }
end
function OnRestoreCheckpoint(level, savedInfo)
  checkpoint.Restore(savedInfo.levelstate)
end
function Set_Encounter_Timer(timeRequirement, encounter)
  ec_TimeRequirement = timeRequirement
  ecTimer = StartLevelTimer(timeRequirement, function()
    EventFailed_TimeElapsed(encounter)
  end)
  ecTimer:Stop()
end
function Start_Timer()
  local startDelay = 1
  Challenge_Started = true
  LD.CallFunctionAfterDelay(function()
    ecTimer:Start()
  end, startDelay)
  hudTimeRemaining = math.floor(ec_TimeRequirement - ecTimer.time)
  local seconds = ec_TimeRequirement % 60
  local minutes = (hudTimeRemaining - seconds) / 60
  local Time_Text = string.format("%02d : %02d", minutes, seconds)
end
function Encounter_Timer()
  hudTimeRemaining = math.floor(ec_TimeRequirement - ecTimer.time)
  local seconds = hudTimeRemaining % 60
  local minutes = (hudTimeRemaining - seconds) / 60
  local Time_Text = string.format("%02d : %02d", minutes, seconds)
  uiCalls.EnableMechanicText(37906, {minutes, seconds})
end
function Event_Complete()
  uiCalls.DisableMechanicText()
  ecTimer:Stop()
  ecTimer:Reset()
  Challenge_Started = false
end
function EventFailed_TimeElapsed(encounter)
  local seconds = Rift_Challenge_Duration % 60
  local minutes = Rift_Challenge_Duration / 60
  local Time_Text = string.format("%02d : %02d", minutes, seconds)
  uiCalls.DisableMechanicText()
  Despawn_Enemy_VFX(encounter)
  encounter:Reset()
  encounter:Stop()
  ResetRift_Callback(encounter)
  ecTimer:Stop()
  ecTimer:Reset()
  Challenge_Started = false
end
function Despawn_Enemy_VFX(encounter)
  local minTime = 0.01
  local maxTime = 0.3
  local randomFn = function()
    return math.random(minTime * 1000, maxTime * 1000) / 1000
  end
  local enemies = encounter:GetActiveEnemies()
  for _, enemy in pairs(enemies) do
    if enemy ~= nil and enemy:IsDoingSyncMove() == false then
      timers.StartLevelTimer(randomFn(), function()
        if enemy ~= nil then
          SpawnFXAtCreatureLocation(enemy)
          enemy:Destroy()
        end
      end)
      CreatureInSyncMove_DelayDestruction(enemy)
    end
  end
  encounter:ResetLivingEnemiesCount()
  encounter:ReportWaveDespawned(nil)
end
function SpawnFXAtCreatureLocation(creature)
  local fx = game.FX.Spawn("Body_Fire_Explode", nil, {
    AutoDelete = true,
    EffectCreator = creature,
    Scale = 1.5
  })
  local lastEnemyPos = creature:GetWorldJointPosition(creature:GetJointIndex("JOPelvis1"))
  fx:SetWorldPosition(lastEnemyPos)
end
function CreatureInSyncMove_DelayDestruction(creature)
  delayDestruction = true
  delayDestruction_T[creature] = true
end
function UpdateCreatureDestruction()
  if delayDestruction == true then
    local remaining = 0
    for creature, _ in pairs(delayDestruction_T) do
      if creature ~= nil and delayDestruction_T[creature] == true then
        if creature:IsDoingSyncMove() == false then
          SpawnFXAtCreatureLocation(creature)
          creature:Destroy()
          delayDestruction_T[creature] = nil
        else
          remaining = remaining + 1
        end
      end
    end
    if remaining == 0 then
      delayDestruction = false
      delayDestruction_T = {}
    end
  end
end
function ResetRift_Callback(encounter)
  GameObjects.LootPocketRift210.LuaObjectScript.ResetCombatState()
end
