local LWSoundManager = BaseClass("LWSoundManager")
local Sound = CS.GameEntry.Sound
local LWSoundTimer = require("DataCenter.LWSound.LWSoundTimer")
local Localization = CS.GameEntry.Localization

function LWSoundManager:__init()
  self.busy = {}
  for i = 1, SoundLimitType.MAX do
    self.busy[i] = {}
  end
  self.limit = {
    [SoundLimitType.UnitDeath] = 2,
    [SoundLimitType.BulletHit] = 1,
    [SoundLimitType.BulletCreate] = 1,
    [SoundLimitType.TroopAttackCity] = 1,
    [SoundLimitType.TroopMarching] = 1,
    [SoundLimitType.BossWarning] = 1
  }
  self.limitByName = {
    [SoundByNameLimitType.SkillFire] = {num = 1, time = 0.5}
  }
  self.busyByName = {}
  self.busyById = nil
  self.busySoundIdToMetaId = {}
  self:AddUpdateTimer()
  self.isEffectOn = CS.GameEntry.Setting:GetBool(SettingKeys.EFFECT_MUSIC_ON, true)
  self.effectExtraGroup = {}
  self.loopTimerList = {}
  self.loopTimerIdList = {}
  self.envSoundGroupIndexList = {}
end

function LWSoundManager:OnEnterGame()
  self:CheckAudioMixerUsable()
end

function LWSoundManager:CheckAudioMixerUsable()
  local usable = self:IsAudioMixerUsable()
  Logger.LogInfo("[AudioMixer]AudioMixer Option: " .. tostring(usable))
  self.useAudioMixer = false
  CS.GameEntry.Sound:SyncAudioMixerUsing(usable)
end

function LWSoundManager:__delete()
  self:RemoveUpdateTimer()
  self.busy = {}
  self.limit = {}
  self.loopTimerList = {}
  self.loopTimerIdList = {}
  self.limitByName = {}
  self.busyByName = {}
  self.abTest = nil
  self.useAudioMixer = nil
  self.envSoundGroupIndexList = nil
end

function LWSoundManager:AddUpdateTimer()
  if self.updateTimer == nil then
    function self.updateTimer()
      self:OnUpdate()
    end
    
    UpdateManager:GetInstance():AddUpdate(self.updateTimer)
  end
end

function LWSoundManager:RemoveUpdateTimer()
  if self.updateTimer then
    UpdateManager:GetInstance():RemoveUpdate(self.updateTimer)
    self.updateTimer = nil
  end
end

function LWSoundManager:OnUpdate()
  local deltaTime = Time.deltaTime
  for i = 1, SoundLimitType.MAX do
    for j = 1, self.limit[i] do
      if self.busy[i][j] then
        self.busy[i][j] = self.busy[i][j] - deltaTime
        if self.busy[i][j] < 0 then
          self.busy[i][j] = nil
        end
      end
    end
  end
  for key, value in pairs(self.busyByName) do
    for i = #value, 1, -1 do
      value[i] = value[i] - deltaTime
      if value[i] <= 0 then
        table.remove(value, i)
      end
    end
  end
  if self.busyById then
    local busyCount = 0
    for id, value in pairs(self.busyById) do
      local count = 0
      for soundId, time in pairs(value) do
        local newValue = time - deltaTime
        if newValue < 0 then
          value[soundId] = nil
          self.busySoundIdToMetaId[soundId] = nil
        else
          value[soundId] = newValue
          count = count + 1
        end
      end
      if count == 0 then
        self.busyById[id] = nil
      else
        busyCount = busyCount + 1
      end
    end
    if busyCount == 0 then
      self.busyById = nil
    end
  end
end

function LWSoundManager:GetSound(id)
  local meta = DataCenter.LWSoundTemplateManager:GetTemplate(id)
  if not meta then
    return nil
  end
  local assetName
  if self.useAudioMixer then
    assetName = meta.sound:GetRandom()
    if not assetName then
      assetName = meta.audioSource:GetRandom()
      if not assetName then
        Logger.LogError(string.format("lw_sound\232\161\168%s\232\161\140audiosource\228\184\186\231\169\186", id))
        return nil
      end
    end
  else
    assetName = meta.sound:GetRandom()
    if not assetName then
      assetName = meta.soundPath2:GetRandom()
      if not assetName then
        Logger.LogError(string.format("lw_sound\232\161\168%s\232\161\140sound\229\136\151\229\146\140sound2\229\136\151\233\131\189\228\184\186\231\169\186", id))
        return nil
      end
    end
  end
  return assetName
