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

public class BjMotionControl : MonoBehaviour
{
	public Maid TargetMaid
	{
		get
		{
			return this.m_TargetMaid;
		}
	}

	public string nMotionName { get; private set; }

	public static BjMotionControl Instance { get; private set; }

	public bool IsWait { get; private set; }

	public bool DoLeaveMotion
	{
		get
		{
			return this.m_DoLeaveMotion;
		}
		set
		{
			this.m_DoLeaveMotion = value;
			if (value)
			{
				this.m_WaitCoroutine = this.LeaveMotion();
				base.StartCoroutine(this.m_WaitCoroutine);
			}
			else if (this.m_WaitCoroutine != null)
			{
				base.StopCoroutine(this.m_WaitCoroutine);
			}
		}
	}

	public Transform RightHand
	{
		get
		{
			return this.m_RightBone;
		}
	}

	public Transform Lefthand
	{
		get
		{
			return this.m_LeftBone;
		}
	}

	private ScriptManager m_ScriptMgr
	{
		get
		{
			return GameMain.Instance.ScriptMgr;
		}
	}

	private void Awake()
	{
		BjMotionControl.Instance = this;
		this.m_WaitMotionList.Add(BjMotionControl.WaitType.Normal, this.m_BaseWaitMotion);
		this.m_WaitMotionList.Add(BjMotionControl.WaitType.Split1, this.m_StandardChoiseWait);
		this.m_WaitMotionList.Add(BjMotionControl.WaitType.Split2, this.m_SplitChoiseWait);
		this.m_WaitMotionList.Add(BjMotionControl.WaitType.Muku, this.m_MukuWin);
		this.m_WaitMotionList.Add(BjMotionControl.WaitType.Majime, this.m_MajimeWin);
		this.m_WaitMotionList.Add(BjMotionControl.WaitType.Rindere, this.m_RindereWin);
	}

