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

public class Dance_Note : NoteBase
{
	public bool IsAppealNow
	{
		get
		{
			return this.m_IsAppealNow;
		}
	}

	public float NotJudgeTime
	{
		get
		{
			return this.m_BaseTiming + this.m_AddTiming * (float)DanceSetting.Settings.NoteOccurTiming;
		}
	}

	protected override void Start()
	{
		base.Start();
		this.m_IsAppealNow = Note_Mgr.Instance.CanNoteAppeal(this.m_MyType);
		Note_Mgr.Instance.AddNote(this, this.m_MyType);
		foreach (ParticleSystem particleSystem in this.m_SpecialEffect)
		{
			particleSystem.gameObject.SetActive(false);
		}
		this.m_IsMySpecial = Note_Mgr.Instance.IsNoteSpecial(this.m_MyType);
		if (this.m_IsMySpecial)
		{
			if (this.m_MyType == DanceBattle_Mgr.CharaType.Player)
			{
				foreach (ParticleSystem particleSystem2 in this.m_SpecialEffect)
				{
					particleSystem2.gameObject.SetActive(true);
					RhythmAction_Mgr.Instance.AddParticleSystem(particleSystem2);
				}
			}
			Note_Mgr.Instance.SetSpecialFlag(this.m_MyType, false);
		}
		if (this.m_MyType == DanceBattle_Mgr.CharaType.Enemy)
		{
			for (int k = 0; k < this.m_NoteUIList.Count<Dance_Note.NoteUIInfo>(); k++)
			{
				this.m_NoteUIList[k].NoteSprite.enabled = false;
			}
			this.m_RingSprite.enabled = false;
			this.CheckNote();
			return;
		}
		this.m_RingWidth = (float)this.m_RingSprite.width;
		this.m_RingHeight = (float)this.m_RingSprite.height;
		float num = this.m_RingWidth - this.m_RingFitNote.x;
		float num2 = this.m_RingHeight - this.m_RingFitNote.y;
		this.m_JudgeStartTime = this.GetBeforeJudge(Dance_Note.Evaluation.BAD) + this.NotJudgeTime;
		this.m_JudgeEndtTime = this.GetAfterJudge(Dance_Note.Evaluation.BAD);
		this.m_nTime = this.m_JudgeStartTime;
		this.m_WidthSpeed = num / this.m_JudgeStartTime;
		this.m_HeightSpeed = num2 / this.m_JudgeStartTime;
		if (this.m_IsAppealNow)
		{
			this.m_RingSprite.color = this.m_Appeal_RingColor;
		}
		else
		{
			this.m_RingSprite.color = this.m_Normal_RingColor;
		}
		base.StartCoroutine(this.NoteScaling());
	}

	private IEnumerator NoteScaling()
	{
		float timer = 0f;
		for (;;)
		{
			if (!RhythmAction_Mgr.Instance.IsPause)
			{
				timer += RhythmAction_Mgr.Instance.DanceDeltaTime;
				float d = Mathf.Sin(Mathf.Clamp01(timer / this.m_ScalingTime) * 90f * 0.0174532924f);
				base.transform.localScale = Vector3.one * d;
				this.m_RingSprite.transform.localScale = Vector3.one / d;
				if (timer > this.m_ScalingTime)
				{
					break;
				}
			}
			yield return null;
		}
		yield break;
		yield break;
	}

	protected override void Update()
	{
		base.Update();
		if (!RhythmAction_Mgr.Instance.IsPause)
		{
			for (int i = 0; i < this.m_NoteUIList.Count<Dance_Note.NoteUIInfo>(); i++)
			{
				if (!this.m_NoteUIList[i].IsRotate)
				{
					this.m_NoteUIList[i].NoteSprite.fillAmount = Mathf.Clamp01(1f - this.m_nTime / this.m_JudgeStartTime) / 2f;
				}
				else
				{
					float d = this.m_RotateSpeed * (float)(1 - i % 2 * 2);
					this.m_NoteUIList[i].NoteSprite.transform.eulerAngles += Vector3.forward * d * RhythmAction_Mgr.Instance.DanceDeltaTime;
				}
			}
			if (!this.m_IsAppealNow && !Note_Mgr.Instance.CanNoteAppeal(this.m_MyType))
			{
				if (this.m_nTime < -this.m_JudgeEndtTime)
				{
					this.NoteEnd(Dance_Note.Evaluation.MISS);
				}
			}
			else
			{
				if (this.m_nTime <= 0f)
				{
					this.NoteEnd(Dance_Note.Evaluation.PERFECT);
				}
				if (this.m_RingSprite.color != this.m_Appeal_RingColor)
				{
					this.m_RingSprite.color = this.m_Appeal_RingColor;
					this.m_IsAppealNow = true;
					Note_Mgr.Instance.AddAppealNoteCount(this.m_MyType);
				}
			}
			this.m_RingWidth -= this.m_WidthSpeed * RhythmAction_Mgr.Instance.DanceDeltaTime;
			this.m_RingHeight -= this.m_HeightSpeed * RhythmAction_Mgr.Instance.DanceDeltaTime;
			this.m_RingSprite.width = Mathf.Max((int)this.m_RingWidth, 0);
			this.m_RingSprite.height = Mathf.Max((int)this.m_RingHeight, 0);
			this.m_nTime -= RhythmAction_Mgr.Instance.DanceDeltaTime;
			if (this.m_nTime <= 0f && Dance_Note.IsAutoPlay)
			{
				this.NoteEnd(Dance_Note.Evaluation.PERFECT);
			}
		}
	}

