using System;
using System.Collections;
using System.Collections.Generic;
using CriWare;
using UnityEngine;

namespace Cute;

public class AudioManager : MonoBehaviour, IManager
{
	[SerializeField]
	private GameObject _bgmParent;

	[SerializeField]
	private CriAtomSource[] _bgm;

	private int _bgmSourceCount;

	[SerializeField]
	private GameObject _seParent;

	[SerializeField]
	private CriAtomSource[] _se;

	private int _seSourceCount;

	private SoundData[] _playingSe;

	[SerializeField]
	private GameObject _voiceParent;

	[SerializeField]
	private CriAtomSource[] _voice;

	private int _voiceSourceCount;

	private bool _bgmPlaySuspend;

	private const int BGM_FADEOUT_TIME = 500;

	private const int SONG_PREVIEW_FADE_TIME = 500;

	private const int SONG_PREVIEW_FADE_SPACE_TIME = 1500;

	private const float SE_FADE_TIME = 0.5f;

	public const int DELAY_TIME_OFFSET = -4;

	private const float VOULMN_BOOST_FACTOR = 1.5f;

	public const string ACB_EXTENSION_WITHPARAM = "{0}.acb";

	public const string ACB_EXTENSION = ".acb";

	public const string AWB_EXTENSION_WITHPARAM = "{0}.awb";

	public const string AWB_EXTENSION = ".awb";

	private const string STR_SUBFOLDER_BGM = "b/";

	public const string STR_SUBFOLDER_SE = "s/";

	private const string STR_SUBFOLDER_SONG = "l/";

	private const string STR_SUBFOLDER_VOICE = "v/";

	private const string STR_SUBFOLDER_STORY = "c/";

	private const string STR_SUBFOLDER_ROOM = "r/";

	public bool isDownloadVoiceUse = true;

	protected bool _isRedy;

	private bool _noSeMode;

	private CriAtomExPlayback _playback;

	private CriAtomExPlayback _bgmPlayback;

	private float _sampleTime;

	private int _delayTime;

	private int _criDelayTime;

	private int _criInitializeCount;

	private const int CRI_RETRY_COUNT = 3;

	private Dictionary<string, CriAtomExAcb> _acbDictionary = new Dictionary<string, CriAtomExAcb>();

	private string[] STR_PREINSTALL_FILENAME = new string[1] { "preinstall" };

	public const float VOICE_MASTER_VOLUME = 0.8f;

	private Action _callbackVoiseEnd;

	private string _bgmName = "";

	private int _cueId = -1;

	private string _bgmCue = "";

	public bool isRedy => _isRedy;

	public int delayTime
	{
		get
		{
			return _delayTime;
		}
		set
		{
			_delayTime = value;
		}
	}

	public string bgmName
	{
		get
		{
			return _bgmName;
		}
		set
		{
			_bgmName = value;
		}
	}

	public int cueId
	{
		get
		{
			return _cueId;
		}
		set
		{
			_cueId = value;
		}
	}

	public string bgmCue
	{
		get
		{
			return _bgmCue;
		}
		set
		{
			_bgmCue = value;
		}
	}

	private void Awake()
	{
	}

	private IEnumerator Start()
	{
		_bgm = _bgmParent.GetComponentsInChildren<CriAtomSource>();
		_bgmSourceCount = _bgm.Length;
		for (int i = 0; i < _bgmSourceCount; i++)
		{
			CriAtomExPlayer player = _bgm[i].player;
			player.AttachFader();
			player.ResetFaderParameters();
			player.SetFadeOutTime(500);
		}
		_se = _seParent.GetComponentsInChildren<CriAtomSource>();
		_seSourceCount = _se.Length;
		_playingSe = new SoundData[_seSourceCount];
		for (int j = 0; j < _seSourceCount; j++)
		{
			CriAtomExPlayer player2 = _se[j].player;
			player2.AttachFader();
			player2.ResetFaderParameters();
		}
		_voice = _voiceParent.GetComponentsInChildren<CriAtomSource>();
		_voiceSourceCount = _voice.Length;
		for (int k = 0; k < _voiceSourceCount; k++)
		{
			CriAtomExPlayer player3 = _voice[k].player;
			player3.AttachFader();
			player3.ResetFaderParameters();
		}
		Toolbox.AudioManager = this;
		yield break;
	}

