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

public class DrawScript : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
    public DrawShape ArrowPrefab;
    public DrawShape TextPrefab;
    DrawPaintbrush PaintbrushPrefab;
    public DrawShape TargetPrefab;

    private RectTransform rectTransform_;

    Vector2 posMin;
    Vector2 posMax;

    private List<GameObject> drawShapeList_ = new List<GameObject>();
    private List<DrawShape> allShapesRedo_ = new List<DrawShape>();

    public void Clear()
    {
        foreach (GameObject obj in drawShapeList_)
        {
            Destroy(obj);
        }
        drawShapeList_.Clear();
        PaintbrushPrefab.Clear();
    }

    void Start ()
    {
        rectTransform_ = GetComponent<RectTransform>();
        print("rectTransform_ " + rectTransform_.gameObject.name);
        PaintbrushPrefab  = gameObject.GetComponentsInChildren<DrawPaintbrush>(true)[0];
        posMin = rectTransform_.TransformPoint(new Vector2(0, 0));
        posMax = rectTransform_.TransformPoint(new Vector2(rectTransform_.rect.width - 1, rectTransform_.rect.height - 1));
    }

    void Update ()
    {
        var mousePosition = Input.mousePosition;
        if (mousePosition.x > posMin.x &&
            mousePosition.x < posMax.x &&
            mousePosition.y > posMin.y &&
            mousePosition.y < posMax.y)
        {
            var canUpdateShape = CurrentShapeToDraw != null && IsDrawingShape;

            if (canUpdateShape)
            {
                UpdateShapeVertex(Input.mousePosition);
            }
        }
    }

    private DrawShape CurrentShapeToDraw { get; set; }
    private bool IsDrawingShape { get; set; }

    public void OnPointerDown(PointerEventData eventData)
    {
        StartDraw(Input.mousePosition);
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        StopDraw(Input.mousePosition);
    }

    public enum DRAW_MODE
    {
        NO_DRAW,
        PAINTBRUSH,
        TEXT,
        ARROW,
        TARGET
    };
    public DRAW_MODE DrawMode
    {
        set { drawMode_ = value; }
    }

    private void StartDraw(Vector2 position)
    {
        GameObject go;
        switch (drawMode_)
        {
            case DRAW_MODE.ARROW:
                CurrentShapeToDraw = Instantiate(ArrowPrefab);
                CurrentShapeToDraw.name = "Shape " + _allShapes.Count;
                CurrentShapeToDraw.transform.SetParent(transform);
                go = GameObject.Find(CurrentShapeToDraw.name);
                drawShapeList_.Add(go);
                break;

            case DRAW_MODE.TEXT:
                CurrentShapeToDraw = Instantiate(TextPrefab);
                CurrentShapeToDraw.name = "Shape " + _allShapes.Count;
                CurrentShapeToDraw.transform.SetParent(transform);
                go = GameObject.Find(CurrentShapeToDraw.name);
                drawShapeList_.Add(go);
                break;

            case DRAW_MODE.TARGET:
                CurrentShapeToDraw = Instantiate(TargetPrefab);
                CurrentShapeToDraw.name = "Shape " + _allShapes.Count;
                CurrentShapeToDraw.transform.SetParent(transform);
                go = GameObject.Find(CurrentShapeToDraw.name);
                drawShapeList_.Add(go);
                break;

            case DRAW_MODE.PAINTBRUSH:
                CurrentShapeToDraw = PaintbrushPrefab;
                break;

            case DRAW_MODE.NO_DRAW:
                return;
        }

        CurrentShapeToDraw.StartDraw(position);

        IsDrawingShape = true;

        _allShapes.Add(CurrentShapeToDraw);
    }

    public void Undo()
    {
        var last = _allShapes.Last();
        last.gameObject.SetActive(false);
        print("_allShapes " + _allShapes.Count);
        _allShapes.RemoveRange(_allShapes.Count - 1, 1);
        allShapesRedo_.Add(last);
        print("_allShapes " + _allShapes.Count);
    }

    private void StopDraw(Vector2 position)
    {
        if (CurrentShapeToDraw != null)
        {
            CurrentShapeToDraw.StopDraw(position);
            CurrentShapeToDraw = null;
        }
    }

    private void UpdateShapeVertex(Vector2 position)
    {
        if (CurrentShapeToDraw == null)
        {
            return;
        }

        CurrentShapeToDraw.UpdateShape(position);
    }

    DRAW_MODE drawMode_;

    private List<DrawShape> _allShapes = new List<DrawShape>();
}