	public float GetBeforeJudge(Dance_Note.Evaluation evalue)
	{
		return this.m_EvalueJudge.SingleOrDefault((Dance_Note.EvalueJadge e) => e.Evalue == evalue).BeforeJudge;
	}

	public float GetAfterJudge(Dance_Note.Evaluation evalue)
	{
		return this.m_EvalueJudge.SingleOrDefault((Dance_Note.EvalueJadge e) => e.Evalue == evalue).AfterJudge;
	}

	private void NoteEnd(Dance_Note.Evaluation evalue)
	{
		Score_Mgr.Instance.AddScore(evalue, this.m_MyType, this.m_IsMySpecial);
		if (Appeal_Mgr.Instance.IsActive && (evalue == Dance_Note.Evaluation.GREAT || evalue == Dance_Note.Evaluation.PERFECT) && !this.m_IsAppealNow)
		{
			Appeal_Mgr.Instance.AddAppealValue(this.m_MyType, this.m_AddAppeal);
		}
		if (this.m_MyType == DanceBattle_Mgr.CharaType.Player)
		{
			if (DanceSetting.Settings.IsSEPlay && evalue != Dance_Note.Evaluation.MISS)
			{
				Note_Mgr.Instance.NoteSEPlay(null);
			}
			if (Voltage_Mgr.Instance.IsActive)
			{
				Voltage_Mgr.Instance.DownVoltage(evalue);
			}
			RhythmAction_Mgr.Instance.RemoveParticleSystem(this.m_SpecialEffect);
			GameObject gameObject = UnityEngine.Object.Instantiate<GameObject>(Note_Mgr.Instance.NoteEffectPrefab);
			gameObject.transform.parent = base.transform.parent;
			gameObject.transform.localPosition = base.transform.localPosition;
			gameObject.transform.localScale = Vector3.one;
			gameObject.GetComponent<NoteEffect>().Initialize(evalue, this.m_IsAppealNow, this.m_MyDotX, this.m_MyDotY, this.m_effectType);
		}
		Note_Mgr.Instance.RemoveNote(this.m_MyType);
		UnityEngine.Object.Destroy(base.gameObject);
	}

	public void SetTargetNote()
	{
		if (!this.m_IsAppealNow)
		{
			this.m_RingSprite.color = this.m_TargetMarkColor;
			for (int i = 0; i < this.m_NoteUIList.Count<Dance_Note.NoteUIInfo>(); i++)
			{
				if (this.m_NoteUIList[i].IsRotate)
				{
					this.m_NoteUIList[i].NoteSprite.color = this.m_TargetNoteColor;
				}
			}
		}
	}

	public void CheckNote()
	{
		Dance_Note.Evaluation evalue = Dance_Note.Evaluation.MISS;
		if (this.m_MyType == DanceBattle_Mgr.CharaType.Player)
		{
			if (Dance_Note.IsAutoPlay)
			{
				return;
			}
			if (this.m_IsAppealNow)
			{
				return;
			}
			if (this.m_nTime > this.GetBeforeJudge(Dance_Note.Evaluation.BAD))
			{
				return;
			}
			bool flag = true;
			foreach (Dance_Note.EvalueJadge evalueJadge in this.m_EvalueJudge)
			{
				if (!flag)
				{
					bool flag2 = false;
					if (this.m_nTime >= 0f)
					{
						if (evalueJadge.BeforeJudge < this.m_nTime)
						{
							flag2 = true;
						}
					}
					else if (evalueJadge.AfterJudge < Mathf.Abs(this.m_nTime))
					{
						flag2 = true;
					}
					if (flag2)
					{
						break;
					}
					evalue = evalueJadge.Evalue;
				}
				flag = false;
			}
		}
		else if (this.m_MyType == DanceBattle_Mgr.CharaType.Enemy)
		{
			if (this.m_IsAppealNow)
			{
				evalue = Dance_Note.Evaluation.PERFECT;
			}
			else if (UnityEngine.Random.Range(0, 100) >= DanceBattle_Mgr.EnemyData.PushRate)
			{
				evalue = Dance_Note.Evaluation.MISS;
			}
			else
			{
				int num = UnityEngine.Random.Range(0, 100);
				int num2 = 0;
				bool flag3 = false;
				foreach (KeyValuePair<Dance_Note.Evaluation, int> keyValuePair in DanceBattle_Mgr.EnemyData.EvalueRate)
				{
					int num3 = num2 + keyValuePair.Value;
					if (num3 > num && num >= num2)
					{
						flag3 = true;
						evalue = keyValuePair.Key;
						break;
					}
					num2 += keyValuePair.Value;
				}
				if (!flag3)
				{
					evalue = Dance_Note.Evaluation.BAD;
				}
			}
		}
		this.NoteEnd(evalue);
	}