	private void Start()
	{
		string text = "bjmotion_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))
					{
						this.m_LabelMotpair.Add(csvParser.GetCellAsString(1, i), (csvParser.GetCellAsString(2, i) + ".anm").ToLower());
					}
				}
			}
		}
		KasaiUtility.CsvReadY("bj_winmotion_data.nei", new Action<CsvParser, int>(this.ReadWinMotion), 1, new Action(this.SetDefaultWinMotion));
	}

	private void ReadWinMotion(CsvParser csv, int cy)
	{
		BjMotionControl.WaitType value = (BjMotionControl.WaitType)Enum.Parse(typeof(BjMotionControl.WaitType), csv.GetCellAsString(0, cy));
		string[] array = csv.GetCellAsString(1, cy).Split(new char[]
		{
			'\n'
		});
		foreach (string key in array)
		{
			this.m_PersonalWinMotionPair.Add(key, value);
		}
	}

	private void SetDefaultWinMotion()
	{
		this.m_PersonalWinMotionPair.Add("Muku", BjMotionControl.WaitType.Muku);
		this.m_PersonalWinMotionPair.Add("Pure", BjMotionControl.WaitType.Muku);
		this.m_PersonalWinMotionPair.Add("Majime", BjMotionControl.WaitType.Majime);
		this.m_PersonalWinMotionPair.Add("Pride", BjMotionControl.WaitType.Majime);
		this.m_PersonalWinMotionPair.Add("Rindere", BjMotionControl.WaitType.Rindere);
		this.m_PersonalWinMotionPair.Add("Cool", BjMotionControl.WaitType.Rindere);
	}

	private IEnumerator LeaveMotion()
	{
		float timer = 0f;
		int wait_time = UnityEngine.Random.Range(this.m_WaitMinTime, this.m_WaitMaxTime);
		Action end_action = delegate()
		{
			this.m_DoLeaveMotion = true;
		};
		for (;;)
		{
			if (this.m_DoLeaveMotion && this.IsWait && !BjVoiceMgr.Instance.isPlay)
			{
				timer += Time.deltaTime;
				if (timer > (float)wait_time)
				{
					timer = 0f;
					this.m_DoLeaveMotion = false;
					wait_time = UnityEngine.Random.Range(this.m_WaitMinTime, this.m_WaitMaxTime);
					if (!BlackjackGame.Instance.isZoom)
					{
						this.PlayMotion("*覗き込む", end_action, false, false);
						BjVoiceMgr.Instance.PlayVoice("行動選択放置", null, 0f);
					}
					else
					{
						BjVoiceMgr.Instance.PlayVoice("行動選択放置", end_action, 0f);
					}
				}
			}
			else
			{
				timer = 0f;
			}
			yield return null;
		}
		yield break;
	}

	private IEnumerator MotionEndCall(string motion_name, Action end_action = null)
	{
		yield return null;
		float last_time = -1f;
		while (this.m_IsVoiceWait && this.m_IsVoiceAfter && this.m_TargetMaid.AudioMan.isPlay())
		{
			yield return null;
		}
		for (;;)
		{
			bool motion_end = false;
			IEnumerator enumerator = this.m_AnimationChache.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					object obj = enumerator.Current;
					AnimationState animationState = (AnimationState)obj;
					if (animationState.name == motion_name)
					{
						motion_end = (animationState.normalizedTime < last_time);
						last_time = animationState.normalizedTime;
						break;
					}
				}
			}
			finally
			{
				IDisposable disposable;
				if ((disposable = (enumerator as IDisposable)) != null)
				{
					disposable.Dispose();
				}
			}
			if (motion_end)
			{
				break;
			}
			yield return null;
		}
		while (this.m_IsVoiceWait && !this.m_IsVoiceAfter && this.m_TargetMaid.AudioMan.isPlay())
		{
			yield return null;
		}
		if (end_action != null)
		{
			end_action();
		}
		this.IsWait = !this.ForceWaitStop;
		yield break;
	}

	private IEnumerator ToNextMotion(string motion_name, string next_label, Action end_action1 = null, Action end_action2 = null)
	{
		yield return null;
		float last_time = -1f;
		for (;;)
		{
			bool motion_end = false;
			IEnumerator enumerator = this.m_AnimationChache.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					object obj = enumerator.Current;
					AnimationState animationState = (AnimationState)obj;
					if (animationState.name == motion_name)
					{
						motion_end = (animationState.normalizedTime < last_time);
						last_time = animationState.normalizedTime;
						break;
					}
				}
			}
			finally
			{
				IDisposable disposable;
				if ((disposable = (enumerator as IDisposable)) != null)
				{
					disposable.Dispose();
				}
			}
			if (motion_end)
			{
				break;
			}
			yield return null;
		}
		if (end_action1 != null)
		{
			end_action1();
		}
		this.MotionFade(next_label, end_action2);
		yield break;
	}

	private void MotionFade(string label, Action end_action = null)
	{
		if (!this.m_TargetMaid)
		{
			return;
		}
		this.nMotionName = label;
		this.m_ScriptMgr.StopMotionScript();
		this.m_ScriptMgr.is_motion_blend = this.m_IsMotionBlend;
		this.m_ScriptMgr.LoadMotionScript(0, false, "work_002.ks", label, string.Empty, string.Empty, false, true);
		this.m_IsMotionBlend = true;
		if (!this.IsWait)
		{
			if (this.m_nMotionEndCall != null)
			{
				base.StopCoroutine(this.m_nMotionEndCall);
			}
			this.m_nMotionEndCall = this.MotionEndCall(this.m_LabelMotpair[label], end_action);
			base.StartCoroutine(this.m_nMotionEndCall);
		}
		BlackjackGame.Instance.SetDealerPos();
	}

	private void MotionToMotion(string first_label, string next_label, Action action1 = null, Action action2 = null)
	{
		if (!this.m_TargetMaid)
		{
			return;
		}
		this.nMotionName = first_label;
		this.m_ScriptMgr.StopMotionScript();
		this.m_ScriptMgr.is_motion_blend = this.m_IsMotionBlend;
		this.m_ScriptMgr.LoadMotionScript(0, false, "work_002.ks", first_label, string.Empty, string.Empty, false, true);
		this.m_IsMotionBlend = true;
		if (!this.IsWait)
		{
			if (this.m_nToNextMotion != null)
			{
				base.StopCoroutine(this.m_nToNextMotion);
			}
			this.m_nToNextMotion = this.ToNextMotion(this.m_LabelMotpair[first_label], next_label, action1, action2);
			base.StartCoroutine(this.m_nToNextMotion);
		}
		BlackjackGame.Instance.SetDealerPos();
	}

	public void Init()
	{
		this.m_TargetMaid = GameMain.Instance.CharacterMgr.GetMaid(0);
		this.m_TargetMaid.EyeToCamera(Maid.EyeMoveType.無視する, 0f);
		this.m_AnimationChache = this.m_TargetMaid.body0.GetAnimation();
		this.m_IsMotionBlend = false;
		this.PlayWaitMotion(BjMotionControl.WaitType.Normal);
		this.m_LeftBone = this.m_TargetMaid.body0.GetBone("_IK_handL");
		this.m_RightBone = this.m_TargetMaid.body0.GetBone("_IK_handR");
	}

	public void PlayMotion(string motion_label, Action end_action = null, bool voice_wait = false, bool voice_after = false)
	{
		bool isWait = this.IsWait;
		this.IsWait = false;
		this.m_IsVoiceWait = voice_wait;
		this.m_IsVoiceAfter = voice_after;
		if (isWait && !this.ForceWaitStop && this.m_WaitMotionList[this.m_WaitMotion].IsStartandEnd)
		{
			this.MotionToMotion(this.m_WaitMotionList[this.m_WaitMotion].WaitEndLabel, motion_label, null, end_action);
		}
		else
		{
			this.MotionFade(motion_label, end_action);
		}
	}

	public void PlayWinMotion(Maid maid)
	{
		this.PlayWaitMotion(this.m_PersonalWinMotionPair[maid.status.personal.uniqueName]);
	}

	public void PlayWaitMotion(BjMotionControl.WaitType motion)
	{
		if (!this.m_TargetMaid)
		{
			return;
		}
		if (this.ForceWaitStop)
		{
			return;
		}
		this.SetWaitMotion(motion);
		this.IsWait = true;
		this.MotionFade(this.m_WaitMotionList[motion].WaitStartLabel, null);
	}

	public void PlayWaitMotion()
	{
		this.PlayWaitMotion(this.m_WaitMotion);
	}

	public void SetWaitMotion(BjMotionControl.WaitType motion)
	{
		this.m_WaitMotion = motion;
		this.IsWait = false;
	}

	public string GetHaihuMotion()
	{
		if (BjPlayer.Instance.IsSplitGame() && BjPlayer.Instance.IsNowSplitHand)
		{
			return "*スプリットで配布" + BjPlayer.Instance.splitHand.CardNum.ToString();
		}
		return "*プレイヤーに配布" + BjPlayer.Instance.standardHand.CardNum.ToString();
	}

	public Vector3 RightHandPos()
	{
		return this.m_RightBone.position;
	}

	public Vector3 LeftHandPos()
	{
		return this.m_LeftBone.position;
	}

	private Maid m_TargetMaid;

	[HideInInspector]
	public bool ForceWaitStop;

	private const string m_MotionScriptName = "work_002.ks";

	private Animation m_AnimationChache;

	[SerializeField]
	private int m_WaitMinTime = 5;

	[SerializeField]
	private int m_WaitMaxTime = 15;

	[SerializeField]
	private BjMotionControl.Motion3Part m_BaseWaitMotion;

	[SerializeField]
	private BjMotionControl.Motion3Part m_StandardChoiseWait;

	[SerializeField]
	private BjMotionControl.Motion3Part m_SplitChoiseWait;

	[Header("各性格勝利時モーション")]
	[SerializeField]
	private BjMotionControl.Motion3Part m_MukuWin;

	[SerializeField]
	private BjMotionControl.Motion3Part m_MajimeWin;

	[SerializeField]
	private BjMotionControl.Motion3Part m_RindereWin;

	private BjMotionControl.WaitType m_WaitMotion;

	private Dictionary<BjMotionControl.WaitType, BjMotionControl.Motion3Part> m_WaitMotionList = new Dictionary<BjMotionControl.WaitType, BjMotionControl.Motion3Part>();

	private IEnumerator m_nMotionEndCall;

	private IEnumerator m_nToNextMotion;

	private IEnumerator m_WaitCoroutine;

	private bool m_DoLeaveMotion;

	private Transform m_RightBone;

	private Transform m_LeftBone;

	private Dictionary<string, string> m_LabelMotpair = new Dictionary<string, string>();

	private Dictionary<string, BjMotionControl.WaitType> m_PersonalWinMotionPair = new Dictionary<string, BjMotionControl.WaitType>();

	private bool m_IsMotionBlend = true;

	private bool m_IsVoiceWait;

	private bool m_IsVoiceAfter;

	public enum WaitType
	{
		Normal,
		Split1,
		Split2,
		Muku,
		Majime,
		Rindere
	}

	[Serializable]
	private class Motion3Part
	{
		public bool IsStartandEnd
		{
			get
			{
				return !string.IsNullOrEmpty(this.WaitStartLabel) && !string.IsNullOrEmpty(this.WaitEndLabel);
			}
		}

		public string WaitStartLabel;

		public string WaitEndLabel;
	}
}
