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

public class VRTouchComm : MonoBehaviour
{
	private bool m_AnyTalkVoice
	{
		get
		{
			return this.m_MaidTouchDataPair.Values.Any((VRTouchComm.VRTouchData e) => e.TgtMaid.AudioMan.isPlay());
		}
	}

	public void Touch_Operator(KagTagSupport tag_data)
	{
		if (tag_data.IsValid("file"))
		{
			this.Touch_Start(tag_data);
		}
		else if (tag_data.IsValid("end"))
		{
			this.Touch_End();
		}
	}

	public void Touch_Start(KagTagSupport tag_data)
	{
		if (this.m_VR_Kag_Mng_Fast == null)
		{
			ScriptManager scriptMgr = GameMain.Instance.ScriptMgr;
			if (this.m_Base_Kag_Mng == null)
			{
				this.m_Base_Kag_Mng = new BaseKagManager(scriptMgr.tjs, scriptMgr);
				this.m_Base_Kag_Mng.Initialize();
				this.m_Base_Kag_Mng.Exec();
			}
			ScriptManagerFast.KagParserFastCache kag_cache = new ScriptManagerFast.KagParserFastCache(this.m_Base_Kag_Mng);
			this.m_VR_Kag_Mng_Fast = new ScriptManagerFast.VRTouchKagManagerFast(this.m_Base_Kag_Mng, kag_cache, null);
			this.m_VR_Kag_Mng_Fast.Initialize();
			int num = 0;
			if (tag_data.IsValid("maid"))
			{
				num = tag_data.GetTagProperty("maid").AsInteger();
			}
			Maid maid = GameMain.Instance.CharacterMgr.GetMaid(num);
			if (!maid)
			{
				Debug.LogErrorFormat("メイド{0}番が存在しません", new object[]
				{
					num
				});
				return;
			}
			VRTouchComm.VRTouchData vrtouchData = new VRTouchComm.VRTouchData(maid);
			vrtouchData.VoiceInterval = this.m_IntervalTime * (float)this.m_MaidTouchDataPair.Count;
			if (!this.m_MaidTouchDataPair.ContainsKey(maid))
			{
				this.m_MaidTouchDataPair.Add(maid, vrtouchData);
			}
			else
			{
				this.m_MaidTouchDataPair[maid] = vrtouchData;
			}
			this.m_CurSettingTouchData = vrtouchData;
			Maid maid2 = GameMain.Instance.CharacterMgr.GetMaid(num);
			this.m_VR_Kag_Mng_Fast.LoadScript(ScriptManager.ReplacePersonal(maid2, tag_data.GetTagProperty("file").AsString()));
			this.m_VR_Kag_Mng_Fast.Start();
			this.m_VR_Kag_Mng_Fast.Update();
			MaidColliderCollect.AddCollider(vrtouchData.TgtMaid, MaidColliderCollect.ColliderType.Touch);
			if (this.m_Touch_Mgr == null)
			{
				this.m_Touch_Mgr = new VRTouchMgr();
			}
			this.m_MaidTouchDataPair[maid].ActiveCroutine = this.Wait_Voice_Mng(vrtouchData);
			base.StartCoroutine(vrtouchData.ActiveCroutine);
			this.Script_End();
			this.m_CurSettingTouchData = null;
		}
	}

	private void Script_End()
	{
		if (this.m_VR_Kag_Mng_Fast != null)
		{
			this.m_VR_Kag_Mng_Fast.SelfDispose();
			this.m_VR_Kag_Mng_Fast = null;
			if (this.m_Base_Kag_Mng != null)
			{
				this.m_Base_Kag_Mng.Dispose();
				this.m_Base_Kag_Mng = null;
			}
		}
	}

	public void Touch_End()
	{
		this.Script_End();
		foreach (VRTouchComm.VRTouchData vrtouchData in this.m_MaidTouchDataPair.Values)
		{
			if (vrtouchData.TgtMaid)
			{
				MaidColliderCollect.RemoveColliderAll(vrtouchData.TgtMaid);
				vrtouchData.TgtMaid.AudioMan.Stop();
				vrtouchData.TgtMaid.FaceAnime(vrtouchData.FirstFace, 1f, 0);
				vrtouchData.TgtMaid.FaceBlend("無し");
			}
			if (vrtouchData.ActiveCroutine != null)
			{
				base.StopCoroutine(vrtouchData.ActiveCroutine);
			}
			vrtouchData.scriptDataList.Clear();
		}
		this.m_MaidTouchDataPair.Clear();
		this.m_Touch_Mgr = null;
	}

