﻿using UnityEngine;
using System.Collections;

using Augumenta;

/**
 * HoverPoseHandler detects if the selected hand pose is over the
 * game object.
 *
 * OnHoverEnter is called when the hand pose starts overlapping the game object.
 * OnHoverLeave is called when the hand pose stops overlapping the game object.
 */
public class HoverPoseHandler : PoseHandler {
	// flag indicating if this object is currently hoverred
	public bool hoverred { get; private set; }
	// event id that is hoverring this object
	private uint hoverEventId = 0;
	[Tooltip("Length of the hand reach")]
	public float lengthHandReach = 2f;

	public override void Start () {
		base.Start ();
		hoverred = false;
	}

	public override void OnPose (PoseEvent e, bool isNew, Vector3 pos, Quaternion rot) {
		// only handle events from the current hovering event
		// or if there is no current hovering event
		if (hoverEventId != 0 && hoverEventId != e.id)
			return;
		if (CheckIfPoseHitsObject(pos)) {
			if (!hoverred) {
				// event rect has entered the object rect
				hoverred = true;
				hoverEventId = e.id;
				OnHoverEnter ();
			}
		} else {
			if (hoverred) {
				// event rect has left the object rect
				hoverred = false;
				hoverEventId = 0;
				OnHoverLeave ();
			}
		}
	}
	public override void OnPoseLost (PoseEvent e) {
		if (hoverred && hoverEventId == e.id) {
			OnHoverLeave ();
			hoverred = false;
			hoverEventId = 0;
		}
	}

	/**
	 * Hover enter callback
	 *
	 * This is called when detection rectangle starts
	 * to overlap with the object rectangle.
	 */
	public virtual void OnHoverEnter() {
		Debug.Log ("OnHoverEnter");
	}

	/**
	 * Hover leave callback
	 *
	 * This is called when detection rectangle stops
	 * to overlap with the object rectangle.
	 */
	public virtual void OnHoverLeave() {
		Debug.Log ("OnHoverLeave");
	}
	/**
	 * Check if the Object is between the event center and camera center
	 *
	 * @param e the PoseEvent detected
	 * @param obj the Object that we want to test
	 * @param distance the maximum distance the ray should check for collision
	 * @return true if hit
	 */
	private bool CheckIfPoseHitsObject(Vector3 pose) {
		RaycastHit hitInfo;
		Debug.DrawRay(this.referential.transform.position, pose-this.referential.transform.position, Color.green);
		// Check if the object is hit by the raycast of the event
		if(Physics.Raycast(this.referential.transform.position, pose-this.referential.transform.position, out hitInfo, this.lengthHandReach, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal)) {
			if (this.gameObject == hitInfo.transform.gameObject) {
				Debug.Log ("Raycast hit!");
				return true;
			}
		}
		return false;
	}
}
