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

public class FingerBlend : MonoBehaviour
{
	public void Awake()
	{
		if (FingerBlend.open_dic == null)
		{
			FingerBlend.open_dic = FingerBlend.ReadFingerBoneDataFromrResource("ScenePhotoMode/binary/finger_template_open");
			FingerBlend.close_dic = FingerBlend.ReadFingerBoneDataFromrResource("ScenePhotoMode/binary/finger_template_close");
			FingerBlend.fist_dic = FingerBlend.ReadFingerBoneDataFromrResource("ScenePhotoMode/binary/finger_template_fist1");
		}
	}

	public void Start()
	{
	}

	public void SetIKManager(IKManager setting_ik_mgr)
	{
		if (this.ik_mgr != null)
		{
			return;
		}
		this.ik_mgr = setting_ik_mgr;
		this.right_arm_finger = new FingerBlend.ArmFinger(this, true);
		this.left_arm_finger = new FingerBlend.ArmFinger(this, false);
		this.right_leg_finger = new FingerBlend.LegFinger(this, true);
		this.left_leg_finger = new FingerBlend.LegFinger(this, false);
		this.right_arm_finger.enabled = true;
	}

	public static Dictionary<IKManager.BoneType, Quaternion> ReadFingerBoneDataFromrResource(string path)
	{
		TextAsset textAsset = Resources.Load(path) as TextAsset;
		if (textAsset == null)
		{
			return null;
		}
		return FingerBlend.ReadFingerBoneData(textAsset.bytes);
	}

	public static Dictionary<IKManager.BoneType, Quaternion> ReadFingerBoneData(byte[] data_byte)
	{
		if (data_byte == null)
		{
			return null;
		}
		Dictionary<IKManager.BoneType, Quaternion> dictionary = new Dictionary<IKManager.BoneType, Quaternion>();
		using (MemoryStream memoryStream = new MemoryStream(data_byte))
		{
			using (BinaryReader binaryReader = new BinaryReader(memoryStream))
			{
				string a = binaryReader.ReadString();
				if (a != "CM3D2_IK_FingerBlend")
				{
					return null;
				}
				int num = binaryReader.ReadInt32();
				int num2 = binaryReader.ReadInt32();
				for (int i = 0; i < num2; i++)
				{
					int num3 = binaryReader.ReadInt32();
					if (num == 1000)
					{
						num3 += 5;
					}
					Vector4 vector;
					vector.x = binaryReader.ReadSingle();
					vector.y = binaryReader.ReadSingle();
					vector.z = binaryReader.ReadSingle();
					vector.w = binaryReader.ReadSingle();
					dictionary.Add((IKManager.BoneType)num3, new Quaternion(vector.x, vector.y, vector.z, vector.w));
				}
			}
		}
		return dictionary;
	}

	public static byte[] GetFingerBoneData(IKManager ik_mgr)
	{
		Dictionary<int, Quaternion> dictionary = new Dictionary<int, Quaternion>();
		for (int i = 42; i <= 56; i++)
		{
			dictionary.Add(i, ik_mgr.GetBone((IKManager.BoneType)i).transform.localRotation);
		}
		for (int j = 27; j <= 41; j++)
		{
			dictionary.Add(j, ik_mgr.GetBone((IKManager.BoneType)j).transform.localRotation);
		}
		for (int k = 63; k <= 68; k++)
		{
			dictionary.Add(k, ik_mgr.GetBone((IKManager.BoneType)k).transform.localRotation);
		}
		for (int l = 57; l <= 62; l++)
		{
			dictionary.Add(l, ik_mgr.GetBone((IKManager.BoneType)l).transform.localRotation);
		}
		MemoryStream memoryStream = new MemoryStream();
		BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
		binaryWriter.Write("CM3D2_IK_FingerBlend");
		binaryWriter.Write(1000);
		binaryWriter.Write(dictionary.Count);
		foreach (KeyValuePair<int, Quaternion> keyValuePair in dictionary)
		{
			binaryWriter.Write(keyValuePair.Key);
			Quaternion value = keyValuePair.Value;
			binaryWriter.Write(value.x);
			binaryWriter.Write(value.y);
			binaryWriter.Write(value.z);
			binaryWriter.Write(value.w);
		}
		binaryWriter.Close();
		memoryStream.Close();
		byte[] result = memoryStream.ToArray();
		memoryStream.Dispose();
		return result;
	}

	public Maid maid
	{
		get
		{
			return (!(this.ik_mgr != null)) ? null : this.ik_mgr.maid;
		}
	}

	public IKManager ik_mgr { get; private set; }

	public FingerBlend.ArmFinger right_arm_finger { get; private set; }

	public FingerBlend.ArmFinger left_arm_finger { get; private set; }

	public FingerBlend.LegFinger right_leg_finger { get; private set; }

	public FingerBlend.LegFinger left_leg_finger { get; private set; }

	public static Dictionary<IKManager.BoneType, Quaternion> open_dic;

