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

public class KupaCtrl
{
	public KupaCtrl(TBody body0, TMorph morph)
	{
		this.m_morph = morph;
		this.m_body0 = body0;
		for (int i = 0; i < this.m_morphId.Length; i++)
		{
			this.m_morphMozaId[i] = (this.m_morphId[i] = -1);
		}
		if (this.m_morph.hash.ContainsKey("openkupa"))
		{
			this.m_morphId[0] = (int)this.m_morph.hash["openkupa"];
		}
		if (this.m_morph.hash.ContainsKey("openvagina"))
		{
			this.m_morphId[1] = (int)this.m_morph.hash["openvagina"];
		}
		if (this.m_morph.hash.ContainsKey("openanal"))
		{
			this.m_morphId[2] = (int)this.m_morph.hash["openanal"];
		}
		if (this.m_morph.hash.ContainsKey("chinkos"))
		{
			this.m_morphId[3] = (int)this.m_morph.hash["chinkos"];
		}
		if (this.m_morph.hash.ContainsKey("chinkof"))
		{
			this.m_morphId[4] = (int)this.m_morph.hash["chinkof"];
		}
		Transform transform = CMT.SearchObjName(body0.m_trBones, "_IK_vagina", true);
		if (transform != null)
		{
			this.m_trans[0] = transform;
		}
		Transform transform2 = CMT.SearchObjName(body0.m_trBones, "_IK_vagina", true);
		if (transform2 != null)
		{
			this.m_trans[1] = transform2;
		}
		Transform transform3 = CMT.SearchObjName(body0.m_trBones, "_IK_anal", true);
		if (transform3 != null)
		{
			this.m_trans[2] = transform3;
		}
	}

	public void AddMozaMorph(TMorph morphMoza)
	{
		this.m_morphMoza = morphMoza;
		if (this.m_morphMoza.hash.ContainsKey("openkupa"))
		{
			this.m_morphMozaId[0] = (int)this.m_morphMoza.hash["openkupa"];
		}
		if (this.m_morphMoza.hash.ContainsKey("openvagina"))
		{
			this.m_morphMozaId[1] = (int)this.m_morphMoza.hash["openvagina"];
		}
		if (this.m_morphMoza.hash.ContainsKey("openanal"))
		{
			this.m_morphMozaId[2] = (int)this.m_morphMoza.hash["openanal"];
		}
		if (this.m_morphMoza.hash.ContainsKey("chinkos"))
		{
			this.m_morphMozaId[3] = (int)this.m_morphMoza.hash["chinkos"];
		}
		if (this.m_morphMoza.hash.ContainsKey("chinkof"))
		{
			this.m_morphMozaId[4] = (int)this.m_morphMoza.hash["chinkof"];
		}
	}

	public void FinishAll()
	{
		for (int i = 0; i < this.m_taskList.Count; i++)
		{
			this.m_taskList[i].ForceFinish();
		}
		this.m_taskList.Clear();
		this.m_morph.FixBlendValues();
		if (this.m_morphMoza != null)
		{
			this.m_morphMoza.FixBlendValues();
		}
	}

	public void ResetAll()
	{
		for (int i = 0; i < this.m_morphId.Length; i++)
		{
			if (this.m_morphId[i] != -1)
			{
				this.m_morph.SetBlendValues(this.m_morphId[i], 0f);
				if (this.m_morphMoza != null && this.m_morphMozaId[i] != -1)
				{
					this.m_morphMoza.SetBlendValues(this.m_morphMozaId[i], 0f);
				}
			}
		}
		this.m_taskList.Clear();
		this.m_morph.FixBlendValues();
		if (this.m_morphMoza != null)
		{
			this.m_morphMoza.FixBlendValues();
		}
	}

	public void KupaStart(KupaCtrl.OPEN reg, float trans, float delay, float val, bool add = false)
	{
		if (!add)
		{
			this.Finish(reg);
		}
		if (this.m_morphId[(int)reg] != -1)
		{
			this.m_taskList.Add(new KupaCtrl.Task(this.m_morph, this.m_morphMoza, this.m_morphId[(int)reg], this.m_morphMozaId[(int)reg], reg, trans, delay, val));
		}
	}