end

function LWSoundManager:StopSound(id, ignorePlayBgm)
  if id and 0 < id then
    Sound:StopSound(id)
    local busyMetaId = self.busySoundIdToMetaId[id]
    if busyMetaId then
      if self.busyById then
        local limitData = self.busyById[busyMetaId]
        if limitData then
          limitData[id] = nil
        end
      end
      self.busySoundIdToMetaId[id] = nil
    end
    if self.envSoundGroupIndexList then
      for index, soundId in ipairs(self.envSoundGroupIndexList) do
        if soundId == id then
          self.envSoundGroupIndexList[index] = 0
          break
        end
      end
    end
  end
  if id == Sound:GetBGMusic() and not ignorePlayBgm then
    CommonUtil.PlayGameBgMusic()
  end
end

function LWSoundManager:StopAllSounds()
  Sound:StopAllSounds()
  if self.busyById then
    self.busyById = nil
    self.busySoundIdToMetaId = {}
  end
  self.envSoundGroupIndexList = {}
end

function LWSoundManager:PlayAMBSound(id)
  local meta = DataCenter.LWSoundTemplateManager:GetTemplate(id)
  if not meta then
    return 0
  end
  local assetName
  if meta.usePath2 then
    assetName = meta.soundPath2:GetRandom()
  else
    assetName = meta.sound:GetRandom()
  end
  return Sound:PlayAMBSound(assetName, meta.usePath2, meta.soundPathTable, meta.reactive, meta.loop_gap, meta.pre_time, meta.speed)
end

function LWSoundManager:PlaySound(id, loop, independent)
  local meta = DataCenter.LWSoundTemplateManager:GetTemplate(id)
  if not meta then
    return 0
  end
  if meta.sound_type ~= LWSoundType.Normal then
    return self:PlaySoundWithType(meta, 0, loop, nil, independent)
  end
  local assetName = meta.sound:GetRandom()
  if not assetName then
    Logger.LogError(string.format("lw_sound\232\161\168%s\232\161\140sound\229\136\151\228\184\186\231\169\186", id))
    return 0
  end
  return self:PlaySoundByAssetName(assetName, loop, independent)
end

function LWSoundManager:PlaySoundWithStartTime(id, startTime, loop, fadeTime)
  local meta = DataCenter.LWSoundTemplateManager:GetTemplate(id)
  if not meta then
    return 0
  end
  if meta.sound_type ~= LWSoundType.Normal then
    return self:PlaySoundWithType(meta, startTime, loop, fadeTime)
  end
end

function LWSoundManager:PlaySoundByAssetName(assetName, loop, independent)
  if string.IsNullOrEmpty(assetName) then
    return 0
  end
  if loop then
    if self.isEffectOn then
      local param = CS.SoundComponent.PlaySoundParams()
      param.Loop = true
      local path = string.format(LoadPath.SoundEffect, assetName)
      local soundGroupName = independent and assetName or "LoopEffect"
      self.effectExtraGroup[soundGroupName] = true
      return Sound:PlaySound(path, soundGroupName, param, nil)
    end
  else
    return Sound:PlayEffect(assetName)
  end
end

function LWSoundManager:PlaySoundByIdWithLimit(id, limitType, isLoop)
  local meta = DataCenter.LWSoundTemplateManager:GetTemplate(id)
  if not meta then
    return 0
  end
  local assetName
  if self.useAudioMixer then
    assetName = meta.audioSource:GetRandom()
  else
    assetName = meta.sound:GetRandom()
  end
  if not assetName then
    Logger.LogError(string.format("lw_sound\232\161\168%s\232\161\140sound\229\136\151\228\184\186\231\169\186", id))
    return 0
  end
  if SoundIdToLimitType[id] then
    self.limit[SoundIdToLimitType[id]] = meta.sound_num
  end
  if isLoop and 0 < meta.sound_time then
    return self:PlayLoopSoundWithLimit(assetName, limitType, meta.sound_time / 1000)
  else
    return self:PlaySoundWithLimit(assetName, limitType)
  end