	public static Dictionary<IKManager.BoneType, Quaternion> close_dic;

	public static Dictionary<IKManager.BoneType, Quaternion> fist_dic;

	public class BaseFinger
	{
		public BaseFinger(FingerBlend finger_blend)
		{
			this.finger_blend_ = finger_blend;
		}

		public virtual void Apply()
		{
			if (!this.enabled)
			{
				return;
			}
			for (int i = 0; i < this.value_array_.Length; i++)
			{
				float lock_value_open;
				float lock_value_fist;
				if (!this.value_array_[i].is_lock)
				{
					lock_value_open = this.value_open_;
					lock_value_fist = this.value_fist_;
				}
				else
				{
					lock_value_open = this.value_array_[i].lock_value_open;
					lock_value_fist = this.value_array_[i].lock_value_fist;
				}
				foreach (IKManager.BoneType boneType in this.value_array_[i].bone)
				{
					this.finger_blend_.ik_mgr.GetBone(boneType).transform.localRotation = Quaternion.Lerp(Quaternion.Lerp(FingerBlend.close_dic[boneType], FingerBlend.open_dic[boneType], lock_value_open), FingerBlend.fist_dic[boneType], lock_value_fist);
				}
			}
		}

		public void SetBinary(byte[] data_byte, bool mirroring = false)
		{
			using (MemoryStream memoryStream = new MemoryStream(data_byte))
			{
				using (BinaryReader binaryReader = new BinaryReader(memoryStream))
				{
					for (int i = 0; i < this.value_array_.Length; i++)
					{
						IKManager.BoneType[] bone = this.value_array_[i].bone;
						for (int j = 0; j < bone.Length; j++)
						{
							Vector4 vector;
							vector.x = binaryReader.ReadSingle();
							vector.y = binaryReader.ReadSingle();
							vector.z = binaryReader.ReadSingle();
							vector.w = binaryReader.ReadSingle();
							if (mirroring)
							{
								vector.x *= -1f;
								vector.y *= -1f;
							}
							this.finger_blend_.ik_mgr.GetBone(bone[j]).transform.localRotation = new Quaternion(vector.x, vector.y, vector.z, vector.w);
						}
					}
				}
			}
		}

