local timer = require("level.timer")
local LD = require("design.LevelDesignLibrary")
local EC = require("design.Encounter")
local CCOS = require("camera.camera_oneshot")
local checkpoint = require("level.checkpoint")
local uiCalls = require("ui.uicalls")
local thisLevel, thisObj, player, foundParts, otherParts, fxObject, Witch_Quest_Encounter_1, Witch_Quest_Encounter_2, frontInteractZone, onCollectedEvent, interactionOnStart, interactionOnFinish, enabled, spawnedSkull, questGiver, camOneShot_WitchRevival, camOneShot_TransitionCamera
function OnScriptLoaded(level, obj)
  thisLevel = level
  thisObj = obj
  player = game.Player.FindPlayer()
  frontInteractZone = LD.CreateInteractZone_Standard_90(thisObj, "promptJointFront")
  onCollectedEvent = thisObj:FindLuaTableAttribute("onCollectedEvent")
  interactionOnStart = thisObj:FindLuaTableAttribute("interactionOnStart")
  interactionOnFinish = thisObj:FindLuaTableAttribute("interactionOnFinish")
  foundParts = thisObj:FindSingleGOByName("FoundParts")
  otherParts = thisObj:FindSingleGOByName("BodyParts")
  fxObject = thisObj:FindSingleGOByName("WitchSpawnFX")
  if onCollectedEvent ~= nil then
    onCollectedEvent = LD.ExtractCallbacksForEvent(thisLevel, thisObj, onCollectedEvent)
  end
  if interactionOnStart ~= nil then
    interactionOnStart = LD.ExtractCallbacksForEvent(thisLevel, thisObj, interactionOnStart)
  end
  if interactionOnFinish ~= nil then
    interactionOnFinish = LD.ExtractCallbacksForEvent(thisLevel, thisObj, interactionOnFinish)
  end
  BodyPartCheck()
  Witch_Quest_Fight_2()
  game.SubObject.Sleep(thisObj)
end
function OnStart(level, obj)
  BodyPartCheck()
  QuestCheck()
  PauseAnim()
  if Witch_Quest_Encounter_2:WasRunning() then
    Witch_Quest_Encounter_2:Start()
  end
end
function PauseAnim(level, obj)
  if fxObject ~= nil then
    fxObject:Hide()
    fxObject:PauseAnim()
  end
  for _, childObj in pairs(foundParts.Descendants) do
    childObj:JumpAnimToFrame(0)
    childObj:PauseAnim()
  end
  for _, childObj in pairs(otherParts.Descendants) do
    childObj:JumpAnimToFrame(0)
    childObj:PauseAnim()
  end
end
function DestroyOneShot_WitchRevival_Forming()
  camOneShot_WitchRevival = nil
  game.SubObject.Sleep(thisObj)
end
function CameraLookAt_WitchRevival_Forming()
  game.SubObject.Wake(thisObj)
  camOneShot_WitchRevival = CCOS.OneShotCamera.New("PLYR_NAR_WitchRevival_Formed", 10.5)
  camOneShot_WitchRevival:SetCallback(DestroyOneShot_WitchRevival_Forming)
  camOneShot_WitchRevival:Start()
end
function DestroyTransitionCamera_QuestCamera()
  camOneShot_TransitionCamera = nil
end
function PlayTransitionCamera(cameraname, length, cinelocklength)
  game.SubObject.Wake(thisObj)
  camOneShot_TransitionCamera = CCOS.OneShotCamera.New(cameraname, length)
  camOneShot_TransitionCamera:SetCallback(DestroyTransitionCamera_QuestCamera)
  camOneShot_TransitionCamera:Start()
end
function ActivateSlowZone()
  local cal270 = game.FindLevel("Cal270_StoneMasonLH")
  local goSpeedZone = cal270:GetGameObject("QuestSpeedZone_WitchAppearance")
  goSpeedZone:Show()
end
function DeactivateSlowZone()
  local cal270 = game.FindLevel("Cal270_StoneMasonLH")
  local goSpeedZone = cal270:GetGameObject("QuestSpeedZone_WitchAppearance")
  goSpeedZone:Hide()
end
function OnUpdate(level, obj)
  if camOneShot_WitchRevival ~= nil then
    camOneShot_WitchRevival:Update()
  end
  if camOneShot_TransitionCamera ~= nil then
    camOneShot_TransitionCamera:Update()
  end
end
function OnUseWorld(level, obj)
  if frontInteractZone:PlayerCanInteract() then
    local spawnArgs = {
      SpawnObject = "goSpawnedSkull",
      HookName = "SkullSpawned"
    }
    thisObj:SpawnGameObject(spawnArgs)
  end