	public void AutoKupaStart(KupaCtrl.OPEN reg, Maid targetMan, float val, float speedIn, float sppedOut, float outVal, float lengthRatio)
	{
		if (this.m_body0.boMAN)
		{
			Debug.LogError("AutoKupaStartはMaid専用。");
			return;
		}
		this.m_taskList.RemoveAll((KupaCtrl.ATask i) => i.m_reg == reg);
		Transform trBones = targetMan.body0.m_trBones;
		NDebug.Assert(trBones != null, "男の体が未だロードされていません。");
		Transform transform = CMT.SearchObjName(trBones, "chinkoCenter", true);
		if (transform != null)
		{
			Transform[] array = new Transform[3];
			array[0] = transform.Find("chinko1");
			array[1] = array[0].Find("chinko2");
			array[2] = array[1].Find("chinko_nub");
			if (this.m_morphId[(int)reg] != -1)
			{
				this.m_taskList.Add(new KupaCtrl.Target(this.m_morph, this.m_morphMoza, this.m_morphId[(int)reg], this.m_morphMozaId[(int)reg], reg, this.m_trans[(int)reg], array, val, speedIn, sppedOut, outVal, lengthRatio));
			}
		}
	}

	public void AutoKariStart(KupaCtrl.OPEN reg, KupaCtrl.TARGET target, Maid targetMaid, float destVal, float speedIn, float sppedOut, float outVal, float lengthRatio)
	{
		if (!this.m_body0.boMAN)
		{
			Debug.LogError("AutoKariStartはMan専用。");
			return;
		}
		this.m_taskList.RemoveAll((KupaCtrl.ATask i) => i.m_reg == reg);
		Transform trBones = this.m_body0.m_trBones;
		NDebug.Assert(trBones != null, "男の体が未だロードされていません。");
		Transform transform = CMT.SearchObjName(trBones, "chinkoCenter", true);
		if (transform != null)
		{
			Transform[] array = new Transform[3];
			array[0] = transform.Find("chinko1");
			array[1] = array[0].Find("chinko2");
			array[2] = array[1].Find("chinko_nub");
			Transform src = CMT.SearchObjName(targetMaid.body0.m_trBones, this.m_targetBoneName[(int)target], true);
			if (this.m_morphId[(int)reg] != -1)
			{
				this.m_taskList.Add(new KupaCtrl.Target(this.m_morph, this.m_morphMoza, this.m_morphId[(int)reg], this.m_morphMozaId[(int)reg], reg, src, array, destVal, speedIn, sppedOut, outVal, lengthRatio));
			}
		}
	}

	public void Finish(KupaCtrl.OPEN reg)
	{
		for (int j = 0; j < this.m_taskList.Count; j++)
		{
			KupaCtrl.ATask atask = this.m_taskList[j];
			if (atask.m_reg == reg)
			{
				atask.ForceFinish();
			}
		}
		this.m_taskList.RemoveAll((KupaCtrl.ATask i) => i.m_reg == reg);
	}

	public void Reset(KupaCtrl.OPEN reg)
	{
		if (this.m_morphId[(int)reg] != -1)
		{
			this.m_morph.SetBlendValues(this.m_morphId[(int)reg], 0f);
			if (this.m_morphMoza != null && this.m_morphMozaId[(int)reg] != -1)
			{
				this.m_morphMoza.SetBlendValues(this.m_morphMozaId[(int)reg], 0f);
			}
		}
		this.m_taskList.RemoveAll((KupaCtrl.ATask i) => i.m_reg == reg);
	}

	public void SelfUpdate()
	{
		bool flag = false;
		for (int j = 0; j < this.m_taskList.Count; j++)
		{
			flag |= (this.m_taskList[j].IsVisible() && this.m_taskList[j].SelfUpdate());
		}
		if (flag)
		{
			this.m_morph.FixBlendValues();
			if (this.m_morphMoza != null)
			{
				this.m_morphMoza.FixBlendValues();
			}
		}
		this.m_taskList.RemoveAll((KupaCtrl.ATask i) => !i.IsVisible());
	}

	public TMorph m_morph;

	public TMorph m_morphMoza;

	public TBody m_body0;

	private int[] m_morphId = new int[5];

	private int[] m_morphMozaId = new int[5];

	private string[] m_targetBoneName = new string[]
	{
		"Mouth",
		"_IK_vagina",
		"_IK_anal"
	};

	private List<KupaCtrl.ATask> m_taskList = new List<KupaCtrl.ATask>();

	private Transform[] m_trans = new Transform[5];