end

function LWSoundManager:StopPlayLoopSoundWithLimit(limitType, timer)
  if timer and timer.timerId then
    local timerId = timer.timerId
    if self.loopTimerList[limitType] and self.loopTimerIdList[timerId] then
      table.removebyvalue(self.loopTimerList[limitType], timerId)
    end
    local timer = self.loopTimerIdList[timerId]
    self.loopTimerIdList[timerId] = nil
    timer:Stop()
  end
end

function LWSoundManager:PlaySoundWithLimit(assetName, limitType)
  for i = 1, self.limit[limitType] do
    if self.busy[limitType][i] == nil then
      self.busy[limitType][i] = 0.5
      return Sound:PlayEffect(assetName)
    end
  end
end

function LWSoundManager:PlaySoundByCache(id)
  local meta = DataCenter.LWSoundTemplateManager:GetTemplate(id)
  if not meta then
    return 0
  end
  if meta.sound_type ~= LWSoundType.Eff then
    return self:PlaySound(id, false)
  end
  local max = meta.sound_num
  local soundTime = meta.sound_time
  local limitData
  if 0 < max and 0 < soundTime then
    soundTime = soundTime / 1000
    if self.busyById == nil then
      self.busyById = {}
    end
    limitData = self.busyById[id]
    if limitData == nil then
      limitData = {}
      self.busyById[id] = limitData
    elseif max <= table.count(limitData) then
      return 0
    end
  end
  local assetName
  local path = "Assets/Main/Sound/Effect/%s.ogg"
  if meta.usePath2 then
    path = nil
    assetName = meta.soundPath2:GetRandom()
  else
    assetName = meta.sound:GetRandom()
  end
  if not assetName then
    Logger.LogError(string.format("lw_sound\232\161\168%s\232\161\140sound\229\136\151\228\184\186\231\169\186", id))
    return 0
  end
  if path then
    assetName = string.format(path, assetName)
  end
  local soundId = Sound:PlayEffectCache(assetName, meta.sound_volume, meta.sound_set)
  if limitData then
    limitData[soundId] = soundTime
    self.busySoundIdToMetaId[soundId] = id
  end
  return soundId
end

function LWSoundManager:ReleaseEffectCache(id)
  local meta = DataCenter.LWSoundTemplateManager:GetTemplate(id)
  if not meta then
    return false
  end
  if meta.sound_type ~= LWSoundType.Eff then
    return false
  end
  local assetName
  local path = "Assets/Main/Sound/Effect/%s.ogg"
  if meta.usePath2 then
    path = nil
    assetName = meta.soundPath2:GetRandom()
  else
    assetName = meta.sound:GetRandom()
  end
  if not assetName then
    Logger.LogError(string.format("lw_sound\232\161\168%s\232\161\140sound\229\136\151\228\184\186\231\169\186", id))
    return false
  end
  if path then
    assetName = string.format(path, assetName)
  end
  return Sound:ReleaseEffect(assetName)
end

function LWSoundManager:PlayLoopSoundWithLimit(assetName, limitType, soundLength)
  local timerIdList = {}
  if self.loopTimerList[limitType] then
    timerIdList = self.loopTimerList[limitType]
  else
    self.loopTimerList[limitType] = timerIdList
  end
  if table.count(timerIdList) < self.limit[limitType] then
    local soundTimer = LWSoundTimer.New(assetName, soundLength)
    table.insert(timerIdList, soundTimer.timerId)
    self.loopTimerIdList[soundTimer.timerId] = soundTimer
    return soundTimer
  end
end

function LWSoundManager:PlaySoundWithNameLimit(assetName, limitType)
  local typeStr = limitType .. assetName
  if self.busyByName[typeStr] == nil then
    self.busyByName[typeStr] = {}
  end
  local template = self.limitByName[limitType]
  if template and #self.busyByName[typeStr] < template.num then
    table.insert(self.busyByName[typeStr], template.time)
    if CommonUtil.IsDebug() then
      Logger.Log("PlaySoundWithNameLimit:" .. assetName)
    end
    return Sound:PlayEffect(assetName)
  end