	private void OnDestory()
	{
		this.Touch_End();
	}

	public void Add_Touch(KagTagSupport tag_data)
	{
		this.m_CurSettingTouchData.scriptDataList.Add(this.Data_Parce(tag_data));
	}

	private VRTouchComm.Script_Data Data_Parce(KagTagSupport tag_data)
	{
		VRTouchComm.Script_Data result = default(VRTouchComm.Script_Data);
		if (tag_data.IsValid("maid"))
		{
			result.nMaidNo = tag_data.GetTagProperty("maid").AsInteger();
			if (result.nMaidNo != this.m_CurSettingTouchData.TgtMaid.ActiveSlotNo)
			{
				Debug.Log("@VRTouchScriptと@VRTouchでターゲットとなるメイドが異なります(@VRTouchScript側優先)");
				Debug.LogFormat("@VRTouchScript側:{0}番\u3000@VRTouch側:{1}番", new object[]
				{
					this.m_CurSettingTouchData.TgtMaid.ActiveSlotNo,
					result.nMaidNo
				});
			}
		}
		if (tag_data.IsValid("type"))
		{
			result.strType = tag_data.GetTagProperty("type").AsString();
		}
		if (tag_data.IsValid("voice"))
		{
			result.strVoice = tag_data.GetTagProperty("voice").AsString() + ".ogg";
		}
		if (tag_data.IsValid("num"))
		{
			result.nNum = tag_data.GetTagProperty("num").AsInteger();
		}
		if (tag_data.IsValid("region"))
		{
			result.strRegion = tag_data.GetTagProperty("region").AsString().Split(new char[]
			{
				':'
			});
		}
		if (tag_data.IsValid("face"))
		{
			result.strFace = tag_data.GetTagProperty("face").AsString();
		}
		if (tag_data.IsValid("faceblend"))
		{
			result.strFaceBlend = tag_data.GetTagProperty("faceblend").AsString();
		}
		return result;
	}

	private IEnumerator Wait_Voice_Mng(VRTouchComm.VRTouchData touch_data)
	{
		float timer = 0f;
		float wait_time = 20f + touch_data.VoiceInterval;
		if (touch_data.scriptDataList.Count == 0)
		{
			timer += Time.deltaTime;
			yield return null;
		}
		List<VRTouchComm.Script_Data> data = touch_data.Get_Data(VRTouchComm.Type.WAIT);
		for (;;)
		{
			if (timer >= wait_time && !this.m_AnyTalkVoice)
			{
				timer = 0f;
				touch_data.VoiceInterval = 0f;
				if (data.Count<VRTouchComm.Script_Data>() != 0)
				{
					int index = 0;
					if (data.Count > 1)
					{
						index = UnityEngine.Random.Range(0, data.Count);
					}
					touch_data.TgtMaid.AudioMan.LoadPlay(data[index].strVoice, 0f, false, false);
					touch_data.TgtMaid.FaceAnime(data[index].strFace, 1f, 0);
					touch_data.TgtMaid.FaceBlend(data[index].strFaceBlend);
				}
				else
				{
					Debug.LogError("TouchComm Wait Voice is 0!!");
				}
			}
			else if (!touch_data.TgtMaid.AudioMan.isPlay())
			{
				timer += Time.deltaTime;
			}
			yield return null;
		}
		yield break;
	}