end
function OnInteractStart()
  if interactionOnStart ~= nil then
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, interactionOnStart, "InteractionEventStart")
  end
  LD.PlaySingleSynchMove_KratosObject(thisObj, "synchJoint1", "Maiden Complete Interaction", "BRA_PutDownGenericLongEnter", "", frontInteractZone, true, "Bare")
  CompleteObjective()
  timer.StartLevelTimer(2.8, function()
    PlayTransitionCamera("PLYR_NAR_QuestCamera", 6.9)
  end)
  if onCollectedEvent ~= nil then
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, onCollectedEvent, "onCollectedEvent")
  end
end
function OnInteractAbort()
end
function OnInteractFinish(level, go)
  if interactionOnFinish ~= nil then
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, interactionOnFinish, "Interaction Event Finish")
  end
  questGiver = GameObjects.GhostInteract02
  if questGiver ~= nil then
    questGiver.LuaObjectScript.FireMaidenQuestComplete()
  end
  Disable()
end
function OnInteractDone()
end
function SkullSpawned(level, obj, spawnedObject)
  spawnedSkull = spawnedObject
  spawnedSkull:Hide()
  player:RequestInteract(obj, {InteractZone = frontInteractZone, LerpObject = spawnedSkull})
end
function BodyPartCheck(level, obj)
  local questState = game.QuestManager.GetQuestState("Quest_UnfinishedBusiness02_Objective_02")
  if questState == "Complete" then
    foundParts:Show()
  else
    foundParts:Hide()
  end
end
function CompleteObjective(level, obj)
  local questState = game.QuestManager.GetQuestState("Quest_UnfinishedBusiness02_Objective_02")
  if questState == "Active" then
    game.QuestManager.ProposeQuestState("Quest_UnfinishedBusiness02_Objective_02", "Complete")
    Disable()
  end
end
function QuestCheck(level, obj)
  local questStateDeliver = game.QuestManager.GetQuestState("Quest_UnfinishedBusiness02_Objective_02")
  if questStateDeliver == "Active" then
    Enable()
  else
    Disable()
  end
end
function StartGullveigSequence(level, obj)
  print("quest event!")
  game.Audio.PlayBanter("FallenWarrior_Global_Complete02_Fight", CompleteReturnObjective)
  ActivateSlowZone()
  timer.StartLevelTimer(12.5, DeactivateSlowZone)
  AnimateSkeleton()
  PlayTransitionCamera("PLYR_NAR_WitchRevival", 7)
  _G.StartLevelTimer(2.69, CameraLookAt_WitchRevival_Forming)
end
function CompleteReturnObjective()
  LD.CompleteQuest("Quest_UnfinishedBusiness02_Return")
  questGiver = GameObjects.GhostInteract02
  if questGiver ~= nil then
    questGiver.LuaObjectScript.ResetGullveig()
  end
  game.World.StoreCheckpoint()
end
function AnimateSkeleton(level, obj)
  for _, childObj in pairs(foundParts.Children) do
    childObj:PlayAnimToEnd()
    childObj:SetAnimRate(0.4)
  end
  for _, childObj in pairs(otherParts.Children) do
    childObj:PlayAnimToEnd()
    childObj:SetAnimRate(0.4)
  end
  _G.StartLevelTimer(8, PlaySpawnFX)
  PlaySoundOnSkeletonReanimate()
  game.Audio.StartMusic("SND_MX_CAL270_return_bones")
end
function PlaySpawnFX()
  fxObject:Show()
  fxObject:PlayAnimToEnd()
  _G.StartLevelTimer(4.5, HideSkeleton)
end
function HideSkeleton(level, obj)
  foundParts:Hide()
  otherParts:Hide()
  SpawnWitch()
end
function HideFX()
  fxObject:HideParticleEmitter()