end

function LWSoundManager:CheckSoundOutput()
  if self.delayCheckOutput then
    self.delayCheckOutput:Stop()
    self.delayCheckOutput = nil
  end
  self.delayCheckOutput = TimerManager:GetInstance():DelayInvoke(function()
    self.delayCheckOutput = nil
    Sound:CheckSoundOutput()
  end, 0.1)
end

function LWSoundManager:SetSoundEffectOnOff(isOn)
  self.isEffectOn = isOn
  for name, _ in pairs(self.effectExtraGroup) do
    Sound:SetSoundGroupMute(name, not isOn)
  end
  if not isOn then
    self:CheckSoundOutput()
  end
end

function LWSoundManager:GetLangName()
  local lang = self:GetVoiceLang()
  local langName
  if lang == 20 then
    langName = "de2"
  elseif lang == 3 then
    langName = "ar2"
  else
    langName = Localization:GetLanguageNameByInt(lang)
  end
  return langName
end

function LWSoundManager:PlayHeroSound(name, soundGroup)
  local langName = self:GetLangName()
  local assetPath = string.format(LoadPath.SoundHero, langName, name)
  if not CS.GameEntry.Resource:HasAsset(assetPath) then
    assetPath = string.format(LoadPath.SoundHero, "en", name)
  end
  return Sound:PlaySound(assetPath, SoundGround.Hero)
end

function LWSoundManager:PlayDub(name)
  local langName = self:GetLangName()
  local assetPath = string.format(LoadPath.SoundDub, langName, name)
  if not CS.GameEntry.Resource:HasAsset(assetPath) then
    assetPath = string.format(LoadPath.SoundDub, "en", name)
  end
  return Sound:PlaySound(assetPath, SoundGround.Dub)
end

function LWSoundManager:GetVoiceLang()
  if not self.voiceLang then
    self.voiceLang = Setting:GetInt("SETTING_VOICE", -1)
    if self.voiceLang == -1 then
      self.voiceLang = Localization:GetLanguage()
    end
    local allSupportedLangs = self:GetSupportedVoiceLangs()
    local isSupported
    for _, v in ipairs(allSupportedLangs) do
      if self.voiceLang == v then
        isSupported = true
        break
      end
    end
    if not isSupported then
      self.voiceLang = Language.English
    end
  end
  return self.voiceLang
end

function LWSoundManager:SetVoiceLang(langInt)
  self.voiceLang = langInt
  Setting:SetInt("SETTING_VOICE", langInt)
end

function LWSoundManager:GetSupportedVoiceLangs()
  if not self.supportedVoiceLangs then
    self.supportedVoiceLangs = {}
    local cfg = LuaEntry.DataConfig:TryGetStr("voice_selection", "k1", "14;27;28")
    cfg = string.split(cfg, ";")
    for i, v in ipairs(cfg) do
      self.supportedVoiceLangs[i] = tonumber(v)
    end
  end
  return self.supportedVoiceLangs
end

function LWSoundManager:PauseSound(serialId)
  Sound:PauseSound(serialId)
end

function LWSoundManager:ResumeSound(serialId)
  Sound:ResumeSound(serialId)
end

