using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class Note_Mgr : PartsMgrBase
{
	public int CellX
	{
		get
		{
			return this.m_CellX;
		}
	}

	public int CellY
	{
		get
		{
			return this.m_CellY;
		}
	}

	public static Note_Mgr Instance
	{
		get
		{
			return Note_Mgr.m_Instance;
		}
	}

	public int UIRootWidth { get; private set; }

	public int UIRootHeight { get; private set; }

	public GameObject NoteEffectPrefab { get; private set; }

	public int SpecialCombo
	{
		get
		{
			return this.m_SpecialCombo;
		}
	}

	public int GetSpecial
	{
		get
		{
			return this.m_GetSpecial;
		}
	}

	private float m_TotalAnimeTime
	{
		get
		{
			return this.m_TextJumpTime * (float)this.m_FullComboObj.childCount + this.m_AnimeLag * (float)(this.m_FullComboObj.childCount - 1) + this.m_DeleteWait;
		}
	}

	protected override void Start()
	{
		Note_Mgr.m_Instance = this;
		base.Start();
		if (!base.IsActive)
		{
			base.gameObject.SetActive(false);
			return;
		}
		this.m_FullComboSe = Resources.Load<AudioClip>("SceneDance/Rhythm_Action/Sound/" + this.m_FullcomSeStr);
		this.NoteEffectPrefab = Resources.Load<GameObject>("SceneDance/Rhythm_Action/Prefab/NoteEffect");
		this.m_SEAudioList = this.m_NoteSEAudio.GetComponents<AudioSource>();
		RhythmAction_Mgr.Instance.AddAudioMgr(this.m_SEAudioList);
		UIRoot component = GameObject.Find("UI Root").GetComponent<UIRoot>();
		this.UIRootWidth = component.manualWidth;
		this.UIRootHeight = component.manualHeight;
		this.m_FullComboObj.gameObject.SetActive(false);
		this.m_NoteCharaData.Add(DanceBattle_Mgr.CharaType.Player, new Note_Mgr.NoteCharaData());
		if (RhythmAction_Mgr.NowDance == RhythmAction_Mgr.DanceType.VS || RhythmAction_Mgr.NowDance == RhythmAction_Mgr.DanceType.BenchMark)
		{
			this.m_NoteCharaData.Add(DanceBattle_Mgr.CharaType.Enemy, new Note_Mgr.NoteCharaData());
		}
		this.m_NoteObj = Resources.Load<GameObject>("SceneDance/Rhythm_Action/Prefab/Note");
		Dance_Note component2 = this.m_NoteObj.GetComponent<Dance_Note>();
		this.m_JudgeStart_Time = component2.GetBeforeJudge(Dance_Note.Evaluation.BAD) + component2.NotJudgeTime;
		this.CSVRead();
	}

	private void CSVRead()
	{
		string text = RhythmAction_Mgr.Instance.MusicCSV_Path + "note_data.nei";
		if (!GameUty.FileSystem.IsExistentFile(text))
		{
			NDebug.Assert("表がありません。" + text, false);
		}
		using (AFileBase afileBase = GameUty.FileSystem.FileOpen(text))
		{
			using (CsvParser csvParser = new CsvParser())
			{
				bool condition = csvParser.Open(afileBase);
				NDebug.Assert(condition, text + "\nopen failed.");
				for (int i = 1; i < csvParser.max_cell_y; i++)
				{
					if (csvParser.IsCellToExistData(0, i))
					{
						Note_Mgr.NoteData noteData = new Note_Mgr.NoteData();
						for (int j = 1; j < csvParser.max_cell_x; j++)
						{
							this.DataParce(csvParser, j, i, noteData);
						}
						this.m_All_NoteData.Add(noteData);
					}
				}
			}
		}
	}

	private void DataParce(CsvParser csv, int cell_X, int cell_Y, Note_Mgr.NoteData data)
	{
		switch (cell_X)
		{
		case 1:
			data.Time = csv.GetCellAsReal(cell_X, cell_Y);
			break;
		case 2:
		{
			string cellAsString = csv.GetCellAsString(cell_X, cell_Y);
			string[] array = cellAsString.Split(new char[]
			{
				','
			});
			data.DotX = int.Parse(array[0]);
			data.DotY = int.Parse(array[1]);
			break;
		}
		case 4:
		{
			string[] array2 = csv.GetCellAsString(cell_X, cell_Y).Split(new char[]
			{
				':'
			});
			if (data.Voltage == null)
			{
				data.Voltage = new List<int>();
			}
			foreach (string s in array2)
			{
				data.Voltage.Add(int.Parse(s));
			}
			break;
		}
		case 5:
			if (csv.GetCellAsString(cell_X, cell_Y) == "エフェクト無し")
			{
				data.effectType = Note_Mgr.EffecctType.Nothing;
			}
			else if (csv.GetCellAsString(cell_X, cell_Y) == "小エフェクト")
			{
				data.effectType = Note_Mgr.EffecctType.Few;
			}
			break;
		case 6:
			data.RingSize = ((!csv.IsCellToExistData(cell_X, cell_Y)) ? -1f : csv.GetCellAsReal(cell_X, cell_Y));
			break;
		}
	}

	private float OccurTime(DanceBattle_Mgr.CharaType chara)
	{
		int dataUseCount = this.m_NoteCharaData[chara].DataUseCount;
		if (this.m_All_NoteData.Count <= dataUseCount)
		{
			return -1f;
		}
		if (chara == DanceBattle_Mgr.CharaType.Player)
		{
			return this.m_All_NoteData[dataUseCount].Time - this.m_JudgeStart_Time - DanceSetting.Settings.NoteJudgeTiming;
		}
		return this.m_All_NoteData[dataUseCount].Time;
	}

	private bool IsOccurOK(DanceBattle_Mgr.CharaType chara_type)
	{
		bool result = false;
		int voltage = 0;
		int dataUseCount = this.m_NoteCharaData[chara_type].DataUseCount;
		if (chara_type == DanceBattle_Mgr.CharaType.Player)
		{
			voltage = Voltage_Mgr.Instance.VoltageStage;
		}
		else if (chara_type == DanceBattle_Mgr.CharaType.Enemy)
		{
			voltage = DanceBattle_Mgr.EnemyData.UseVoltage;
		}
		if (this.m_All_NoteData.Count > dataUseCount)
		{
			result = this.m_All_NoteData[dataUseCount].Voltage.Any((int e) => e == voltage);
		}
		return result;
	}

	private bool IsExistKeyInput()
	{
		foreach (KeyCode key in this.m_AsClickKey)
		{
			if (Input.GetKeyDown(key))
			{
				return true;
			}
		}
		return false;
	}

	private IEnumerator NoteCheck()
	{
		float timer = 0f;
		bool input_check = true;
		for (;;)
		{
			if (!RhythmAction_Mgr.Instance.IsPause)
			{
				timer += RhythmAction_Mgr.Instance.DanceDeltaTime;
				foreach (KeyValuePair<DanceBattle_Mgr.CharaType, Note_Mgr.NoteCharaData> keyValuePair in this.m_NoteCharaData)
				{
					if (keyValuePair.Key == DanceBattle_Mgr.CharaType.Player)
					{
						if (keyValuePair.Value.NoteList.Count > 0)
						{
							keyValuePair.Value.NoteList.First<Dance_Note>().SetTargetNote();
						}
						bool flag = false;
						if (input_check)
						{
							if (GameMain.Instance.VRMode && !GameMain.Instance.OvrMgr.OvrCamera.IsNoHandController)
							{
								OvrMgr.OvrObject.Controller left_controller = GameMain.Instance.OvrMgr.ovr_obj.left_controller;
								OvrMgr.OvrObject.Controller right_controller = GameMain.Instance.OvrMgr.ovr_obj.right_controller;
								flag |= (left_controller.controller_buttons.GetPressDown(AVRControllerButtons.BTN.VIRTUAL_L_CLICK) && left_controller.controller.HandDanceMode);
								flag |= (right_controller.controller_buttons.GetPressDown(AVRControllerButtons.BTN.VIRTUAL_L_CLICK) && right_controller.controller.HandDanceMode);
							}
							else
							{
								flag = (NInput.GetMouseButtonDown(0) || this.IsExistKeyInput());
							}
						}
						else
						{
							input_check = true;
						}
						if (flag)
						{
							input_check = false;
							if (!Appeal_Mgr.Instance.IsActive || !Appeal_Mgr.Instance.GetPlayerData().IsAppealNow)
							{
								this.CheckStart(keyValuePair.Key);
							}
						}
					}
					if (this.OccurTime(keyValuePair.Key) > 0f && timer >= this.OccurTime(keyValuePair.Key))
					{
						bool flag2 = this.IsOccurOK(keyValuePair.Key);
						if (keyValuePair.Value.DataUseCount + 1 < this.m_All_NoteData.Count)
						{
							flag2 &= (timer < this.m_All_NoteData[keyValuePair.Value.DataUseCount + 1].Time);
						}
						if (flag2)
						{
							GameObject gameObject = UnityEngine.Object.Instantiate<GameObject>(this.m_NoteObj);
							gameObject.transform.SetParent(base.transform, false);
							int dotX = this.m_All_NoteData[keyValuePair.Value.DataUseCount].DotX;
							int dotY = this.m_All_NoteData[keyValuePair.Value.DataUseCount].DotY;
							gameObject.GetComponent<Dance_Note>().Init(this.m_All_NoteData[keyValuePair.Value.DataUseCount], keyValuePair.Key, keyValuePair.Value.DataUseCount);
						}
						keyValuePair.Value.DataUseCount++;
					}
				}
			}
			yield return null;
		}
		yield break;
	}

	private void FullComboAnim(float time)
	{
		for (int i = 0; i < this.m_FullComboObj.childCount; i++)
		{
			if (time < (float)i * this.m_AnimeLag)
			{
				break;
			}
			float current_time = Mathf.Clamp(time - this.m_AnimeLag * (float)i, 0f, this.m_TextJumpTime);
			Transform child = this.m_FullComboObj.GetChild(i);
			Vector3 localPosition = child.localPosition;
			localPosition.y = this.m_TextJump * KasaiUtility.SinRate01(current_time, this.m_TextJumpTime / 2f, false, true);
			child.localPosition = localPosition;
		}
	}

	public void CheckStart(DanceBattle_Mgr.CharaType chara)
	{
		if (this.m_NoteCharaData[chara].NoteList.Count > 0)
		{
			this.m_NoteCharaData[chara].NoteList.First<Dance_Note>().CheckNote();
		}
	}

	public void RemoveNote(DanceBattle_Mgr.CharaType chara)
	{
		if (this.m_NoteCharaData[chara].NoteList.Count > 0)
		{
			this.m_NoteCharaData[chara].NoteList.RemoveAt(0);
		}
		if (chara != DanceBattle_Mgr.CharaType.Player && RhythmAction_Mgr.NowDance != RhythmAction_Mgr.DanceType.VS)
		{
			return;
		}
		if (this.IsNoteEnd(chara) && !Score_Mgr.Instance.IsExistMiss)
		{
			Score_Mgr.Instance.NotMissClear();
			this.m_FullComboObj.gameObject.SetActive(true);
			this.NoteSEPlay(this.m_FullComboSe);
			base.StartCoroutine(RhythmAction_Mgr.Instance.DanceTimeCoroutine(this.m_TotalAnimeTime, new Action<float>(this.FullComboAnim), delegate()
			{
				this.m_FullComboObj.gameObject.SetActive(false);
			}));
		}
	}

	public void AddNote(Dance_Note note, DanceBattle_Mgr.CharaType chara)
	{
		this.m_NoteCharaData[chara].NoteList.Add(note);
		if (note.IsAppealNow)
		{
			this.AddAppealNoteCount(chara);
		}
	}

	public void NoteSEPlay(AudioClip clip = null)
	{
		foreach (AudioSource audioSource in this.m_SEAudioList)
		{
			if (!audioSource.isPlaying)
			{
				if (clip)
				{
					audioSource.clip = clip;
				}
				audioSource.Play();
				break;
			}
		}
	}

	public bool IsNoteEnd(DanceBattle_Mgr.CharaType chara_type)
	{
		bool flag = this.m_NoteCharaData[chara_type].DataUseCount == this.m_All_NoteData.Count;
		bool flag2 = this.m_NoteCharaData[chara_type].NoteList.Count == 0;
		return flag && flag2;
	}

	public bool IsNoteSpecial(DanceBattle_Mgr.CharaType chara_type)
	{
		return this.m_NoteCharaData[chara_type].IsSpecialNote;
	}

	public void SetSpecialFlag(DanceBattle_Mgr.CharaType chara_type, bool flag_value)
	{
		this.m_NoteCharaData[chara_type].IsSpecialNote = flag_value;
	}

	public int AppealNoteCount(DanceBattle_Mgr.CharaType chara_type)
	{
		return this.m_NoteCharaData[chara_type].AppealNoteCount;
	}

	public void AddAppealNoteCount(DanceBattle_Mgr.CharaType chara_type)
	{
		this.m_NoteCharaData[chara_type].AppealNoteCount++;
	}

	public void RecetAppealCount(DanceBattle_Mgr.CharaType chara_type)
	{
		this.m_NoteCharaData[chara_type].AppealNoteCount = 0;
	}

	public bool CanNoteAppeal(DanceBattle_Mgr.CharaType chara_type)
	{
		return Appeal_Mgr.Instance.IsActive && Appeal_Mgr.Instance.GetAppealData(chara_type).IsAppealNow && this.m_NoteCharaData[chara_type].AppealNoteCount < Appeal_Mgr.Instance.AppealComboCount;
	}

	public override void StartAction()
	{
		base.StartCoroutine(this.NoteCheck());
	}

	public override void EndAction()
	{
		base.StopAllCoroutines();
	}

	private const string m_NoteEffectPath = "SceneDance/Rhythm_Action/Prefab/NoteEffect";

	private const string m_NotePath = "SceneDance/Rhythm_Action/Prefab/Note";

	[SerializeField]
	[Header("横マス数")]
	private int m_CellX = 27;

	[SerializeField]
	[Header("縦マス数")]
	private int m_CellY = 17;

	[SerializeField]
	[Header("ノートSE用のオーディオ")]
	private GameObject m_NoteSEAudio;

	private AudioSource[] m_SEAudioList;

	private Dictionary<DanceBattle_Mgr.CharaType, Note_Mgr.NoteCharaData> m_NoteCharaData = new Dictionary<DanceBattle_Mgr.CharaType, Note_Mgr.NoteCharaData>();

	private List<Note_Mgr.NoteData> m_All_NoteData = new List<Note_Mgr.NoteData>();

	private Vector2 m_DotSize = Vector2.zero;

	private GameObject m_NoteObj;

	private float m_JudgeStart_Time;

	private static Note_Mgr m_Instance;

	[SerializeField]
	[Header("フルコンボ時の設定")]
	private Transform m_FullComboObj;

	[SerializeField]
	private float m_TextJump = 90f;

	[SerializeField]
	private float m_TextJumpTime = 0.3f;

	[SerializeField]
	private float m_AnimeLag = 0.05f;

	[SerializeField]
	private float m_DeleteWait = 0.25f;

	[SerializeField]
	private string m_FullcomSeStr = "4_battle_win";

	[SerializeField]
	[Header("左クリックに割り当てるキー")]
	private List<KeyCode> m_AsClickKey = new List<KeyCode>();

	[SerializeField]
	[Header("このコンボ数毎に特殊なノート発生")]
	private int m_SpecialCombo = 50;

	[SerializeField]
	[Header("このコンボ数分の効果を得る")]
	private int m_GetSpecial = 10;

	private AudioClip m_FullComboSe;

	public enum EffecctType
	{
		ALL,
		Few,
		Nothing
	}

	public class NoteData
	{
		public float Time;

		public int DotX;

		public int DotY;

		public List<int> Voltage;

		public Note_Mgr.EffecctType effectType;

		public float RingSize;
	}

	private class NoteCharaData
	{
		public List<Dance_Note> NoteList = new List<Dance_Note>();

		public int DataUseCount;

		public bool IsSpecialNote;

		public int AppealNoteCount;
	}
}