	public void ResetSoundMode()
	{
		_noSeMode = false;
	}

	private void Update()
	{
	}

	public void PauseAllBgm(bool pauseStatus)
	{
		if (pauseStatus)
		{
			_bgmPlaySuspend = false;
			for (int i = 0; i < _bgmSourceCount; i++)
			{
				if (_bgm[i].status == CriAtomSource.Status.Prep || _bgm[i].status == CriAtomSource.Status.Playing)
				{
					_bgm[i].Pause(sw: true);
					_bgmPlaySuspend = true;
				}
			}
		}
		else if (_bgmPlaySuspend)
		{
			for (int j = 0; j < _bgmSourceCount; j++)
			{
				_bgm[j].Pause(sw: false);
			}
		}
	}

	public long GetMusicLength(string acbName)
	{
		CriAtomExAcb acb = CriAtom.GetAcb(acbName);
		if (acb != null && acb.GetCueInfo(0, out var info))
		{
			return info.length;
		}
		return -1L;
	}

	public bool IsAvailableCueSheet(string cueName)
	{
		CriAtomCueSheet cueSheet = CriAtom.GetCueSheet(cueName);
		if (cueSheet != null)
		{
			return cueSheet.acb != null;
		}
		return false;
	}

	public bool AddCueSheet(string _name, string acbFile, string subFolderPath, string awbname = "")
	{
		_name = _name.Replace(".acb", "");
		if (CriAtom.GetCueSheet(_name) != null || CriAtom.GetCueSheet(acbFile) != null)
		{
			return true;
		}
		bool flag = false;
		int num = STR_PREINSTALL_FILENAME.Length;
		for (int i = 0; i < num; i++)
		{
			if (string.Compare(_name, STR_PREINSTALL_FILENAME[i]) == 0)
			{
				flag = true;
				break;
			}
		}
		if (flag)
		{
			acbFile = $"{subFolderPath}{acbFile}";
			awbname = $"{subFolderPath}{awbname}";
		}
		else
		{
			acbFile = string.Format("{0}{1}{2}{3}", Application.persistentDataPath, "/", subFolderPath, acbFile);
			awbname = string.Format("{0}{1}{2}{3}", Application.persistentDataPath, "/", subFolderPath, awbname);
		}
		CriAtomCueSheet criAtomCueSheet = CriAtom.AddCueSheet(_name, acbFile, awbname);
		if (criAtomCueSheet == null)
		{
			return false;
		}
		if (criAtomCueSheet.acb == null)
		{
			RemoveCueSheet(_name);
			return false;
		}
		return true;
	}

	public bool AddCueSheetFromFileName(string _name, string acbFile, string awbname)
	{
		_name = _name.Replace(".acb", "");
		int num = STR_PREINSTALL_FILENAME.Length;
		for (int i = 0; i < num && string.Compare(_name, STR_PREINSTALL_FILENAME[i]) != 0; i++)
		{
		}
		if (CriAtom.GetCueSheet(_name) != null)
		{
			return true;
		}
		CriAtomCueSheet criAtomCueSheet = CriAtom.AddCueSheet(_name, acbFile, awbname);
		if (criAtomCueSheet == null)
		{
			return false;
		}
		if (criAtomCueSheet.acb == null)
		{
			RemoveCueSheet(_name);
			return false;
		}
		return true;
	}

	public void RemoveCueSheet(string name)
	{
		name = name.Replace(".awb", "");
		name = name.Replace(".acb", "");
		name = name.Replace("s/", "");
		name = name.Replace("b/", "");
		CriAtom.RemoveCueSheet(name);
	}

	public void RemoveCueSheet(List<string> nameList)
	{
		for (int i = 0; i < nameList.Count; i++)
		{
			RemoveCueSheet(nameList[i]);
		}
	}

	public float GetSampleTime()
	{
		long numSamples = 0L;
		int samplingRate = 0;
		if (_playback.GetNumPlayedSamples(out numSamples, out samplingRate))
		{
			_sampleTime = (float)numSamples / (float)samplingRate;
		}
		return _sampleTime;
	}

	private void OnDestroy()
	{
		foreach (KeyValuePair<string, CriAtomExAcb> item in _acbDictionary)
		{
			item.Value.Dispose();
		}
	}

