local LD = require("design.LevelDesignLibrary")
local LM = require("level.loadmonitor")
local thisLevel
local hero = game.Player.FindPlayer()
local sonSickActive = false
function OnScriptLoaded(level)
  SoundInit()
  thisLevel = level
  game.Audio.StartMusicMaster("SND_MX_CAL_start_master")
  game.Audio.StartMusicMaster("SND_MX_SonSick_master")
  game.Audio.StartMusicMaster("SND_MX_CAL_snake_belly_master")
end
function OnFirstStart(level)
  SetAmbience()
  GameObjects.SNDZnCalSonSickExit:HideSoundEmitterVolume()
end
function OnStart(level)
  LD.RegisterForCineUpdate(level, {
    {
      at = 365,
      immediateFn = ValidateRedStormState,
      fn = function()
        ValidateRedStormState()
        game.Audio.StopAmbiences()
      end
    }
  })
  LD.RegisterForVariableUpdate(level, "WaterDrop01Triggered", {
    immediateFn = SetAmbience,
    fn = SetAmbience
  })
  LD.RegisterForVariableUpdate(level, "WaterDrop02Triggered", {
    immediateFn = SetAmbience,
    fn = SetAmbience
  })
  LD.RegisterForVariableUpdate(level, "BridgePosition", {
    immediateFn = SwapAirlockZone,
    fn = SwapAirlockZone
  })
  ValidateRedStormState()
  SoundOnPreStart()
end
local waterLevel = {}
waterLevel.Bottom = 2
waterLevel.Medium = 1
waterLevel.Top = 0
local bottomWaterAmbience, mediumWaterAmbience, topWaterAmbience, RuneVaultZones
function SoundInit()
  bottomWaterAmbience = GameObjects.BottomWaterAmbience
  mediumWaterAmbience = GameObjects.MediumWaterAmbience
  topWaterAmbience = GameObjects.TopWaterAmbience
  RuneVaultZones = GameObjects.SNDGrpRuneVault
  HideRuneVaultZones()
  HideFinaleZones()
  HideXplInnerZones()
  HideSnakeMouthZone()
end
function SoundOnPreStart()
  local runeVaultMonitor = LM.CreateLoadMonitor()
  runeVaultMonitor:AddCallback({
    Wads = {
      "Cal500_RuneVault"
    },
    Functions = {
      ShowRuneVaultZones
    }
  })
  local cal400Monitor = LM.CreateLoadMonitor()
  cal400Monitor:AddCallback({
    Wads = {
      "Cal400_FinaleWorldTravel"
    },
    Functions = {
      ShowFinaleZones
    }
  })
  local cal410Monitor = LM.CreateLoadMonitor()
  cal410Monitor:AddCallback({
    Wads = {
      "Cal410_FinaleTowerFight"
    },
    Functions = {
      ShowFinaleZones
    }
  })
end
function SetAmbience()
  local newWaterLevel = LD.GetCurrentWaterLevel()
  if newWaterLevel == waterLevel.Bottom then
    topWaterAmbience:Hide()
    mediumWaterAmbience:Hide()
    bottomWaterAmbience:Show()
    game.Audio.SetWwiseSwitch(hero, "LVL_Caldera_Lake_Water_Level", "LVL_Caldera_Lake_Water_Level_02")
    print("sound water level 2")
  elseif newWaterLevel == waterLevel.Medium then
    topWaterAmbience:Hide()
    mediumWaterAmbience:Show()
    bottomWaterAmbience:Hide()
    game.Audio.SetWwiseSwitch(hero, "LVL_Caldera_Lake_Water_Level", "LVL_Caldera_Lake_Water_Level_01")
    print("sound water level 1")
  elseif newWaterLevel == waterLevel.Top then
    topWaterAmbience:Show()
    mediumWaterAmbience:Hide()
    bottomWaterAmbience:Hide()
    game.Audio.SetWwiseSwitch(hero, "LVL_Caldera_Lake_Water_Level", "LVL_Caldera_Lake_Water_Level_00")
    print("sound water level 0")
  end
end
function HideAllAmbience()
  topWaterAmbience:Hide()
  mediumWaterAmbience:Hide()
  bottomWaterAmbience:Hide()
end
function HideRuneVaultZones()
  print("Hiding RuneVault Zones")
  RuneVaultZones:Hide()
end
function ShowRuneVaultZones()
  print("Showing RuneVault Zones")
  RuneVaultZones:Show()
end
function ValidateRedStormState()
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  if 365 <= cineNumber and cineNumber < 390 then
    EnableRedStormState()
  else
    DisableRedStormState()
  end
end
function EnableRedStormState()
  game.Audio.SetWwiseState("Red_Storm", "Active")
end
function DisableRedStormState()
  game.Audio.SetWwiseState("Red_Storm", "Inactive")