	private void Touch_Voice_Play(VRTouchMgr.ETouchPos touch_pos, VRTouchComm.VRTouchData touch_data)
	{
		List<VRTouchComm.Script_Data> list = touch_data.Get_Data(VRTouchComm.Type.TOUCH);
		list = (from e in list
		where e.nNum == touch_data.TouchCount
		select e).ToList<VRTouchComm.Script_Data>();
		if (list.Count == 0)
		{
			int n_count = -1;
			List<VRTouchComm.Script_Data> list2 = touch_data.Get_Data(VRTouchComm.Type.TOUCH);
			foreach (VRTouchComm.Script_Data script_Data in list2)
			{
				if (n_count == -1 || n_count < script_Data.nNum)
				{
					n_count = script_Data.nNum;
				}
			}
			list = (from e in list2
			where e.nNum == n_count
			select e).ToList<VRTouchComm.Script_Data>();
		}
		List<VRTouchComm.Script_Data> list3 = new List<VRTouchComm.Script_Data>(list);
		list.Clear();
		VRTouchComm.Region region = this.m_TouchPosPair.SingleOrDefault((KeyValuePair<VRTouchMgr.ETouchPos, VRTouchComm.Region> e) => e.Key == touch_pos).Value;
		foreach (VRTouchComm.Script_Data item in list3)
		{
			foreach (string a in item.strRegion)
			{
				if (a == this.m_RegionPair.SingleOrDefault((KeyValuePair<string, VRTouchComm.Region> e) => e.Value == region).Key)
				{
					list.Add(item);
					break;
				}
			}
		}
		if (list.Count > 0)
		{
			int index = 0;
			if (list.Count > 1)
			{
				index = UnityEngine.Random.Range(0, list.Count);
			}
			touch_data.TgtMaid.AudioMan.LoadPlay(list[index].strVoice, 0f, false, false);
			touch_data.TgtMaid.FaceAnime(list[index].strFace, 1f, 0);
			touch_data.TgtMaid.FaceBlend(list[index].strFaceBlend);
		}
		touch_data.ActiveCroutine = this.After_To_Wait(touch_data);
		base.StartCoroutine(touch_data.ActiveCroutine);
	}

	private IEnumerator After_To_Wait(VRTouchComm.VRTouchData touch_data)
	{
		while (touch_data.TgtMaid.AudioMan.isPlay())
		{
			yield return null;
		}
		List<VRTouchComm.Script_Data> bace_data = touch_data.Get_Data(VRTouchComm.Type.AFTER);
		bace_data = (from e in bace_data
		where e.nNum == touch_data.TouchCount
		select e).ToList<VRTouchComm.Script_Data>();
		if (bace_data.Count == 0)
		{
			int n_count = -1;
			List<VRTouchComm.Script_Data> list = touch_data.Get_Data(VRTouchComm.Type.AFTER);
			foreach (VRTouchComm.Script_Data script_Data in list)
			{
				if (n_count == -1 || n_count < script_Data.nNum)
				{
					n_count = script_Data.nNum;
				}
			}
			bace_data = (from e in list
			where e.nNum == n_count
			select e).ToList<VRTouchComm.Script_Data>();
		}
		int rand = 0;
		if (bace_data.Count > 1)
		{
			rand = UnityEngine.Random.Range(0, bace_data.Count);
		}
		touch_data.TgtMaid.FaceAnime(bace_data[rand].strFace, 1f, 0);
		touch_data.TgtMaid.FaceBlend(bace_data[rand].strFaceBlend);
		touch_data.ActiveCroutine = this.Wait_Voice_Mng(touch_data);
		base.StartCoroutine(touch_data.ActiveCroutine);
		yield break;
	}

	private void Update()
	{
		if (this.m_Touch_Mgr == null)
		{
			return;
		}
		this.m_Touch_Mgr.FrameStart();
		foreach (VRTouchComm.VRTouchData vrtouchData in this.m_MaidTouchDataPair.Values)
		{
			bool flag = false;
			VRTouchMgr.ETouchPos touch_pos = VRTouchMgr.ETouchPos.無し;
			int i;
			for (i = 0; i < this.m_RegionPair.Length; i++)
			{
				VRTouchMgr.ETouchPos key = this.m_TouchPosPair.Single((KeyValuePair<VRTouchMgr.ETouchPos, VRTouchComm.Region> e) => e.Value == this.m_RegionPair[i].Value).Key;
				for (int j = 0; j <= 1; j++)
				{
					if (this.m_Touch_Mgr.GetBehaviorTouch((VRTouchMgr.EHand)j, key, VRTouchMgr.ETouchBehavior.触る, vrtouchData.TgtMaid.ActiveSlotNo))
					{
						flag = true;
						touch_pos = key;
						this.m_Touch_Mgr.FrameEnd();
						break;
					}
				}
				if (flag)
				{
					break;
				}
			}
			if (flag)
			{
				if (!vrtouchData.IsTouch)
				{
					if (vrtouchData.ActiveCroutine != null)
					{
						base.StopCoroutine(vrtouchData.ActiveCroutine);
					}
					this.Touch_Voice_Play(touch_pos, vrtouchData);
					vrtouchData.TouchCount++;
				}
				vrtouchData.IsTouch = true;
			}
			else
			{
				vrtouchData.IsTouch = false;
			}
		}
		this.m_Touch_Mgr.FrameEnd();
	}