	public int GetDelayTimeFromCRI()
	{
		int result = 0;
		if (_criInitializeCount >= 3)
		{
			return result;
		}
		return _criDelayTime / 10;
	}

	public CriAtomSource GetBgmSource(int bgmId)
	{
		return _bgm[bgmId];
	}

	public int GetBgmMaxCount()
	{
		return _bgmSourceCount;
	}

	public void VolumeUpdate_Bgm(int level, bool mute, int bgmId = -1)
	{
		if (bgmId < 0)
		{
			int num = _bgm.Length;
			for (int i = 0; i < num; i++)
			{
				Volume_Bgm((float)level * 0.1f, mute, i);
			}
		}
		else
		{
			Volume_Bgm((float)level * 0.1f, mute, bgmId);
		}
	}

	public void Volume_Bgm(float level, bool mute, int bgmId = -1)
	{
		if (mute)
		{
			level = 0f;
		}
		if (bgmId < 0)
		{
			int num = _bgm.Length;
			for (int i = 0; i < num; i++)
			{
				_bgm[i].volume = level;
				_bgm[i].player.Update(_bgmPlayback);
			}
		}
		else
		{
			_bgm[bgmId].volume = level;
			_bgm[bgmId].player.Update(_bgmPlayback);
		}
	}

	public bool IsPlayBgm(int bgmId = 0)
	{
		if (_bgm[bgmId].status == CriAtomSource.Status.Prep || _bgm[bgmId].status == CriAtomSource.Status.Playing)
		{
			return true;
		}
		return false;
	}

	public int PlayBgmFromName(string cueSheet, string cueName, string acbName, string awbName = "", int bgmId = 0, bool loop = true, float FadeInfime = 0f, float OffsetTime = 0f, long startTime = 0L)
	{
		if (_bgmName == cueName)
		{
			return -1;
		}
		string acbFile = "";
		string awbname = "";
		if (acbName.CompareTo("") != 0)
		{
			acbFile = acbName + ".acb";
		}
		if (awbName.CompareTo("") != 0)
		{
			awbname = awbName + ".awb";
		}
		if (AddCueSheet(cueSheet, acbFile, "b/", awbname))
		{
			StopBgm(bgmId);
			_bgm[bgmId].cueSheet = cueSheet;
			_bgm[bgmId].cueName = cueName;
			_bgm[bgmId].player.ResetFaderParameters();
			_bgm[bgmId].player.SetStartTime(startTime);
			_bgm[bgmId].player.SetFadeInTime((int)(FadeInfime * 1000f));
			_bgm[bgmId].player.SetFadeInStartOffset((int)(OffsetTime * 1000f));
			_bgm[bgmId].loop = loop;
			_bgmPlayback = _bgm[bgmId].Play();
			_bgmName = cueName;
			return 0;
		}
		return -1;
	}

	public int PlayBgmFromId(string cueSheet, int cueId, int bgmId = 0, bool loop = true, float FadeInfime = 0f, float OffsetTime = 0f, long startTime = 0L)
	{
		if (_bgmCue == cueSheet && cueId == _cueId)
		{
			return -1;
		}
		if (CriAtom.GetCueSheet(cueSheet) != null)
		{
			StopBgm(bgmId);
			_bgm[bgmId].cueSheet = cueSheet;
			_bgm[bgmId].player.ResetFaderParameters();
			_bgm[bgmId].player.SetStartTime(startTime);
			_bgm[bgmId].player.SetFadeInTime((int)(FadeInfime * 1000f));
			_bgm[bgmId].player.SetFadeInStartOffset((int)(OffsetTime * 1000f));
			_bgm[bgmId].loop = loop;
			_bgmPlayback = _bgm[bgmId].Play(cueId);
			_cueId = cueId;
			_bgmCue = "";
			return 1;
		}
		return 0;
	}

	public void StopBgm(int bgmId = 0)
	{
		_bgmName = "";
		_bgm[bgmId].Stop();
	}

	public void PauseBgm(bool isPause, int bgmId = 0)
	{
		_bgm[bgmId].Pause(isPause);
	}

	public void StopFadeBgm(int bgmId = 0, float time = 0.5f)
	{
		_bgm[bgmId].player.SetFadeOutTime((int)(time * 1000f));
		StopBgm(bgmId);
	}