function LWSoundManager:PlaySoundWithType(meta, startTime, loop, fadeTime, independent)
  local type = meta.sound_type
  local assetName
  if meta.usePath2 then
    assetName = meta.soundPath2:GetRandom()
  else
    assetName = meta.sound:GetRandom()
  end
  if string.IsNullOrEmpty(assetName) then
    return 0
  end
  local isLoop = loop
  if isLoop == nil then
    isLoop = true
  end
  if type == LWSoundType.BGM then
    local time = startTime or 0
    local fade = fadeTime or 0.5
    Sound:PlayBGMusicByNameWithStartTime(assetName, time, isLoop, meta.sound_volume, meta.sound_set, fade, meta.speed, meta.usePath2, meta.reactive, meta.loop_gap, meta.pre_time)
    return Sound:GetBGMusic()
  elseif type == LWSoundType.Eff then
    local max = meta.sound_num
    local soundTime = meta.sound_time
    local id = meta.id
    local limitData
    if 0 < max and 0 < soundTime then
      soundTime = soundTime / 1000
      if self.busyById == nil then
        self.busyById = {}
      end
      limitData = self.busyById[id]
      if limitData == nil then
        limitData = {}
        self.busyById[id] = limitData
      elseif max > table.count(limitData) then
      else
        return 0
      end
    end
    local sound_change = meta.sound_change
    if isLoop and self.isEffectOn then
      local param = CS.SoundComponent.PlaySoundParams()
      param.Loop = true
      param.VolumeInSoundGroup = meta.sound_volume
      param.SoundVolumeSet = meta.sound_set
      if sound_change then
        param.FadeInSeconds = 0.5
        param.FadeOutSeconds = 0.5
      end
      local soundGroupName = "LoopEffect"
      self.effectExtraGroup[soundGroupName] = true
      local path = meta.usePath2 and assetName or string.format(LoadPath.SoundEffect, assetName)
      local soundId = Sound:PlaySound(path, soundGroupName, param, nil)
      if limitData then
        limitData[soundId] = soundTime
        self.busySoundIdToMetaId[soundId] = id
      end
      return soundId
    end
    if sound_change then
      if self.isEffectOn then
        local soundGroupName = independent and assetName or "EffectFade"
        local param = CS.SoundComponent.PlaySoundParams()
        param.FadeInSeconds = 0.5
        param.FadeOutSeconds = 0.5
        param.VolumeInSoundGroup = meta.sound_volume
        param.SoundVolumeSet = meta.sound_set
        self.effectExtraGroup[soundGroupName] = true
        local path = meta.usePath2 and assetName or string.format(LoadPath.SoundEffect, assetName)
        local soundId = Sound:PlaySound(path, soundGroupName, param, nil)
        if limitData then
          limitData[soundId] = soundTime
          self.busySoundIdToMetaId[soundId] = id
        end
        return soundId
      else
        return 0
      end
    else
      local soundId
      if meta.usePath2 then
        soundId = Sound:PlayEffectFullPath(assetName, meta.sound_volume, meta.sound_set)
      else
        soundId = Sound:PlayEffect(assetName, meta.sound_volume, meta.sound_set)
      end
      if limitData then
        limitData[soundId] = soundTime
        self.busySoundIdToMetaId[soundId] = id
      end
      return soundId
    end
  elseif type == LWSoundType.Env then
    if self.isEffectOn then
      if loop == false then
        Logger.LogError("PlaySoundWithType Env sound must be loop : " .. meta.id)
      elseif self.envSoundGroupIndexList then
        local soundGroupIndex
        for index, soundId in ipairs(self.envSoundGroupIndexList) do
          if soundId == 0 then
            soundGroupIndex = index
            break
          end
        end
        if soundGroupIndex == nil then
          soundGroupIndex = #self.envSoundGroupIndexList + 1
        end
        local param = CS.SoundComponent.PlaySoundParams()
        param.Loop = true
        param.VolumeInSoundGroup = meta.sound_volume
        param.SoundVolumeSet = meta.sound_set
        if meta.sound_change then
          param.FadeInSeconds = 0.5
          param.FadeOutSeconds = 0.5
        end
        local soundGroupName = "Env_" .. soundGroupIndex
        self.effectExtraGroup[soundGroupName] = true
        local path = meta.usePath2 and assetName or string.format(LoadPath.SoundEffect, assetName)
        local soundId = Sound:PlaySound(path, soundGroupName, param, nil)
        self.envSoundGroupIndexList[soundGroupIndex] = soundId
        return soundId
      end
    end
  else
    Logger.LogError("PlaySoundWithType invalid type : " .. type)
  end
  return 0
end

function LWSoundManager:PlayBloodyNightTransitionBGM(startTime)
  local meta = DataCenter.LWSoundTemplateManager:GetTemplate(70030)
  if not meta then
    return
  end
  local startTimeFloat = startTime / 1000
  self:PlaySoundWithType(meta, startTimeFloat, false)
