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

public class WallMaker : MonoBehaviour, IPointerClickHandler
{
    private int mode = 0;

    const int IDLE = 0;
    const int PICKING_FIRST_POINT = 1;
    const int DRAGGING_SECOND_POINT = 2;

    public GameObject gameWorld;
    public GameObject objectFactory;

    private Vector2 initialPoint;

    static Texture2D _rectTexture;
    public static Texture2D PointTexture
    {
        get
        {
            if (_rectTexture == null)
            {
                _rectTexture = new Texture2D(1, 1);
                _rectTexture.SetPixel(0, 0, Color.blue);
                _rectTexture.Apply();
            }

            return _rectTexture;
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (mode == PICKING_FIRST_POINT)
        {
            if (Input.GetMouseButtonDown(0))
            {
                mode = DRAGGING_SECOND_POINT;
                initialPoint = Input.mousePosition;
            }
        }
        else if (mode == DRAGGING_SECOND_POINT)
        {
            if (Input.GetMouseButtonUp(0))
            {
                if (rayCastEventSystemFromMouse().Count == 0)
                {
                    GameObject obj = Instantiate(objectFactory);
                    obj.transform.SetParent(gameWorld.transform);

                    LevelWall levelWall = obj.GetComponent<LevelWall>();
                    if (levelWall != null)
                    {
                        levelWall.position1 = initialPoint;
                        levelWall.position2 = Input.mousePosition;
                    }
                }

                mode = IDLE;
            }
        }
    }

    public void OnGUI()
    {
        if (mode == DRAGGING_SECOND_POINT)
        {
            DrawLine(FlipY(initialPoint), FlipY(Input.mousePosition), 5);
        }
    }

    public Vector2 FlipY(Vector2 vec)
    {
        Vector3 world = Camera.main.ScreenToWorldPoint(vec);
        world.y = -world.y;
        return Camera.main.WorldToScreenPoint(world);
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        if (mode == IDLE)
        {
            mode = PICKING_FIRST_POINT;
        }
    }

    private List<RaycastResult> rayCastEventSystemFromMouse()
    {
        PointerEventData ped = new PointerEventData(EventSystem.current);
        List<RaycastResult> raycastResults = new List<RaycastResult>();
        ped.position = Input.mousePosition;

        EventSystem.current.RaycastAll(ped, raycastResults);
        return raycastResults;
    }

    public static Rect GetScreenRect(Vector3 screenPosition1, Vector3 screenPosition2)
    {
        // Move origin from bottom left to top left
        screenPosition1.y = Screen.height - screenPosition1.y;
        screenPosition2.y = Screen.height - screenPosition2.y;
        // Calculate corners
        var topLeft = Vector3.Min(screenPosition1, screenPosition2);
        var bottomRight = Vector3.Max(screenPosition1, screenPosition2);
        // Create Rect
        return Rect.MinMaxRect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
    }

    public void DrawScreenRectBorder(Rect rect, float thickness, Color color)
    {
        // Top
        DrawScreenRect(new Rect(rect.xMin, rect.yMin, rect.width, thickness), color);
        // Left
        DrawScreenRect(new Rect(rect.xMin, rect.yMin, thickness, rect.height), color);
        // Right
        DrawScreenRect(new Rect(rect.xMax - thickness, rect.yMin, thickness, rect.height), color);
        // Bottom
        DrawScreenRect(new Rect(rect.xMin, rect.yMax - thickness, rect.width, thickness), color);
    }

    public void DrawScreenRect(Rect rect, Color color)
    {
        GUI.color = color;
        GUI.DrawTexture(rect, PointTexture);
        GUI.color = Color.white;
    }

    private void DrawLine(Vector2 start, Vector2 end, int width)
    {
        Vector2 d = end - start;

        if (d.SqrMagnitude() < 0.01)
        {
            return;
        }

        float a = Mathf.Rad2Deg * Mathf.Atan(d.y / d.x);
        if (d.x < 0)
            a += 180;

        int width2 = (int)Mathf.Ceil(width / 2);

        GUIUtility.RotateAroundPivot(a, start);
        GUI.DrawTexture(new Rect(start.x, start.y - width2, d.magnitude, width), PointTexture);
        GUIUtility.RotateAroundPivot(-a, start);
    }
}