	public enum OPEN
	{
		KUPA,
		VAGINA,
		ANAL,
		CHINKOS,
		CHINKOF,
		MAX
	}

	public enum TARGET
	{
		MOUTH,
		VAGINA,
		ANAL,
		MAX
	}

	private abstract class ATask
	{
		public ATask(TMorph morph, TMorph morphMoza, int id, int mozaId, KupaCtrl.OPEN reg)
		{
			this.m_morph = morph;
			this.m_morphMoza = morphMoza;
			this.m_id = id;
			this.m_mozaId = mozaId;
			this.m_reg = reg;
		}

		public virtual bool IsVisible()
		{
			return this.m_visible;
		}

		public abstract void ForceFinish();

		public virtual void ForceReset()
		{
			this.m_morph.SetBlendValues(this.m_id, 0f);
			if (this.m_morphMoza != null && this.m_mozaId != -1)
			{
				this.m_morphMoza.SetBlendValues(this.m_mozaId, 0f);
			}
			this.m_visible = false;
		}

		public abstract bool SelfUpdate();

		protected TMorph m_morph;

		protected TMorph m_morphMoza;

		protected int m_id;

		protected int m_mozaId;

		public KupaCtrl.OPEN m_reg;

		protected bool m_visible;
	}

	private class Task : KupaCtrl.ATask
	{
		public Task(TMorph morph, TMorph morphMoza, int id, int mozaId, KupaCtrl.OPEN reg, float trans, float delay, float val) : base(morph, morphMoza, id, mozaId, reg)
		{
			this.m_transTime = trans;
			this.m_delayTime = delay;
			this.m_distVal = Mathf.Clamp01(val);
			this.m_startTime = Time.realtimeSinceStartup;
			this.m_visible = true;
			this.m_start = false;
			if (trans <= 0f && delay <= 0f)
			{
				this.ForceFinish();
				return;
			}
		}

		public override void ForceFinish()
		{
			this.m_morph.SetBlendValues(this.m_id, this.m_distVal);
			if (this.m_morphMoza != null && this.m_mozaId != -1)
			{
				this.m_morphMoza.SetBlendValues(this.m_mozaId, this.m_distVal);
			}
			this.m_visible = false;
		}

		public override bool SelfUpdate()
		{
			if (!this.m_visible)
			{
				return false;
			}
			float num = Time.realtimeSinceStartup - this.m_startTime;
			if (!this.m_start)
			{
				if (this.m_delayTime > num)
				{
					return false;
				}
				if (this.m_transTime <= 0f)
				{
					this.ForceFinish();
					return true;
				}
				this.m_start = true;
				this.m_startVal = this.m_morph.GetBlendValues(this.m_id);
				this.m_subVal = this.m_distVal - this.m_startVal;
			}
			float num2 = num - this.m_delayTime;
			float num3 = 1f;
			if (0f < this.m_transTime)
			{
				num3 = this.m_startVal + this.m_subVal * (num2 / this.m_transTime);
			}
			if (this.m_transTime <= num2 || this.m_distVal == num3)
			{
				num3 = this.m_distVal;
				this.m_visible = false;
			}
			float num4 = Mathf.Clamp01(num3);
			if (num4 != this.m_morph.GetBlendValues(this.m_id))
			{
				this.m_morph.SetBlendValues(this.m_id, num4);
				if (this.m_morphMoza != null && this.m_mozaId != -1)
				{
					this.m_morphMoza.SetBlendValues(this.m_mozaId, num4);
				}
				return true;
			}
			return false;
		}

		private float m_transTime;

		private float m_delayTime;

		private float m_distVal;

		private float m_startTime;

		private float m_startTime2;

		private float m_startVal;

		private float m_subVal;

		private bool m_start;
	}

	private class Target : KupaCtrl.ATask
	{
		public Target(TMorph morph, TMorph morphMoza, int id, int mozaId, KupaCtrl.OPEN reg, Transform src, Transform[] target, float val = 1f, float speedIn = 5f, float sppedOut = 5f, float outVal = 0f, float lengthRatio = 1f) : base(morph, morphMoza, id, mozaId, reg)
		{
			this.m_src = src;
			this.m_target = target;
			this.m_distVal = val;
			this.m_sppedIn = speedIn;
			this.m_sppedNow = speedIn;
			this.m_sppedOut = sppedOut;
			this.m_outVal = outVal;
			this.m_lengthRatio = lengthRatio;
			this.m_nowRatio = this.m_morph.GetBlendValues(this.m_id);
			this.m_visible = true;
		}