	private ScriptManagerFast.VRTouchKagManagerFast m_VR_Kag_Mng_Fast;

	private BaseKagManager m_Base_Kag_Mng;

	private KeyValuePair<string, VRTouchComm.Region>[] m_RegionPair = new KeyValuePair<string, VRTouchComm.Region>[]
	{
		new KeyValuePair<string, VRTouchComm.Region>("頭", VRTouchComm.Region.Head),
		new KeyValuePair<string, VRTouchComm.Region>("胸", VRTouchComm.Region.Bust),
		new KeyValuePair<string, VRTouchComm.Region>("尻", VRTouchComm.Region.Hip),
		new KeyValuePair<string, VRTouchComm.Region>("手", VRTouchComm.Region.Hand)
	};

	private List<KeyValuePair<VRTouchMgr.ETouchPos, VRTouchComm.Region>> m_TouchPosPair = new List<KeyValuePair<VRTouchMgr.ETouchPos, VRTouchComm.Region>>
	{
		new KeyValuePair<VRTouchMgr.ETouchPos, VRTouchComm.Region>(VRTouchMgr.ETouchPos.頭頂部, VRTouchComm.Region.Head),
		new KeyValuePair<VRTouchMgr.ETouchPos, VRTouchComm.Region>(VRTouchMgr.ETouchPos.胸, VRTouchComm.Region.Bust),
		new KeyValuePair<VRTouchMgr.ETouchPos, VRTouchComm.Region>(VRTouchMgr.ETouchPos.お尻, VRTouchComm.Region.Hip),
		new KeyValuePair<VRTouchMgr.ETouchPos, VRTouchComm.Region>(VRTouchMgr.ETouchPos.手, VRTouchComm.Region.Hand)
	};

	private Dictionary<Maid, VRTouchComm.VRTouchData> m_MaidTouchDataPair = new Dictionary<Maid, VRTouchComm.VRTouchData>();

	private VRTouchMgr m_Touch_Mgr;

	private VRTouchComm.VRTouchData m_CurSettingTouchData;

	[SerializeField]
	[Header("ボイス再生時のインターバル")]
	private float m_IntervalTime = 20f;

	public enum Type
	{
		WAIT,
		TOUCH,
		AFTER
	}

	public enum Region
	{
		Non,
		Head,
		Bust,
		Hip = 4,
		Hand = 8
	}

	private struct Script_Data
	{
		public int nMaidNo;

		public string strType;

		public int nNum;

		public string strVoice;

		public string[] strRegion;

		public string strFace;

		public string strFaceBlend;
	}

	private class VRTouchData
	{
		public VRTouchData(Maid maid)
		{
			this.TgtMaid = maid;
			this.FirstFace = maid.ActiveFace;
		}

		public List<VRTouchComm.Script_Data> Get_Data(VRTouchComm.Type type)
		{
			List<VRTouchComm.Script_Data> result = new List<VRTouchComm.Script_Data>();
			switch (type)
			{
			case VRTouchComm.Type.WAIT:
				result = (from e in this.scriptDataList
				where e.strType == "wait"
				select e).ToList<VRTouchComm.Script_Data>();
				break;
			case VRTouchComm.Type.TOUCH:
				result = (from e in this.scriptDataList
				where e.strType == "touch"
				select e).ToList<VRTouchComm.Script_Data>();
				break;
			case VRTouchComm.Type.AFTER:
				result = (from e in this.scriptDataList
				where e.strType == "after"
				select e).ToList<VRTouchComm.Script_Data>();
				break;
			}
			return result;
		}

		public List<VRTouchComm.Script_Data> scriptDataList = new List<VRTouchComm.Script_Data>();

		public bool IsTouch;

		public string FirstFace = string.Empty;

		public int TouchCount;

		public Maid TgtMaid;

		public IEnumerator ActiveCroutine;

		public float VoiceInterval;
	}
}
