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

namespace Framework.Debugging
{
    [Serializable]
    public class Draw
    {
        static public bool active = true; // Determines whether debug drawing is on or off
        static public bool textsActive = true;
        //static public List<DbugText> texts = new List<DbugText>(); // An array of texts given to the SubGlobal to draw

        /// <summary>
        /// Turns dbug drawing on.
        /// </summary>
        static public void On()
        {
            Draw.active = true;
        }

        /// <summary>
        /// Turns dbug drawing off.
        /// </summary>
        static public void Off()
        {
            Draw.active = false;
        }

        /// <summary>
        /// Turns dbug text drawing on.
        /// </summary>
        static public void TextOn()
        {
            Draw.textsActive = true;
        }

        /// <summary>
        /// Turns dbug text drawing off.
        /// </summary>
        static public void TextOff()
        {
            Draw.textsActive = false;
        }

        /// <summary>
        /// Draws a line.
        /// </summary>
        /// <param name="origin">The origin.</param>
        /// <param name="target">The target.</param>
        /// <param name="color">The color.</param>
        static public void Line(Vector3 origin, Vector3 target, Color color)
        {
            if (Draw.active)
            {
                Debug.DrawLine(origin, target, color);
            }
        }

        /// <summary>
        /// Draws a cube.
        /// </summary>
        /// <param name="position">The position.</param>
        /// <param name="size">The size.</param>
        /// <param name="color">The color.</param>
        static public void Cube(Vector3 position, float size, Color color)
        {
            Cube(position, new Quaternion(0, 0, 0, 0), size, color);
        }

        /// <summary>
        /// Draws a cube.
        /// </summary>
        /// <param name="position">The position.</param>
        /// <param name="rotation">The rotation.</param>
        /// <param name="size">The size.</param>
        /// <param name="color">The color.</param>
        static public void Cube(Vector3 position, Quaternion rotation, float size, Color color)
        {
            if (Draw.active)
            {
                Vector3[] corner = new Vector3[8];
                corner[0] = position + rotation * new Vector3(0, 0, 0);
                corner[1] = position + rotation * new Vector3(size, 0, 0);
                corner[2] = position + rotation * new Vector3(0, 0, size);
                corner[3] = position + rotation * new Vector3(size, 0, size);
                corner[4] = position + rotation * new Vector3(0, size, 0);
                corner[5] = position + rotation * new Vector3(size, size, 0);
                corner[6] = position + rotation * new Vector3(0, size, size);
                corner[7] = position + rotation * new Vector3(size, size, size);
                Debug.DrawLine(corner[0], corner[1], color);
                Debug.DrawLine(corner[0], corner[2], color);
                Debug.DrawLine(corner[2], corner[3], color);
                Debug.DrawLine(corner[1], corner[3], color);
                Debug.DrawLine(corner[0], corner[4], color);
                Debug.DrawLine(corner[1], corner[5], color);
                Debug.DrawLine(corner[2], corner[6], color);
                Debug.DrawLine(corner[3], corner[7], color);
                Debug.DrawLine(corner[4], corner[5], color);
                Debug.DrawLine(corner[4], corner[6], color);
                Debug.DrawLine(corner[6], corner[7], color);
                Debug.DrawLine(corner[5], corner[7], color);
            }
        }

        /// <summary>
        /// Draws a cuboid.
        /// </summary>
        /// <param name="min">The minimum.</param>
        /// <param name="max">The maximum.</param>
        /// <param name="rotation">The rotation.</param>
        /// <param name="color">The color.</param>
        static public void Cuboid(Vector3 min, Vector3 max, Quaternion rotation, Color color)
        {
            if (Draw.active)
            {
                Vector3[] corner = new Vector3[8];
                corner[0] = min + rotation * new Vector3(0, 0, 0);
                corner[1] = min + rotation * new Vector3(max.x, 0, 0);
                corner[2] = min + rotation * new Vector3(0, 0, max.z);
                corner[3] = min + rotation * new Vector3(max.x, 0, max.z);
                corner[4] = min + rotation * new Vector3(0, max.y, 0);
                corner[5] = min + rotation * new Vector3(max.x, max.y, 0);
                corner[6] = min + rotation * new Vector3(0, max.y, max.z);
                corner[7] = min + rotation * max;
                Debug.DrawLine(corner[0], corner[1], color);
                Debug.DrawLine(corner[0], corner[2], color);
                Debug.DrawLine(corner[2], corner[3], color);
                Debug.DrawLine(corner[1], corner[3], color);
                Debug.DrawLine(corner[0], corner[4], color);
                Debug.DrawLine(corner[1], corner[5], color);
                Debug.DrawLine(corner[2], corner[6], color);
                Debug.DrawLine(corner[3], corner[7], color);
                Debug.DrawLine(corner[4], corner[5], color);
                Debug.DrawLine(corner[4], corner[6], color);
                Debug.DrawLine(corner[6], corner[7], color);
                Debug.DrawLine(corner[5], corner[7], color);
            }
        }