end
function HideFinaleZones()
  ShowFinaleOverlappingZones()
  HideFinaleExteriorZones()
  HideFinaleInteriorZones()
end
function ShowFinaleZones()
  HideFinaleOverlappingZones()
  ShowFinaleExteriorZones()
  ShowFinaleInteriorZones()
end
function HideFinaleOverlappingZones()
  GameObjects.SNDCalOverall:Hide()
end
function ShowFinaleOverlappingZones()
  GameObjects.SNDCalOverall:Show()
end
function HideFinaleExteriorZones()
  GameObjects.SNDGrpFinale_Exterior:Hide()
end
function ShowFinaleExteriorZones()
  GameObjects.SNDGrpFinale_Exterior:Show()
end
function HideFinaleInteriorZones()
  GameObjects.SNDGrpFinale_Interior:Hide()
end
function ShowFinaleInteriorZones()
  GameObjects.SNDGrpFinale_Interior:Show()
end
local acceptedRealms = {
  "Jotunheim",
  "Alfheim",
  "Helheim",
  "Svartalfheim",
  "Asgard",
  "Niflheim",
  "Muspelheim",
  "Vanaheim"
}
function SwapAirlockZone()
  HideAllAirlockZones()
  local targetRealm = LD.GetBridgePosition()
  if targetRealm == "Midgard" then
    targetRealm = "Vanaheim"
  end
  local targetZone = thisLevel:FindGameObject("SNDZnCal120_" .. targetRealm)
  if targetZone ~= nil then
    targetZone:Show()
  else
    print("[Cal050_Sound.lua -> HideAllAirlockZones()] WARNING: Couldn't find target sound zone game object! Name of GO searched for -> " .. "SNDZnCal120_" .. targetRealm)
  end
end
function HideAllAirlockZones()
  local airlockZones = thisLevel:FindGameObjects("SNDZnCal120_*")
  if #airlockZones == 0 or airlockZones == nil then
    print("[Cal050_Sound.lua -> HideAllAirlockZones()] WARNING: Table of airlock sound zones is 0 or nil!")
  elseif #airlockZones < #acceptedRealms then
    print("[Cal050_Sound.lua -> HideAllAirlockZones()] WARNING: Table of airlock sound zones is less than number of realms! Are you missing/misnaming zones?")
  elseif #airlockZones > #acceptedRealms then
    print("[Cal050_Sound.lua -> HideAllAirlockZones()] WARNING: Table of airlock sound zones is more than number of realms! Look for extraneous sound zones.")
  else
    print("Hiding all airlock sound zones.")
    for i = 1, #airlockZones do
      airlockZones[i]:Hide()
    end
  end
end
function HideDoor2Zones()
  GameObjects.SNDZone500_Hall_5a1:HideSoundEmitterVolume()
  GameObjects.SNDZone500_Hall_5a2:HideSoundEmitterVolume()
end
function HideDoor3Zones()
  GameObjects.SNDZone500_Hall_4_Lower1:HideSoundEmitterVolume()
  GameObjects.SNDZone500_Hall_4_Lower2:HideSoundEmitterVolume()
end
function ShowXplInnerZones()
  GameObjects.SNDZnXpl900In_1:ShowSoundEmitterVolume()
  GameObjects.SNDZnXpl900In_2:ShowSoundEmitterVolume()
  GameObjects.SNDZnXpl960Cave:ShowSoundEmitterVolume()
  GameObjects.SNDGrpXpl650Zones:Show()
end
function HideXplInnerZones()
  GameObjects.SNDZnXpl900In_1:HideSoundEmitterVolume()
  GameObjects.SNDZnXpl900In_2:HideSoundEmitterVolume()
  GameObjects.SNDZnXpl960Cave:HideSoundEmitterVolume()
  GameObjects.SNDGrpXpl650Zones:Hide()
end
function ShowSnakeMouthZone()
  GameObjects.SNDGrpZnCal800:Show()
end
function HideSnakeMouthZone()
  GameObjects.SNDGrpZnCal800:Hide()
end
function ShowCalLakeZones()
  GameObjects.SNDCalOverall:Show()
  GameObjects.SNDZnCalOverall_Inner:Show()
  SetAmbience()
end
function HideCalLakeZones()
  GameObjects.SNDCalOverall:Hide()
  GameObjects.SNDZnCalOverall_Inner:Hide()
  HideAllAmbience()
end
function SonSickActive()
  sonSickActive = true
  GameObjects.SNDZnCalSonSickExit:ShowSoundEmitterVolume()
end
function SonSickExit()
  if sonSickActive then
    sonSickActive = false
    GameObjects.SNDZnCalSonSickExit:HideSoundEmitterVolume()
  end
end
function OnSaveCheckpoint(level)
  return {sonSickActive = sonSickActive}
end
function OnRestoreCheckpoint(level, savedInfo)
  sonSickActive = savedInfo.sonSickActive or false
end
