using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Rigidbody))]
public class HoverEngineCSharp : MonoBehaviour 
{
    public float height = 0.5f;
    public float width = 3.0f;
    public float length = 3.2f;
    public float distToGround = 3.0f;
    public float springiness = 5.0f;
    public Vector3 offset = Vector3.zero;

    public float damping = 0.3f;

    //[System.NonSerialized]
    public bool isHovering = false;

    void Start()
    {
        //rigidbody.useGravity = false;
        rigidbody.interpolation = RigidbodyInterpolation.Interpolate;
        rigidbody.centerOfMass = Vector3.zero;
    }

    void FixedUpdate()
    {
        Vector3 flPoint = transform.TransformPoint(-width / 2, -height / 2, length / 2) + offset;
        Vector3 frPoint = transform.TransformPoint(width / 2, -height / 2, length / 2) + offset;
        Vector3 rlPoint = transform.TransformPoint(-width / 2, -height / 2, -length / 2) + offset;
        Vector3 rrPoint = transform.TransformPoint(width / 2, -height / 2, -length / 2) + offset;

        Vector3 upAxis = transform.TransformDirection(Vector3.up);

        RaycastHit flRayHit, frRayHit, rlRayHit, rrRayHit, centerRayHit;

        Physics.Raycast(flPoint, -upAxis, out flRayHit);
        Physics.Raycast(frPoint, -upAxis, out frRayHit);
        Physics.Raycast(rlPoint, -upAxis, out rlRayHit);
        Physics.Raycast(rrPoint, -upAxis, out rrRayHit);
        Physics.Raycast(transform.position, -upAxis, out centerRayHit);

        if (centerRayHit.distance > (distToGround + 1.0f))
            isHovering = false;
        else
            isHovering = true;

        Vector3 dampVec = new Vector3(0, damping, 0);

        Vector3 flDamp = transform.TransformDirection(Vector3.Scale(transform.InverseTransformDirection(rigidbody.GetPointVelocity(flPoint)), dampVec));
        Vector3 frDamp = transform.TransformDirection(Vector3.Scale(transform.InverseTransformDirection(rigidbody.GetPointVelocity(frPoint)), dampVec));
        Vector3 rlDamp = transform.TransformDirection(Vector3.Scale(transform.InverseTransformDirection(rigidbody.GetPointVelocity(rlPoint)), dampVec));
        Vector3 rrDamp = transform.TransformDirection(Vector3.Scale(transform.InverseTransformDirection(rigidbody.GetPointVelocity(rrPoint)), dampVec));

        Vector3 flLift = (upAxis * (distToGround - flRayHit.distance) * springiness) - flDamp;
        Vector3 frLift = (upAxis * (distToGround - frRayHit.distance) * springiness) - frDamp;
        Vector3 rlLift = (upAxis * (distToGround - rlRayHit.distance) * springiness) - rlDamp;
        Vector3 rrLift = (upAxis * (distToGround - rrRayHit.distance) * springiness) - rrDamp;

        if (isHovering)
        {
            rigidbody.AddForceAtPosition(flLift, flPoint);
            rigidbody.AddForceAtPosition(frLift, frPoint);
            rigidbody.AddForceAtPosition(rlLift, rlPoint);
            rigidbody.AddForceAtPosition(rrLift, rrPoint);
        }
    }

    void OnDrawGizmosSelected()
    {
        Vector3 flPoint = transform.TransformPoint(-width / 2, -height / 2, length / 2) + offset;
        Vector3 frPoint = transform.TransformPoint(width / 2, -height / 2, length / 2) + offset;
        Vector3 rlPoint = transform.TransformPoint(-width / 2, -height / 2, -length / 2) + offset;
        Vector3 rrPoint = transform.TransformPoint(width / 2, -height / 2, -length / 2) + offset;

        Gizmos.color = Color.cyan;
        Gizmos.DrawLine(flPoint, frPoint);
        Gizmos.DrawLine(frPoint, rrPoint);
        Gizmos.DrawLine(rrPoint, rlPoint);
        Gizmos.DrawLine(rlPoint, flPoint);

        Gizmos.DrawSphere(transform.position, 0.5f);
    }
}
