﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.EditorTools;

namespace Arugula
{
    [EditorTool("Grid Tool", null)]
    public class GridTool : EditorTool
    {
        static Grid grid;
        static bool restoreTool;

        [SerializeField] Texture2D m_ToolIcon;
        GUIContent m_IconContent;

        void OnEnable()
        {
            SceneView.duringSceneGui += DuringSceneGUI;

            m_IconContent = new GUIContent()
            {
                image = m_ToolIcon,
                text = "Grid Tool",
                tooltip = "Grid Tool"
            };

            if (grid == null)
                grid = FindObjectOfType<Grid>();

            if (grid != null && restoreTool)
            {
                if (Selection.activeTransform != null)
                    EditorTools.SetActiveTool<GridTool>();
            }
        }

        private void DuringSceneGUI(SceneView obj)
        {
            var ev = Event.current;

            if (ev.isKey)
            {
                if (ev.type == EventType.KeyDown)
                {
                    if (ev.keyCode == KeyCode.W && ev.shift)
                    {
                        EditorTools.SetActiveTool(this);
                    }
                }
            }

            restoreTool = EditorTools.activeToolType == typeof(GridTool);
        }

        private void OnDisable()
        {
            SceneView.duringSceneGui -= DuringSceneGUI;
        }

        public override GUIContent toolbarIcon
        {
            get { return m_IconContent; }
        }

        public override bool IsAvailable()
        {
            return grid != null;
        }

        public override void OnToolGUI(EditorWindow window)
        {
            base.OnToolGUI(window);

            if (grid == null)
            {
                grid = FindObjectOfType<Grid>();
                return;
            }


            var transforms = Selection.GetTransforms(SelectionMode.TopLevel);
            bool dirty = false;
            Vector3 tOrigin = Vector3.zero;
            Vector3 delta = Vector3.zero;

            if (transforms.Length > 0)
            {

                var t = Selection.activeTransform;
                tOrigin = t.position;

                EditorGUI.BeginChangeCheck();
                {
                    Handles.color = Color.blue;
                    var pos = Handles.Slider(t.position, grid.transform.forward);
                    if (EditorGUI.EndChangeCheck())
                    {
                        t.position = pos;
                    }
                }

                EditorGUI.BeginChangeCheck();
                {
                    Handles.color = Color.Lerp(Color.red, Color.blue, 0.5f);

                    var pos = Handles.Slider(t.position, Quaternion.Euler(0, 60, 0) * grid.transform.forward);
                    if (EditorGUI.EndChangeCheck())
                        t.position = pos;
                }

                EditorGUI.BeginChangeCheck();
                {
                    Handles.color = Color.red;

                    var pos = Handles.Slider(t.position, Quaternion.Euler(0, 120, 0) * grid.transform.forward);
                    if (EditorGUI.EndChangeCheck())
                        t.position = pos;
                }

                EditorGUI.BeginChangeCheck();
                {
                    Handles.color = Color.green;

                    var pos = Handles.Slider(t.position, grid.transform.up, HandleUtility.GetHandleSize(t.position) * 0.5f, Handles.ArrowHandleCap, 0);
                    if (EditorGUI.EndChangeCheck())
                        t.position = pos;
                }

                EditorGUI.BeginChangeCheck();
                {
                    Handles.color = Color.gray;

                    var pos = Handles.Slider2D(
                        t.position,
                        grid.transform.up,
                        grid.transform.forward,
                        grid.transform.right,
                        HandleUtility.GetHandleSize(t.position) * 0.25f,
                        Handles.CircleHandleCap, 0);

                    //var pos = Handles.Slider(t.position, grid.transform.up);
                    if (EditorGUI.EndChangeCheck())
                        t.position = pos;
                }

                if (t.position != tOrigin)
                {
                    delta = t.position - tOrigin;
                    dirty = true;
                }

                Handles.Label(t.position, grid.WorldToCell(t.position).ToString());
            }

            if (dirty)
            {
                Undo.RegisterCompleteObjectUndo(transforms, "gridmove");
                foreach (var t in transforms)
                {
                    var cellPos = grid.WorldToCell(t == Selection.activeTransform ? t.position : (t.position + delta));
                    var snappedPos = grid.CellToWorld(cellPos);
                    t.position = snappedPos;
                    EditorUtility.SetDirty(t);
                    //Handles.Label(t.position, $"{cellPos.x}, {cellPos.y}, {cellPos.z}");
                }
            }

            foreach (var t in transforms)
            {
                var cellPos = grid.WorldToCell(t.position);

                Handles.color = Color.white;
                if (cellPos.z > 0)
                {
                    for (int i = 0; i < cellPos.z; i++)
                    {
                        var pos = grid.CellToWorld(new Vector3Int(cellPos.x, cellPos.y, i));
                        Handles.DotHandleCap(0, pos, Quaternion.identity, HandleUtility.GetHandleSize(pos) * 0.015f, EventType.Repaint);
                    }
                }
                else
                {
                    for (int i = 0; i > cellPos.z; i--)
                    {
                        var pos = grid.CellToWorld(new Vector3Int(cellPos.x, cellPos.y, i));
                        Handles.DotHandleCap(0, pos, Quaternion.identity, HandleUtility.GetHandleSize(pos) * 0.015f, EventType.Repaint);
                    }
                }
            }

        }


    }
}