﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace Arugula.Prototypical
{
    [ExecuteInEditMode]
    public class GravityWell : MonoBehaviour
    {
        public static List<GravityWell> Instances = new List<GravityWell>();

        public enum Mode { TwoD, ThreeD };
        public Mode mode = Mode.ThreeD;
        public LayerMask mask;
        public QueryTriggerInteraction queryTriggers = QueryTriggerInteraction.Ignore;
        public float range = 3;
        public float power = 5;
        public int maximumObjects = 256;
        public float maximumForce = 500;

        Collider[] objects3D;
        int objectCount;

        private void Awake()
        {
            objects3D = new Collider[maximumObjects];
        }

        private void OnEnable()
        {
            Instances.Add(this);
        }

        private void OnDisable()
        {
            Instances.Remove(this);
        }

        private void FixedUpdate()
        {
            if (mode != Mode.ThreeD || Application.isPlaying == false)
                return;

            objectCount = Physics.OverlapSphereNonAlloc(transform.position, range, objects3D, mask, queryTriggers);

            for (int i = 0; i < objectCount; i++)
            {
                var rb = objects3D[i].attachedRigidbody;
                if (rb == null || rb.isKinematic || rb.gameObject == gameObject)
                    continue;

                rb.AddForce(GetForce(rb.position), ForceMode.Acceleration);
            }
        }

        public Vector3 GetForce(Vector3 position)
        {
            float dist = Vector3.Distance(transform.position, position);
            if (dist > range)
                return Vector3.zero;

            return (transform.position - position).normalized * power * (1f / (dist * dist));
        }

        //[ContextMenu("Calc Trajectory")]
        //Vector3[] CalcTrajectory(Rigidbody rb)
        //{
        //    if (rb == null || rb == this.GetComponent<Rigidbody>())
        //        return null;

        //    Vector3[] points = new Vector3[1500];
        //    Vector3 velocity = Vector3.zero;
        //    if (rb.GetComponent<InitialVelocity>() != null)
        //        velocity = rb.GetComponent<InitialVelocity>().Velocity3D;


        //    float step = 0.01f;
        //    //float t = 0;
        //    Vector3 pos = rb.position;
        //    for (int i = 0; i < 1500; i++)
        //    {
        //        points[i] = pos;

        //        pos += velocity * step;
        //        velocity += GetForce(pos) * step;

        //    }

        //    return points;
        //}

        private void OnDrawGizmos()
        {

            //if(Application.isPlaying == false)
            //{
            //    var colliders = Physics.OverlapSphere(transform.position, range, mask, queryTriggers);
            //    foreach (var c in colliders)
            //    {
            //        var rb = c.attachedRigidbody;
            //        if (rb != null && rb.isKinematic == false)
            //        {
            //            var line = CalcTrajectory(rb);
            //            Handles.DrawPolyLine(line);
            //        }
            //    }
            //}


            Gizmos.color = new Color(0, 0, 0, 0.15f);
            Gizmos.DrawSphere(transform.position, range);

        }
    }
}