	public void Init(Note_Mgr.NoteData data, DanceBattle_Mgr.CharaType setType, int note_count)
	{
		this.m_MyDotX = data.DotX;
		this.m_MyDotY = data.DotY;
		this.m_MyType = setType;
		this.m_effectType = data.effectType;
		if (data.RingSize > 0f)
		{
			this.m_RingSprite.width = Mathf.FloorToInt((float)this.m_RingSprite.width * data.RingSize);
			this.m_RingSprite.height = Mathf.FloorToInt((float)this.m_RingSprite.height * data.RingSize);
		}
		UIBasicSprite[] componentsInChildren = base.GetComponentsInChildren<UIBasicSprite>();
		foreach (UIBasicSprite uibasicSprite in componentsInChildren)
		{
			uibasicSprite.depth -= (note_count - 1) * componentsInChildren.Count<UIBasicSprite>();
		}
	}

	public static bool IsAutoPlay;

	[SerializeField]
	[Header("輪がノートと完全に重なるサイズ")]
	private Vector2 m_RingFitNote;

	[SerializeField]
	[Header("判定中の輪の色")]
	private Color m_TargetMarkColor = Color.white;

	[SerializeField]
	private UI2DSprite m_RingSprite;

	[SerializeField]
	[Header("通常時の輪の色")]
	private Color m_Normal_RingColor = Color.white;

	[SerializeField]
	[Header("アピール時の輪の色")]
	private Color m_Appeal_RingColor = Color.white;

	[SerializeField]
	[Header("判定中のノートの色")]
	private Color m_TargetNoteColor = Color.white;

	[SerializeField]
	[Header("SE名")]
	private string m_Sound_Name = "PUSH_SE.ogg";

	private float m_RingWidth;

	private float m_RingHeight;

	private float m_nTime;

	private float m_JudgeStartTime;

	private float m_JudgeEndtTime;

	private float m_WidthSpeed;

	private float m_HeightSpeed;

	private bool m_IsAppealNow;

	[SerializeField]
	private float m_ScalingTime = 0.25f;

	[SerializeField]
	[Header("回転速度")]
	private float m_RotateSpeed;

	[SerializeField]
	private Dance_Note.NoteUIInfo[] m_NoteUIList;

	[SerializeField]
	[Header("各評定の設定")]
	private Dance_Note.EvalueJadge[] m_EvalueJudge = new Dance_Note.EvalueJadge[]
	{
		new Dance_Note.EvalueJadge(Dance_Note.Evaluation.MISS, 0),
		new Dance_Note.EvalueJadge(Dance_Note.Evaluation.BAD, 0),
		new Dance_Note.EvalueJadge(Dance_Note.Evaluation.GOOD, 0),
		new Dance_Note.EvalueJadge(Dance_Note.Evaluation.GREAT, 0),
		new Dance_Note.EvalueJadge(Dance_Note.Evaluation.PERFECT, 0)
	};

	[SerializeField]
	[Header("アピール増加量")]
	private int m_AddAppeal = 2;

	[SerializeField]
	[Header("基底タイミング時間")]
	private float m_BaseTiming = 0.5f;

	[SerializeField]
	private float m_AddTiming = 0.05f;

	[SerializeField]
	[Header("コンボ一定数毎に出すエフェクト")]
	private ParticleSystem[] m_SpecialEffect;

	private DanceBattle_Mgr.CharaType m_MyType;

	private bool m_IsMySpecial;

	private Note_Mgr.EffecctType m_effectType;

	public enum Evaluation
	{
		MISS,
		BAD,
		GOOD,
		GREAT,
		PERFECT
	}

	[Serializable]
	private class EvalueJadge
	{
		public EvalueJadge(Dance_Note.Evaluation evalue, int time)
		{
			this.Evalue = evalue;
			this.BeforeJudge = (float)time;
			this.AfterJudge = (float)time;
		}

		[Header("評価")]
		public Dance_Note.Evaluation Evalue;

		[Header("判定時間(0秒までの判定時間)")]
		public float BeforeJudge;

		[Header("判定時間(0秒以降の判定時間)")]
		public float AfterJudge;
	}

	[Serializable]
	private class NoteUIInfo
	{
		public UISprite NoteSprite;

		public bool IsRotate;
	}
}