	public void SetBgmVolume(float volume)
	{
		GameMgr.GetIns().GetSoundMgr().SetBgmVolume(volume);
	}

	public void StartCoroutine_DelayMethod(float waitTime, Action process)
	{
		StartCoroutine(Timer.DelayMethod(waitTime, process));
	}

	public void VolumeUpdate_Se(int level, bool mute)
	{
		Volume_Se((float)level * 0.1f, mute);
	}

	public void Volume_Se(float level, bool mute)
	{
		if (mute)
		{
			level = 0f;
		}
		for (int i = 0; i < _seSourceCount; i++)
		{
			_se[i].volume = level;
		}
	}

	public int PlaySeFromId(ref SoundData seData, bool loop = false)
	{
		int index = -1;
		CriAtomSource criAtomSource = FindSe(ref seData, out index);
		if (criAtomSource != null)
		{
			criAtomSource.cueSheet = seData._acbName;
			criAtomSource.loop = loop;
			CriAtomExPlayer player = criAtomSource.player;
			player.ResetFaderParameters();
			player.SetFadeOutTime(0);
			criAtomSource.Play(seData._cueName);
			return index;
		}
		return index;
	}

	public int PlaySeFromId(string cueName, int cueId, bool loop = false)
	{
		if (!IsAvailableCueSheet(cueName))
		{
			return -1;
		}
		for (int i = 0; i < _seSourceCount; i++)
		{
			if (_se[i].status == CriAtomSource.Status.PlayEnd)
			{
				_se[i].Stop();
			}
			if (_se[i].status == CriAtomSource.Status.Stop)
			{
				_se[i].cueSheet = cueName;
				_se[i].loop = loop;
				_se[i].Play(cueId);
				return i;
			}
		}
		return -1;
	}

	private CriAtomSource FindSe(ref SoundData seData, out int index)
	{
		index = -1;
		if (_noSeMode)
		{
			return null;
		}
		if (!IsAvailableCueSheet(seData._acbName))
		{
			Debug.LogError($"No Include Acb!!!:{seData._acbName},{seData._cueName}");
			return null;
		}
		for (int i = 0; i < _seSourceCount; i++)
		{
			if (_se[i].status == CriAtomSource.Status.PlayEnd)
			{
				_se[i].Stop();
			}
			if (_se[i].status == CriAtomSource.Status.Stop)
			{
				index = i;
				return _se[i];
			}
		}
		return null;
	}

	public int PlaySe(string cueName, int cueId, bool loop = false)
	{
		if (!IsAvailableCueSheet(cueName))
		{
			return -1;
		}
		for (int i = 0; i < _seSourceCount; i++)
		{
			if (_se[i].status == CriAtomSource.Status.PlayEnd)
			{
				_se[i].Stop();
			}
			if (_se[i].status == CriAtomSource.Status.Stop)
			{
				_se[i].cueSheet = cueName;
				_se[i].loop = loop;
				_se[i].Play(cueId);
				return i;
			}
		}
		return -1;
	}

	public void StopSe(int index, float fadeout = 500f)
	{
		if (index >= 0 && index < _seSourceCount)
		{
			ResumeSe(index);
			_se[index].player.SetFadeOutTime((int)(fadeout * 1000f));
			_se[index].Stop();
		}
	}

	public void StopSe(string cuename, float fadeout = 500f)
	{
		for (int i = 0; i < _se.Length; i++)
		{
			if (_se[i].cueName.CompareTo(cuename) == 0)
			{
				ResumeSe(i);
				_se[i].player.SetFadeOutTime((int)(fadeout * 1000f));
				_se[i].Stop();
			}
		}
	}

	public void StopSeAll(float fadeout = 500f)
	{
		for (int i = 0; i < _seSourceCount; i++)
		{
			StopSe(i, fadeout);
		}
	}

	public void PauseSe(int index)
	{
		if (index >= 0 && index < _seSourceCount && (_se[index].status == CriAtomSource.Status.Playing || _se[index].status == CriAtomSource.Status.Prep))
		{
			_se[index].Pause(sw: true);
		}
	}

	public void ResumeSe(int index)
	{
		if (index >= 0 && index < _seSourceCount && _se[index].status == CriAtomSource.Status.Playing)
		{
			_se[index].Pause(sw: false);
		}
	}

