using UnityEngine;
using System.Collections;

public enum SliceType{ Line, Push, Pull}

public class Cursor : MonoBehaviour {
    public static Cursor Instance;

    private Vector2 place;
    private Vector2 lastPoint;
    private Transform orientation;
    private Transform border;
    private SpriteRenderer borderRenderer;
    private SpriteRenderer orientationRenderer;

    private bool started = false;
    private float strength = 0;
    private SliceType sliceType;
    private bool specialMoves = false;
    private bool ready = true;

    void Awake()
    {
        Instance = this;
        border = transform.FindChild("Border");
        orientation = transform.FindChild("Orientation");
        borderRenderer = border.GetComponent<SpriteRenderer>();
        orientationRenderer = orientation.GetComponent<SpriteRenderer>();
    }

    public void SetSpecialMoves(bool special)
    {
        specialMoves = special;
    }

    public void Reset()
    {
        ready = true;
        started = false;
        borderRenderer.color = new Color(1, 1, 1, 0);
        orientationRenderer.color = new Color(1, 1, 1, 0);
        strength = 0;
        Dot.Dots.ForEach((Dot dot) => { dot.CutEnd(); });
    }

    void Start()
    {
        ready = true;
        sliceType = SliceType.Line;
        borderRenderer.color = new Color(1, 1, 1, 0);
        orientationRenderer.color = new Color(1, 1, 1, 0);
        RandomSliceType();
    }

    public void RandomSliceType()
    {
        SetSliceType((SliceType)Random.Range(0, specialMoves ? 3 : 1));
    }

    private void SetSliceType(SliceType type)
    {
        if (sliceType != type)
        {
            sliceType = type;
            CanvasManager.Instance.SetSliceType(type);
            if (sliceType == SliceType.Line)
            {
                borderRenderer.enabled = true;
                orientationRenderer.enabled = true;
            }
            else
            {
                borderRenderer.enabled = false;
                orientationRenderer.enabled = false;
            }
        }
    }

    void Update()
    {
        if (started)
        {
            if (strength < 1)
            {
                strength = Mathf.Clamp(strength + Time.unscaledDeltaTime * 4, 0, 1);
                if (sliceType == SliceType.Line)
                {
                    borderRenderer.color = new Color(1, 1, 1, strength);
                    orientationRenderer.color = new Color(1, 1, 1, strength);
                    border.localScale = Vector3.one * (strength * 0.2f + 0.8f);
                }
            }
        }
        else
        {
            if (strength > 0)
            {
                strength = Mathf.Clamp(strength - (Time.unscaledDeltaTime * 0.5f + Time.deltaTime * 2), 0, 1);
                if (strength == 0 && ready == false)
                {
                    ready = true;
                    RandomSliceType();
                }
                if (sliceType == SliceType.Line)
                {
                    borderRenderer.color = new Color(1, 1, 1, strength);
                    orientationRenderer.color = new Color(1, 1, 1, strength);
                }

                Time.timeScale = 1 - strength;
            }
        }
    }

    public void Begin(Vector2 point)
    {
        if (started || strength > 0 || !ready)
        {
            return;
        }
        started = true;
        Time.timeScale = 0.1f;

        transform.position = place = lastPoint = point;
        transform.position += new Vector3(0, 0, -5);

        Dot.Dots.ForEach((Dot dot) => { dot.CutBegin(); });

        Drag(point);
    }

    public void Drag(Vector2 point)
    {
        if (!started)
        {
            return;
        }

        lastPoint = Vector2.Lerp(lastPoint, point, 0.2f);
        Vector2 diff = lastPoint - place;
        if ((sliceType == SliceType.Line) && (diff.magnitude > 2))
        {
            Slicer.Instance.SliceLine(diff);
            GameManager.Instance.Slice();
            Time.timeScale = 0f;
            strength = 1;
            End(lastPoint);
            ready = false;
            return;
        }


        switch (sliceType)
        {
            case SliceType.Line:
                orientation.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(diff.y, diff.x) / Mathf.PI * 180 + 90);
                orientation.localScale = new Vector3(0.4f, 0.2f + diff.magnitude * 0.5f, 1);
                Dot.Dots.ForEach((Dot dot) => { dot.CutLine(diff); });
                break;
            case SliceType.Push:
                Dot.Dots.ForEach((Dot dot) => { dot.CutPush(lastPoint); });
                break;
            case SliceType.Pull:
                Dot.Dots.ForEach((Dot dot) => { dot.CutPull(lastPoint); });
                break;
            default:
                break;
        }
    }

    public void End(Vector2 point)
    {
        if (!started)
        {
            return;
        }
        started = false;

        lastPoint = Vector2.Lerp(lastPoint, point, 0.2f);
        if (sliceType == SliceType.Push)
        {
            Slicer.Instance.SlicePush(lastPoint);
            Time.timeScale = 0f;
            strength = 1;
            GameManager.Instance.Slice();
            ready = false;
        } else if (sliceType == SliceType.Pull)
        {
            Slicer.Instance.SlicePull(lastPoint);
            Time.timeScale = 0f;
            strength = 1;
            GameManager.Instance.Slice();
            ready = false;
        }

        Dot.Dots.ForEach((Dot dot) => { dot.CutEnd(); });
    }
}