end
function Witch_Quest_Fight_2()
  local powerLevel
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  if 375 <= cineNumber then
    powerLevel = 5
  end
  Witch_Quest_Encounter_2 = EC.NewEncounter(thisLevel, "[Area 1]EC:1 Unfinished Business 02 Witch Spawn Water Lvl 2", {
    CheckpointOnComplete = true,
    LeashZone = "LeashZoneCal270",
    StartMusic = "SND_MX_CAL270_witch_fight_in",
    StopMusic = "SND_MX_CAL270_witch_fight_out"
  })
  Witch_Quest_Encounter_2:AddWave({
    powerLevel = powerLevel,
    requireCompletionOfAllPriorWaves = true,
    {
      spawners = "WitchSpawner",
      spawnWad = "Cal270_StoneMasonLH_AI_02",
      markerID = "GulvMarker",
      spawnCooldown = 0
    },
    {
      spawners = "FlyerGulv01",
      spawnWad = "Cal270_StoneMasonLH_AI_02",
      maxActive = 2,
      totalSpawns = 2,
      spawnCooldown = 4
    }
  })
  Witch_Quest_Encounter_2:SetStartZone(GameObjects.EntZn_Arena_RestartFight270)
  Witch_Quest_Encounter_2:OnComplete(UnlockBestiaryEntry)
  Witch_Quest_Encounter_2:OnEnemyDeath(function()
    timer.StartLevelTimer(1.5, function()
      Gulv_Despawn_Enemy_VFX()
      Witch_Quest_Encounter_2:DespawnEnemies()
      Witch_Quest_Encounter_2:SetComplete()
    end)
  end, {markerID = "GulvMarker"})
end
function Gulv_Despawn_Enemy_VFX()
  local minTime = 0
  local maxTime = 0.2
  local randomFn = function()
    return math.random(minTime * 1000, maxTime * 1000) / 1000
  end
  local enemies1 = Witch_Quest_Encounter_2:GetActiveEnemies()
  for _, enemy in pairs(enemies1) do
    if enemy ~= nil then
      local enemyLastPos = enemy:GetWorldJointPosition(enemy:GetJointIndex("JOPelvis1"))
      timer.StartLevelTimer(randomFn(), function()
        local enemyVFX = game.FX.Spawn("BloodExplode", nil, {
          AutoDelete = true,
          EffectCreator = enemy,
          Scale = 1.5
        })
        enemyVFX:SetWorldPosition(enemyLastPos)
      end)
    end
  end
end
function CompleteQuest()
  game.QuestManager.ProposeQuestState("Quest_UnfinishedBusiness02_Fight", "Complete")
  Disable()
  game.Audio.PlayBanter("FallenWarrior_Global_Complete02_PostFight", CheckForTyrArmorQuest)
  TrophyCheck()
  game.World.StoreCheckpoint()
end
function TrophyCheck()
  if game.QuestManager.GetQuestState("Quest_UnfinishedBusiness02_Parent") == "Complete" and game.QuestManager.GetQuestState("Quest_UnfinishedBusiness03_Parent") == "Complete" and game.QuestManager.GetQuestState("Quest_UnfinishedBusiness04_Parent") == "Complete" and game.QuestManager.GetQuestState("Quest_UnfinishedBusiness05_Parent") == "Complete" and game.QuestManager.GetQuestState("Quest_SecretBusiness02_Parent") == "Complete" then
    AwardTrophy()
  end
end
function AwardTrophy()
  print("Trophy Awarded: Unfinished Business")
  game.UnlockTrophy(31)
end
function CheckForTyrArmorQuest()
  LD.ActivateQuest("Quest_TyrArmor_Parent")
  game.SubObject.SoftSave(thisObj)
end
function UnlockBestiaryEntry()
  LD.UnlockBestiaryEntry_EndOfEncounter("Bestiary_Unlock_Gullveig")
end
function SpawnWitch()
  thisObj:HideCollision()
  local waterLevel = LD.GetCurrentWaterLevel()
  if waterLevel == 2 then
    Witch_Quest_Encounter_2:Start()
    GameObjects.EntZn_Arena_RestartFight270:ShowEntityVolume()
  end
end
function Enable()
  enabled = true
  frontInteractZone:Enable()
end
function Disable()
  enabled = false
  frontInteractZone:Disable()
end
function PlaySoundOnSkeletonReanimate()
  LD.PlaySound(thisObj:FindSingleSoundEmitterByName("SNDWitchSkeleton"), "SND_CHR_Quest_Giver_Witch_Spawn")
end
function OnSaveCheckpoint(level)
  print("Pickup - OnSaveCheckpoint")
  return {
    enabled = enabled,
    levelstate = checkpoint.Save()
  }
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  print("Pickup - OnRestoreCheckpoint")
  enabled = savedInfo.enabled
  checkpoint.Restore(savedInfo.levelstate)
end
function LuaHook_HideSkull()
  spawnedSkull:Hide()
end
function LuaHook_ShowSkull()
  spawnedSkull:Show()
end
function LuaHook_DestroySkull()
  spawnedSkull:Destroy()
end
function LuaHook_ShowFoundParts()
  foundParts:Show()
end
