using System;
using UnityEngine;

namespace Leap.Unity
{
	public abstract class FingerModel : MonoBehaviour
	{
		public void SetLeapHand(Hand hand)
		{
			this.hand_ = hand;
			if (this.hand_ != null)
			{
				this.finger_ = hand.Fingers[(int)this.fingerType];
			}
		}

		public Hand GetLeapHand()
		{
			return this.hand_;
		}

		public Finger GetLeapFinger()
		{
			return this.finger_;
		}

		public virtual void InitFinger()
		{
			this.UpdateFinger();
		}

		public abstract void UpdateFinger();

		public Vector3 GetTipPosition()
		{
			if (this.finger_ != null)
			{
				return this.finger_.Bone(Bone.BoneType.TYPE_DISTAL).NextJoint.ToVector3();
			}
			if (this.bones[3] && this.joints[1])
			{
				return 2f * this.bones[3].position - this.joints[1].position;
			}
			return Vector3.zero;
		}

		public Vector3 GetJointPosition(int joint)
		{
			if (joint >= 4)
			{
				return this.GetTipPosition();
			}
			if (this.finger_ != null)
			{
				return this.finger_.Bone((Bone.BoneType)joint).PrevJoint.ToVector3();
			}
			if (this.joints[joint])
			{
				return this.joints[joint].position;
			}
			return Vector3.zero;
		}

		public Ray GetRay()
		{
			Ray result = new Ray(this.GetTipPosition(), this.GetBoneDirection(3));
			return result;
		}

		public Vector3 GetBoneCenter(int bone_type)
		{
			if (this.finger_ != null)
			{
				Bone bone = this.finger_.Bone((Bone.BoneType)bone_type);
				return bone.Center.ToVector3();
			}
			if (this.bones[bone_type])
			{
				return this.bones[bone_type].position;
			}
			return Vector3.zero;
		}

		public Vector3 GetBoneDirection(int bone_type)
		{
			if (this.finger_ != null)
			{
				return (this.GetJointPosition(bone_type + 1) - this.GetJointPosition(bone_type)).normalized;
			}
			if (this.bones[bone_type])
			{
				return this.bones[bone_type].forward;
			}
			return Vector3.forward;
		}

		public Quaternion GetBoneRotation(int bone_type)
		{
			if (this.finger_ != null)
			{
				return this.finger_.Bone((Bone.BoneType)bone_type).Rotation.ToQuaternion();
			}
			if (this.bones[bone_type])
			{
				return this.bones[bone_type].rotation;
			}
			return Quaternion.identity;
		}

		public float GetBoneLength(int bone_type)
		{
			return this.finger_.Bone((Bone.BoneType)bone_type).Length;
		}

		public float GetBoneWidth(int bone_type)
		{
			return this.finger_.Bone((Bone.BoneType)bone_type).Width;
		}

		public float GetFingerJointStretchMecanim(int joint_type)
		{
			Quaternion quaternion = Quaternion.identity;
			if (this.finger_ != null)
			{
				quaternion = Quaternion.Inverse(this.finger_.Bone((Bone.BoneType)joint_type).Rotation.ToQuaternion()) * this.finger_.Bone(joint_type + Bone.BoneType.TYPE_PROXIMAL).Rotation.ToQuaternion();
			}
			else if (this.bones[joint_type] && this.bones[joint_type + 1])
			{
				quaternion = Quaternion.Inverse(this.GetBoneRotation(joint_type)) * this.GetBoneRotation(joint_type + 1);
			}
			float num = -quaternion.eulerAngles.x;
			if (num <= -180f)
			{
				num += 360f;
			}
			return num;
		}

		public float GetFingerJointSpreadMecanim()
		{
			Quaternion quaternion = Quaternion.identity;
			if (this.finger_ != null)
			{
				quaternion = Quaternion.Inverse(this.finger_.Bone(Bone.BoneType.TYPE_METACARPAL).Rotation.ToQuaternion()) * this.finger_.Bone(Bone.BoneType.TYPE_PROXIMAL).Rotation.ToQuaternion();
			}
			else if (this.bones[0] && this.bones[1])
			{
				quaternion = Quaternion.Inverse(this.GetBoneRotation(0)) * this.GetBoneRotation(1);
			}
			float num = 0f;
			Finger.FingerType fingerType = this.fingerType;
			if (this.finger_ != null)
			{
				this.fingerType = this.finger_.Type;
			}
			if (fingerType == Finger.FingerType.TYPE_INDEX || fingerType == Finger.FingerType.TYPE_MIDDLE)
			{
				num = quaternion.eulerAngles.y;
				if (num > 180f)
				{
					num -= 360f;
				}
			}
			if (fingerType == Finger.FingerType.TYPE_THUMB || fingerType == Finger.FingerType.TYPE_RING || fingerType == Finger.FingerType.TYPE_PINKY)
			{
				num = -quaternion.eulerAngles.y;
				if (num <= -180f)
				{
					num += 360f;
				}
			}
			return num;
		}

		public const int NUM_BONES = 4;

		public const int NUM_JOINTS = 3;

		public Finger.FingerType fingerType = Finger.FingerType.TYPE_INDEX;

		public Transform[] bones = new Transform[4];

		public Transform[] joints = new Transform[3];

		protected Hand hand_;

		protected Finger finger_;
	}
}
