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

namespace Leap.Unity
{
	public class LeapHandController : MonoBehaviour
	{
		public bool GraphicsEnabled
		{
			get
			{
				return this.graphicsEnabled;
			}
			set
			{
				this.graphicsEnabled = value;
			}
		}

		public bool PhysicsEnabled
		{
			get
			{
				return this.physicsEnabled;
			}
			set
			{
				this.physicsEnabled = value;
			}
		}

		private void OnDrawGizmos()
		{
			Gizmos.matrix = Matrix4x4.Scale(5f * Vector3.one);
			Gizmos.DrawIcon(base.transform.position, "leap_motion.png");
		}

		protected virtual void OnEnable()
		{
			this.provider = this.requireComponent<LeapProvider>();
			this.factory = this.requireComponent<HandFactory>();
			this.provider.OnUpdateFrame += this.OnUpdateFrame;
			this.provider.OnFixedFrame += this.OnFixedFrame;
		}

		protected virtual void OnDisable()
		{
			this.provider.OnUpdateFrame -= this.OnUpdateFrame;
			this.provider.OnFixedFrame -= this.OnFixedFrame;
		}

		protected virtual void OnUpdateFrame(Frame frame)
		{
			if (frame != null && this.graphicsEnabled)
			{
				this.UpdateHandRepresentations(this.graphicsReps, ModelType.Graphics, frame);
			}
		}

		protected virtual void OnFixedFrame(Frame frame)
		{
			if (frame != null && this.physicsEnabled)
			{
				this.UpdateHandRepresentations(this.physicsReps, ModelType.Physics, frame);
			}
		}

		protected virtual void UpdateHandRepresentations(Dictionary<int, HandRepresentation> all_hand_reps, ModelType modelType, Frame frame)
		{
			foreach (Hand hand in frame.Hands)
			{
				HandRepresentation handRepresentation;
				if (!all_hand_reps.TryGetValue(hand.Id, out handRepresentation))
				{
					handRepresentation = this.factory.MakeHandRepresentation(hand, modelType);
					if (handRepresentation != null)
					{
						all_hand_reps.Add(hand.Id, handRepresentation);
					}
				}
				if (handRepresentation != null)
				{
					handRepresentation.IsMarked = true;
					handRepresentation.UpdateRepresentation(hand);
					handRepresentation.LastUpdatedTime = (int)frame.Timestamp;
				}
			}
			HandRepresentation handRepresentation2 = null;
			foreach (KeyValuePair<int, HandRepresentation> keyValuePair in all_hand_reps)
			{
				if (keyValuePair.Value != null)
				{
					if (keyValuePair.Value.IsMarked)
					{
						keyValuePair.Value.IsMarked = false;
					}
					else
					{
						handRepresentation2 = keyValuePair.Value;
					}
				}
			}
			if (handRepresentation2 != null)
			{
				all_hand_reps.Remove(handRepresentation2.HandID);
				handRepresentation2.Finish();
			}
		}

		private T requireComponent<T>() where T : Component
		{
			T component = base.GetComponent<T>();
			if (component == null)
			{
				string name = typeof(T).Name;
				Debug.LogError(string.Concat(new string[]
				{
					"LeapHandController could not find a ",
					name,
					" and has been disabled.  Make sure there is a ",
					name,
					" on the same gameObject."
				}));
				base.enabled = false;
			}
			return component;
		}

		protected LeapProvider provider;

		protected HandFactory factory;

		protected Dictionary<int, HandRepresentation> graphicsReps = new Dictionary<int, HandRepresentation>();

		protected Dictionary<int, HandRepresentation> physicsReps = new Dictionary<int, HandRepresentation>();

		protected const float GIZMO_SCALE = 5f;

		protected bool graphicsEnabled = true;

		protected bool physicsEnabled = true;
	}
}