        /// <summary>
        /// Draws text.
        /// </summary>
        /// <param name="position">The position.</param>
        /// <param name="str">The string.</param>
        static public void Text(Vector3 position, string str)
        {
            if (Draw.active)
            {
                //GameObject cameraInterface = GameObject.Find("CameraInterface");
                //Vector3 screenPosition = cameraInterface.camera.WorldToScreenPoint(position);
                int i = FindTextsIndex(str);
                if (i == -1)
                {
                    //Draw.texts.Add(new DbugText(str, screenPosition));
                }
                else
                {
                    //Draw.texts[i].SetPosition(screenPosition);
                    //Draw.texts[i].Activate();
                }
            }
        }

        /// <summary>
        /// Finds an index of a text.
        /// </summary>
        /// <param name="str">The string.</param>
        /// <returns></returns>
        static private int FindTextsIndex(string str)
        {
            //for (int i = 0; i < Draw.texts.Count; i++)
            //{
                //if (str == Draw.texts[i].name)
               // {
                //    return i;
                //}
           // }
            return -1;
        }

        /// <summary>
        /// Draws a mesh.
        /// </summary>
        /// <param name="vertices">The vertices.</param>
        /// <param name="triangles">The triangles.</param>
        /// <param name="position">The position.</param>
        /// <param name="scale">The scale.</param>
        static public void Mesh(Vector3[] vertices, int[] triangles, Vector3 position, float scale)
        {
            if (Draw.active)
            {
                for (int i = 0; i < triangles.Length / 3; i++)
                {
                    int tri = i * 3;
                    Debug.DrawLine(position + vertices[triangles[tri]] * scale, position + vertices[triangles[tri + 1]] * scale, Color.blue);
                    Debug.DrawLine(position + vertices[triangles[tri + 1]] * scale, position + vertices[triangles[tri + 2]] * scale, Color.blue);
                    Debug.DrawLine(position + vertices[triangles[tri + 2]] * scale, position + vertices[triangles[tri]] * scale, Color.blue);

                    Arrow(position + vertices[triangles[tri]] * scale, Vector3.Lerp(position + vertices[triangles[tri]] * scale, position + vertices[triangles[tri + 1]] * scale, 0.75f), Color.blue);
                    Arrow(position + vertices[triangles[tri + 1]] * scale, Vector3.Lerp(position + vertices[triangles[tri + 1]] * scale, position + vertices[triangles[tri + 2]] * scale, 0.75f), Color.blue);
                    Arrow(position + vertices[triangles[tri + 2]] * scale, Vector3.Lerp(position + vertices[triangles[tri + 2]] * scale, position + vertices[triangles[tri]] * scale, 0.75f), Color.blue);
                }

                for (int i = 0; i < vertices.Length; i++)
                {
                    Text(position + vertices[i] * scale, "V" + i);
                }
            }
        }

        /// <summary>
        /// Draws an arrow.
        /// </summary>
        /// <param name="origin">The origin.</param>
        /// <param name="target">The target.</param>
        /// <param name="color">The color.</param>
        static public void Arrow(Vector3 origin, Vector3 target, Color color)
        {
            if (Draw.active)
            {
                Debug.DrawLine(origin, target, color);
                Debug.DrawLine(target, target + (Quaternion.Euler(30, 0, 0) * Vector3.Normalize(origin - target) * (Vector3.Distance(origin, target)) * 0.2f), color);
            }
        }

        /// <summary>
        /// Draws an axis.
        /// </summary>
        /// <param name="position">The position.</param>
        static public void Axis(Vector3 position)
        {
            if (Draw.active)
            {
                Debug.DrawLine(position, position + (Vector3.forward * 0.25f), Color.blue);
                Debug.DrawLine(position, position + (Vector3.up * 0.25f), Color.green);
                Debug.DrawLine(position, position + (Vector3.right * 0.25f), Color.red);
            }
        }

        /// <summary>
        /// Draws an axis.
        /// </summary>
        /// <param name="position">The position.</param>
        /// <param name="color">The color.</param>
        static public void Axis(Vector3 position, Color color)
        {
            if (Draw.active)
            {
                Debug.DrawLine(position, position + (Vector3.forward * 0.25f), color);
                Debug.DrawLine(position, position + (Vector3.up * 0.25f), color);
                Debug.DrawLine(position, position + (Vector3.right * 0.25f), color);
            }
        }

        /// <summary>
        /// Draws a check box.
        /// </summary>
        /// <param name="position">The position.</param>
        /// <param name="state">if set to <c>true</c> [state].</param>
        /// <param name="color">The color.</param>
        static public void CheckBox(Vector3 position, bool state, Color color)
        {
            if (Draw.active)
            {
                Vector3 direction = Vector3.right;
                Vector3 upperLeft = position + (Vector3.up * 0.2f);
                Vector3 lowerLeft = position;
                Vector3 upperRight = position + (Vector3.up * 0.2f) - (direction * 0.2f);
                Vector3 lowerRight = position - (direction * 0.2f);
                // Top Bar
                Debug.DrawLine(upperLeft, upperRight, color);
                // Upright Left
                Debug.DrawLine(lowerLeft, upperLeft, color);
                // Bottom Bar
                Debug.DrawLine(lowerLeft, lowerRight, color);
                // Upright Right
                Debug.DrawLine(lowerRight, upperRight, color);

                if (state == true) Debug.DrawLine(lowerLeft, upperRight, color);
            }
        }
    }
}