end

function LWSoundManager:NewCommonSoundTest()
  if self.abTest ~= nil then
    return self.abTest
  end
  local server = LuaEntry.Player:GetSourceServerId()
  if server == -1 then
    return true
  end
  local serverArray = LuaEntry.DataConfig:TryGetStr("sound_change_server", CS.CommonUtils.IsDebug() and "k1" or "k2")
  if not string.IsNullOrEmpty(serverArray) then
    local array = string.split(serverArray, "|")
    for _, arr in ipairs(array) do
      local list = string.split(arr, "-")
      if #list == 2 then
        local startServer = tonumber(list[1])
        local endServer = tonumber(list[2])
        if startServer <= endServer and server >= startServer and server <= endServer then
          self.abTest = true
          return self.abTest
        end
      elseif #list == 1 then
        local se = tonumber(list[1]) or 0
        if 0 < se and se == server then
          self.abTest = true
          return self.abTest
        end
      end
    end
  end
  self.abTest = false
  return false
end

function LWSoundManager:IsAudioMixerUsable()
  local server = LuaEntry.Player:GetSourceServerId()
  if server == -1 then
    return false
  end
  local serverArray = LuaEntry.DataConfig:TryGetStr("audio_mixer_using", CS.CommonUtils.IsDebug() and "k1" or "k2")
  if not string.IsNullOrEmpty(serverArray) then
    local array = string.split(serverArray, "|")
    for _, arr in ipairs(array) do
      local list = string.split(arr, "-")
      if #list == 2 then
        local startServer = tonumber(list[1])
        local endServer = tonumber(list[2])
        if startServer <= endServer and server >= startServer and server <= endServer then
          return true
        end
      elseif #list == 1 then
        local se = tonumber(list[1]) or 0
        if 0 < se and se == server then
          return true
        end
      end
    end
  end
  return false
end

function LWSoundManager:PlayMusicById(id, loop)
  local meta = DataCenter.LWSoundTemplateManager:GetTemplate(id)
  if not meta then
    return 0
  end
  local assetName
  if self.useAudioMixer then
    assetName = meta.sound:GetRandom()
    if not assetName then
      assetName = meta.audioSource:GetRandom()
      if not assetName then
        Logger.LogError(string.format("lw_sound\232\161\168%s\232\161\140audiosource\228\184\186\231\169\186", id))
        return
      end
      return
    end
  else
    assetName = meta.sound:GetRandom()
    if not assetName then
      assetName = meta.soundPath2:GetRandom()
      if not assetName then
        Logger.LogError(string.format("lw_sound\232\161\168%s\232\161\140sound\229\136\151\229\146\140sound2\229\136\151\233\131\189\228\184\186\231\169\186", id))
        return
      end
      return
    end
  end
  if not assetName then
    Logger.LogError(string.format("lw_sound\232\161\168%s\232\161\140sound\229\136\151\228\184\186\231\169\186", id))
    return 0
  end
  return CS.GameEntry.Sound:PlayMusic(assetName, not not loop, 0.5, 0, 1, -1, 1, meta.usePath2)
end

function LWSoundManager:PlayMusic(path, loop)
  CS.GameEntry.Sound:PlayMusic(path, not not loop)
end

function LWSoundManager:PlayParkourBattleBGMusic()
  if CS.GameEntry.Sound.PlayParkourBattleBGMusic ~= nil then
    CS.GameEntry.Sound:PlayParkourBattleBGMusic()
  else
    CS.GameEntry.Sound:PlayMusic("bgm_pve_30034")
  end
end

function LWSoundManager:PlayPveSceneBGMusic()
  if CS.GameEntry.Sound.PlayPveSceneBGMusic ~= nil then
    CS.GameEntry.Sound:PlayPveSceneBGMusic()
  end
end

function LWSoundManager:PlayPveSceneBGMusicLW()
  if CS.GameEntry.Sound.PlayPveSceneBGMusicLW ~= nil then
    CS.GameEntry.Sound:PlayPveSceneBGMusicLW()
  else
    CS.GameEntry.Sound:PlayMusic("Bgm_Movie_Battle1")
  end