		public override void ForceFinish()
		{
			this.m_visible = false;
		}

		public override void ForceReset()
		{
			this.m_morph.SetBlendValues(this.m_id, 0f);
			if (this.m_morphMoza != null && this.m_mozaId != -1)
			{
				this.m_morphMoza.SetBlendValues(this.m_mozaId, 0f);
			}
			this.m_visible = false;
		}

		public override bool SelfUpdate()
		{
			if (!this.m_visible)
			{
				return false;
			}
			Vector3 lhs = this.m_src.TransformVector(-Vector3.forward);
			float num = Vector3.Distance(this.m_src.position, this.m_target[this.m_target.Length - 1].position);
			float num2 = float.PositiveInfinity;
			int num3 = 0;
			Vector3 zero = Vector3.zero;
			float num4 = 0f;
			float num5 = 0f;
			for (int i = 1; i < this.m_target.Length; i++)
			{
				num5 += Vector3.Distance(this.m_target[i - 1].position, this.m_target[i].position);
			}
			float num6 = num5 * this.m_lengthRatio;
			float num7 = 0f;
			for (int j = 1; j < this.m_target.Length; j++)
			{
				Vector3 position = this.m_target[j - 1].position;
				Vector3 position2 = this.m_src.position;
				this.m_segTemp.s = position;
				this.m_segTemp.e = this.m_target[j].position;
				this.m_segTemp.v = this.m_segTemp.e - this.m_segTemp.s;
				bool flag = false;
				float num8;
				num7 += (num8 = Vector3.Distance(this.m_segTemp.s, this.m_segTemp.e));
				if (num6 < num7)
				{
					this.m_segTemp.e = this.m_segTemp.s + this.m_segTemp.v.normalized * (num8 - (num7 - num6));
					flag = true;
				}
				Vector3 vector;
				float num10;
				float num9 = MathCM.calcPointSegmentDist(ref position2, ref this.m_segTemp, out vector, out num10);
				if (num9 < num2)
				{
					num2 = num9;
					num3 = j;
					num4 = num10;
				}
				if (flag)
				{
					break;
				}
			}
			float num11 = this.m_outNowVal;
			if (num2 <= this.m_hitDistance)
			{
				num11 = this.m_distVal;
				if (0f < num4 && num4 < 1f)
				{
					this.m_outNowVal = this.m_outVal;
				}
			}
			else if (num2 <= this.m_apprDistance)
			{
				num11 = this.m_outNowVal + (this.m_distVal - this.m_outNowVal) * (1f - (num2 - this.m_hitDistance) / (this.m_apprDistance - this.m_hitDistance));
				Vector3 normalized = (this.m_target[num3 - 1].position - this.m_target[num3].position).normalized;
				float num12 = Vector3.Dot(lhs, normalized);
				if ((double)num12 <= 0.0)
				{
					num11 = 0f;
				}
				else if (num12 <= 0.7f)
				{
					num11 *= num12 / 0.7f;
				}
			}
			if (num11 - this.m_befRatio > 0f)
			{
				this.m_sppedNow = this.m_sppedIn;
			}
			else if (num11 - this.m_befRatio < 0f)
			{
				this.m_sppedNow = this.m_sppedOut;
			}
			this.m_nowRatio += (num11 - this.m_nowRatio) * (Time.deltaTime * this.m_sppedNow);
			this.m_befRatio = num11;
			float num13 = Mathf.Clamp01(this.m_nowRatio);
			if (num13 != this.m_morph.GetBlendValues(this.m_id))
			{
				this.m_morph.SetBlendValues(this.m_id, num13);
				if (this.m_morphMoza != null && this.m_mozaId != -1)
				{
					this.m_morphMoza.SetBlendValues(this.m_mozaId, num13);
				}
				return true;
			}
			return false;
		}

		public Transform m_src;

		public Transform[] m_target;

		private float m_distVal = 1f;

		private float m_outVal;

		private float m_apprDistance = 0.025f;

		private float m_hitDistance = 0.02f;

		private float m_sppedIn = 5f;

		private float m_sppedOut = 5f;

		private float m_sppedNow = 5f;

		private float m_outNowVal;

		private float m_nowRatio;

		private float m_befRatio;

		private float m_lengthRatio = 1f;

		private MathCM.Segment m_segTemp = default(MathCM.Segment);
	}
}