	public bool IsPlaySe(string cueName, int cueId)
	{
		for (int i = 0; i < _seSourceCount; i++)
		{
			if (_playingSe[i]._cueName == cueName && _playingSe[i]._cueId == cueId && (_se[i].status == CriAtomSource.Status.Prep || _se[i].status == CriAtomSource.Status.Playing))
			{
				return true;
			}
		}
		return false;
	}

	public bool IsPlaySe(string cueSheetName, string cueName, out int number)
	{
		number = 0;
		for (int i = 0; i < _seSourceCount; i++)
		{
			if (_playingSe[i]._acbName == cueSheetName && _playingSe[i]._cueName == cueName && _se[i].status == CriAtomSource.Status.Playing)
			{
				number++;
			}
		}
		if (number > 0)
		{
			return true;
		}
		return false;
	}

	public bool IsPrepSe(string cueSheetName, string cueName, out int number)
	{
		number = 0;
		for (int i = 0; i < _seSourceCount; i++)
		{
			if (_playingSe[i]._acbName == cueSheetName && _playingSe[i]._cueName == cueName && _se[i].status == CriAtomSource.Status.Prep)
			{
				number++;
			}
		}
		if (number > 0)
		{
			return true;
		}
		return false;
	}

	public void ResetSe()
	{
		for (int i = 0; i < _seSourceCount; i++)
		{
			_se[i].Stop();
			_se[i].Pause(sw: false);
		}
	}

	public bool IsPlaySe(int index)
	{
		if (_se[index].status == CriAtomSource.Status.Prep || _se[index].status == CriAtomSource.Status.Playing)
		{
			return true;
		}
		return false;
	}

	public void SetAisac(string cuename, string param, float num)
	{
		for (int i = 0; i < _se.Length; i++)
		{
			if (_se[i].cueName.CompareTo(cuename) == 0)
			{
				_se[i].SetAisacControl(param, num);
			}
		}
	}

	public int PlaySeFromName(string acbName, string seName, bool loop = false, float fadeInfime = 0f, long startTime = 0L)
	{
		if (!IsAvailableCueSheet(acbName))
		{
			return -1;
		}
		for (int i = 0; i < _seSourceCount; i++)
		{
			if (_se[i].status == CriAtomSource.Status.PlayEnd)
			{
				_se[i].Stop();
			}
			if (_se[i].status == CriAtomSource.Status.Stop)
			{
				_se[i].cueSheet = acbName;
				_se[i].cueName = seName;
				_se[i].loop = loop;
				_se[i].player.ResetFaderParameters();
				_se[i].player.SetStartTime(startTime);
				_se[i].player.SetFadeInTime((int)(fadeInfime * 1000f));
				_se[i].Play(seName);
				return i;
			}
		}
		return -1;
	}

	public int GetVoiceSourceCount()
	{
		return _voiceSourceCount;
	}

	public void VolumeUpdate_Voice(int level, bool mute, int voiceId = -1)
	{
		Volume_Voice((float)level * 0.1f, mute, voiceId);
	}

	public void Volume_Voice(float level, bool mute, int voiceId = -1)
	{
		if (mute)
		{
			level = 0f;
		}
		if (voiceId < 0)
		{
			int num = _voice.Length;
			for (int i = 0; i < num; i++)
			{
				_voice[i].volume = level;
			}
		}
		else
		{
			_voice[voiceId].volume = level;
		}
	}

	public bool IsPlayVoice(int index)
	{
		if (_voice[index].status == CriAtomSource.Status.Prep || _voice[index].status == CriAtomSource.Status.Playing)
		{
			return true;
		}
		return false;
	}

	public void PlayVoice(int voiceId, string acbFile, string cueSheet, string cueName)
	{
		AddCueSheet(cueSheet, acbFile, "v/");
		_voice[voiceId].Play(cueName);
	}

	public void PlayVoice(int voiceId, string cueName)
	{
		_voice[voiceId].Play(cueName);
	}

	public void StopVoice(int voiceId, float fadetout = 500f)
	{
		CriAtomSource criAtomSource = _voice[voiceId];
		if (criAtomSource != null && criAtomSource.player != null)
		{
			criAtomSource.player.SetFadeOutTime((int)(fadetout * 1000f));
			criAtomSource.Stop();
		}
	}
}