end

function LWSoundManager:FadeOutAndPlayMusic(id, time)
  CS.GameEntry.Sound:FadeOutAndPlayMusic(id, time)
end

function LWSoundManager:PlayBGMusicByName(path)
  CS.GameEntry.Sound:PlayBGMusicByName(path)
end

function LWSoundManager:PlayBGMWithDspTime(bgmFullPath, loop, fadeIn, getMusicStartDspTimeFunc, musicLoadFinishFunc)
  CS.GameEntry.Sound:PlayBGMWithDspTime(bgmFullPath, loop, fadeIn, getMusicStartDspTimeFunc, musicLoadFinishFunc)
end

function LWSoundManager:StopBGMusic()
  CS.GameEntry.Sound:StopBGMusic()
end

function LWSoundManager:SetEffectMute(mute)
  local temps = DataCenter.LWSoundTemplateManager:GetGroupTemplates()
  if temps then
    for _, t in pairs(temps) do
      if t and t.menu_option == 1 then
        Sound:SetSoundGroupMute(t.group, mute, true)
      end
    end
  else
    Logger.LogError("[AudioMixer]DataCenter.LWSoundTemplateManager:GetGroupTemplates Is Nil")
  end
  Sound:SetSoundGroupMute(SoundGround.Effect, mute)
  Sound:SetSoundGroupMute(SoundGround.Dub, mute)
  Sound:SetSoundGroupMute(SoundGround.Hero, mute)
  Sound:SetSoundGroupMute(SoundGround.AMBSound, mute)
  if mute then
    self:CheckSoundOutput()
  end
end

function LWSoundManager:SetMusicMute(mute)
  local temps = DataCenter.LWSoundTemplateManager:GetGroupTemplates()
  if temps then
    for _, t in pairs(temps) do
      if t and t.menu_option == 0 then
        Sound:SetSoundGroupMute(t.group, mute, true)
      end
    end
  else
    Logger.LogError("[AudioMixer]DataCenter.LWSoundTemplateManager:GetGroupTemplates Is Nil")
  end
  Sound:SetSoundGroupMute(SoundGround.Music, mute)
  if mute then
    self:CheckSoundOutput()
  end
end

function LWSoundManager:IsSoundEffectGroup(name)
  local temp = DataCenter.LWSoundTemplateManager:GetGroupTempByName(name)
  if temp == nil then
    Logger.LogWarning("[AudioMixer]IsSoundEffectGroup Temp Is Nil : " .. name)
    return false
  end
  if temp.menu_option == 0 then
    return false
  end
  return true
end

function LWSoundManager:ChangeEffectVolumeRatio(val)
  Sound:ChangeGlobalSettingVolumeRatio(SoundGround.Effect, val)
  Sound:ChangeGlobalSettingVolumeRatio(SoundGround.Dub, val)
  Sound:ChangeGlobalSettingVolumeRatio(SoundGround.Hero, val)
  Sound:ChangeGlobalSettingVolumeRatio(SoundGround.AMBSound, val)
  local temps = DataCenter.LWSoundTemplateManager:GetGroupTemplates()
  if temps then
    for _, t in pairs(temps) do
      if t and t.menu_option == 1 then
        Sound:ChangeGlobalSettingVolumeRatio(t.group, val)
      end
    end
  else
    Logger.LogError("[AudioMixer]DataCenter.LWSoundTemplateManager:GetGroupTemplates Is Nil")
  end
end

function LWSoundManager:ChangeMusicVolumeRatio(val)
  Sound:ChangeGlobalSettingVolumeRatio(SoundGround.Music, val)
  local temps = DataCenter.LWSoundTemplateManager:GetGroupTemplates()
  if temps then
    for _, t in pairs(temps) do
      if t and t.menu_option == 0 then
        Sound:ChangeGlobalSettingVolumeRatio(t.group, val)
      end
    end
  else
    Logger.LogError("[AudioMixer]DataCenter.LWSoundTemplateManager:GetGroupTemplates Is Nil")
  end
end

function LWSoundManager:SetUseAudioMixer(value)
  self.useAudioMixer = value
end

return LWSoundManager
