using System;
using Leap.Unity.Attributes;
using UnityEngine;

namespace Leap.Unity
{
	public abstract class AbstractHoldDetector : Detector
	{
		protected abstract void ensureUpToDate();

		public IHandModel HandModel
		{
			get
			{
				return this._handModel;
			}
			set
			{
				this._handModel = value;
			}
		}

		protected virtual void Awake()
		{
			if (base.GetComponent<IHandModel>() != null && this.ControlsTransform)
			{
				Debug.LogWarning("Detector should not be control the IHandModel's transform. Either attach it to its own transform or set ControlsTransform to false.");
			}
			if (this._handModel == null)
			{
				this._handModel = base.GetComponentInParent<IHandModel>();
				if (this._handModel == null)
				{
					Debug.LogWarning("The HandModel field of Detector was unassigned and the detector has been disabled.");
					base.enabled = false;
				}
			}
		}

		protected virtual void Update()
		{
			this.ensureUpToDate();
		}

		public virtual bool IsHolding
		{
			get
			{
				this.ensureUpToDate();
				return base.IsActive;
			}
		}

		public virtual bool DidChangeFromLastFrame
		{
			get
			{
				this.ensureUpToDate();
				return this._didChange;
			}
		}

		public virtual bool DidStartHold
		{
			get
			{
				this.ensureUpToDate();
				return this.DidChangeFromLastFrame && this.IsHolding;
			}
		}

		public virtual bool DidRelease
		{
			get
			{
				this.ensureUpToDate();
				return this.DidChangeFromLastFrame && !this.IsHolding;
			}
		}

		public float LastHoldTime
		{
			get
			{
				this.ensureUpToDate();
				return this._lastHoldTime;
			}
		}

		public float LastReleaseTime
		{
			get
			{
				this.ensureUpToDate();
				return this._lastReleaseTime;
			}
		}

		public Vector3 Position
		{
			get
			{
				this.ensureUpToDate();
				return this._position;
			}
		}

		public Vector3 LastActivePosition
		{
			get
			{
				return this._lastPosition;
			}
		}

		public Quaternion Rotation
		{
			get
			{
				this.ensureUpToDate();
				return this._rotation;
			}
		}

		public Quaternion LastActiveRotation
		{
			get
			{
				return this._lastRotation;
			}
		}

		public Vector3 Direction
		{
			get
			{
				return this._direction;
			}
		}

		public Vector3 LastActiveDirection
		{
			get
			{
				return this._lastDirection;
			}
		}

		public Vector3 Normal
		{
			get
			{
				return this._normal;
			}
		}

		public Vector3 LastActiveNormal
		{
			get
			{
				return this._lastNormal;
			}
		}

		public float Distance
		{
			get
			{
				return this._distance;
			}
		}

		public float LastActiveDistance
		{
			get
			{
				return this._lastDistance;
			}
		}

		protected virtual void changeState(bool shouldBeActive)
		{
			bool isActive = base.IsActive;
			if (shouldBeActive)
			{
				this._lastHoldTime = Time.time;
				this.Activate();
			}
			else
			{
				this._lastReleaseTime = Time.time;
				this.Deactivate();
			}
			if (isActive != base.IsActive)
			{
				this._didChange = true;
			}
		}

		[AutoFind(AutoFindLocations.Parents)]
		[SerializeField]
		protected IHandModel _handModel;

		public bool ControlsTransform = true;

		protected int _lastUpdateFrame = -1;

		protected bool _didChange;

		protected Vector3 _position;

		protected Quaternion _rotation;

		protected Vector3 _direction = Vector3.forward;

		protected Vector3 _normal = Vector3.up;

		protected float _distance;

		protected float _lastHoldTime;

		protected float _lastReleaseTime;

		protected Vector3 _lastPosition = Vector3.zero;

		protected Quaternion _lastRotation = Quaternion.identity;

		protected Vector3 _lastDirection = Vector3.forward;

		protected Vector3 _lastNormal = Vector3.up;

		protected float _lastDistance = 1f;
	}
}