		public byte[] GetBinary()
		{
			byte[] result = null;
			using (MemoryStream memoryStream = new MemoryStream())
			{
				using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream))
				{
					for (int i = 0; i < this.value_array_.Length; i++)
					{
						IKManager.BoneType[] bone = this.value_array_[i].bone;
						for (int j = 0; j < bone.Length; j++)
						{
							Quaternion localRotation = this.finger_blend_.ik_mgr.GetBone(bone[j]).transform.localRotation;
							binaryWriter.Write(localRotation.x);
							binaryWriter.Write(localRotation.y);
							binaryWriter.Write(localRotation.z);
							binaryWriter.Write(localRotation.w);
						}
					}
					result = memoryStream.ToArray();
				}
			}
			return result;
		}

		public float value_open
		{
			get
			{
				return this.value_open_;
			}
			set
			{
				this.value_open_ = value;
				this.Apply();
			}
		}

		public float value_fist
		{
			get
			{
				return this.value_fist_;
			}
			set
			{
				this.value_fist_ = value;
				this.Apply();
			}
		}

		public bool enabled
		{
			get
			{
				return this.enabled_;
			}
			set
			{
				this.enabled_ = value;
				this.Apply();
			}
		}

		public void LockSingleItemValue(bool set_lock, int value_no, Vector2 value)
		{
			this.value_array_[value_no].is_lock = set_lock;
			this.value_array_[value_no].lock_value_open = value.x;
			this.value_array_[value_no].lock_value_fist = value.y;
		}

		public void LockSingleItem(bool set_lock, int value_no)
		{
			this.value_array_[value_no].is_lock = set_lock;
			this.value_array_[value_no].lock_value_open = this.value_open_;
			this.value_array_[value_no].lock_value_fist = this.value_fist_;
		}

		protected float value_open_;

		protected float value_fist_;

		protected bool enabled_;

		protected FingerBlend.BaseFinger.value_set[] value_array_;

		protected FingerBlend finger_blend_;

		protected struct value_set
		{
			public bool is_lock;

			public float lock_value_open;

			public float lock_value_fist;

			public IKManager.BoneType[] bone;
		}
	}

	public class ArmFinger : FingerBlend.BaseFinger
	{
		public ArmFinger(FingerBlend finger_blend, bool is_right) : base(finger_blend)
		{
			this.value_array_ = new FingerBlend.BaseFinger.value_set[5];
			for (int i = 0; i < this.value_array_.Length; i++)
			{
				this.value_array_[i].bone = new IKManager.BoneType[3];
				for (int j = 0; j < this.value_array_[i].bone.Length; j++)
				{
					if (is_right)
					{
						this.value_array_[i].bone[j] = i * this.value_array_[i].bone.Length + IKManager.BoneType.Finger0_Root_R + j;
					}
					else
					{
						this.value_array_[i].bone[j] = i * this.value_array_[i].bone.Length + IKManager.BoneType.Finger0_Root_L + j;
					}
				}
			}
		}

		public bool lock_enabled0
		{
			get
			{
				return this.value_array_[0].is_lock;
			}
			set
			{
				base.LockSingleItem(value, 0);
			}
		}

		public Vector2 lock_value0
		{
			get
			{
				return new Vector2(this.value_array_[0].lock_value_open, this.value_array_[0].lock_value_fist);
			}
			set
			{
				if (this.lock_enabled0)
				{
					base.LockSingleItemValue(true, 0, value);
				}
			}
		}

		public bool lock_enabled1
		{
			get
			{
				return this.value_array_[1].is_lock;
			}
			set
			{
				base.LockSingleItem(value, 1);
			}
		}

		public Vector2 lock_value1
		{
			get
			{
				return new Vector2(this.value_array_[1].lock_value_open, this.value_array_[1].lock_value_fist);
			}
			set
			{
				if (this.lock_enabled1)
				{
					base.LockSingleItemValue(true, 1, value);
				}
			}
		}

		public bool lock_enabled2
		{
			get
			{
				return this.value_array_[2].is_lock;
			}
			set
			{
				base.LockSingleItem(value, 2);
			}
		}

		public Vector2 lock_value2
		{
			get
			{
				return new Vector2(this.value_array_[2].lock_value_open, this.value_array_[2].lock_value_fist);
			}
			set
			{
				if (this.lock_enabled2)
				{
					base.LockSingleItemValue(true, 2, value);
				}
			}
		}

		public bool lock_enabled3
		{
			get
			{
				return this.value_array_[3].is_lock;
			}
			set
			{
				base.LockSingleItem(value, 3);
			}
		}

		public Vector2 lock_value3
		{
			get
			{
				return new Vector2(this.value_array_[3].lock_value_open, this.value_array_[3].lock_value_fist);
			}
			set
			{
				if (this.lock_enabled3)
				{
					base.LockSingleItemValue(true, 3, value);
				}
			}
		}

		public bool lock_enabled4
		{
			get
			{
				return this.value_array_[4].is_lock;
			}
			set
			{
				base.LockSingleItem(value, 4);
			}
		}

		public Vector2 lock_value4
		{
			get
			{
				return new Vector2(this.value_array_[4].lock_value_open, this.value_array_[4].lock_value_fist);
			}
			set
			{
				if (this.lock_enabled4)
				{
					base.LockSingleItemValue(true, 4, value);
				}
			}
		}
	}

	public class LegFinger : FingerBlend.BaseFinger
	{
		public LegFinger(FingerBlend finger_blend, bool is_right) : base(finger_blend)
		{
			this.value_array_ = new FingerBlend.BaseFinger.value_set[3];
			for (int i = 0; i < this.value_array_.Length; i++)
			{
				this.value_array_[i].bone = new IKManager.BoneType[2];
				for (int j = 0; j < this.value_array_[i].bone.Length; j++)
				{
					if (is_right)
					{
						this.value_array_[i].bone[j] = i * this.value_array_[i].bone.Length + IKManager.BoneType.Toe0_Root_R + j;
					}
					else
					{
						this.value_array_[i].bone[j] = i * this.value_array_[i].bone.Length + IKManager.BoneType.Toe0_Root_L + j;
					}
				}
			}
		}

		public bool lock_enabled0
		{
			get
			{
				return this.value_array_[0].is_lock;
			}
			set
			{
				base.LockSingleItem(value, 0);
			}
		}

		public Vector2 lock_value0
		{
			get
			{
				return new Vector2(this.value_array_[0].lock_value_open, this.value_array_[0].lock_value_fist);
			}
			set
			{
				if (this.lock_enabled0)
				{
					base.LockSingleItemValue(true, 0, value);
				}
			}
		}

		public bool lock_enabled1
		{
			get
			{
				return this.value_array_[1].is_lock;
			}
			set
			{
				base.LockSingleItem(value, 1);
			}
		}

		public Vector2 lock_value1
		{
			get
			{
				return new Vector2(this.value_array_[1].lock_value_open, this.value_array_[1].lock_value_fist);
			}
			set
			{
				if (this.lock_enabled1)
				{
					base.LockSingleItemValue(true, 1, value);
				}
			}
		}

		public bool lock_enabled2
		{
			get
			{
				return this.value_array_[2].is_lock;
			}
			set
			{
				base.LockSingleItem(value, 2);
			}
		}

		public Vector2 lock_value2
		{
			get
			{
				return new Vector2(this.value_array_[2].lock_value_open, this.value_array_[2].lock_value_fist);
			}
			set
			{
				if (this.lock_enabled2)
				{
					base.LockSingleItemValue(true, 2, value);
				}
			}
		}
	}
}
