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

using ProtoTurtle.BitmapDrawing;

public class Painter : Singleton<Painter> {

    public int resolution;
    public MeshRenderer frameRenderer;
    public Text coords;
    public int BrushSize = 5;
    public float LineDensity = 1;
    public Color BrushColor = Color.black;
    public Color EraserColor = Color.white;
    Color currentBrushColor = Color.black;
    public Text EraserText;
    public bool Erasing;

    public Color[] allColors;

    Vector3 prevCoord = -Vector3.one;
    float right, left, top, bot;

    Texture2D currentTex;
    [HideInInspector] public Texture2D savedTex;
    public RawImage rawImg;

    const float aspectY = 1.4f;

    protected override void Awake()
    {
        base.Awake();

        frameRenderer.material.mainTexture = currentTex = new Texture2D(resolution, (int)(aspectY * resolution), TextureFormat.RGB24, false);
        currentTex.filterMode = FilterMode.Point;
        currentTex.wrapMode = TextureWrapMode.Clamp;
        currentTex.name = "current drawing";
        savedTex = new Texture2D(resolution, (int)(aspectY * resolution), TextureFormat.RGB24, false);
        savedTex.filterMode = FilterMode.Point;
        savedTex.wrapMode = TextureWrapMode.Clamp;
        savedTex.name = "final drawing";

        ClearTex();

        frameRenderer.GetComponent<ClickDetect>().action += SaveTex;

        enabled = false;
    }

    void Update () {
        UpdateMargins();

        if (Input.GetMouseButtonDown(0))
        {
            SoundEffectsPlayer.Instance.Play("sfx-ilha-swipe", true);
        }

	    if (Input.GetMouseButton(0))
            Draw();

        if (Input.GetMouseButtonUp(0))
        {
            SoundEffectsPlayer.Instance.Stop("sfx-ilha-swipe");
            prevCoord = -Vector3.one;
        }
	}

    public void ClearTex()
    {
        for (int i = 0; i < currentTex.width; i++)
            for (int j = 0; j < currentTex.height; j++)
                currentTex.SetPixel(i, j, Color.white);
        currentTex.Apply();
        SaveTex();
    }

    private void SaveTex()
    {
        Graphics.CopyTexture(currentTex, savedTex);
        savedTex.Apply();
    }

    private void UpdateMargins()
    {
        Bounds bounds = frameRenderer.bounds;

        Vector3 centerLeftInWorld = new Vector3(bounds.center.x - bounds.extents.x, bounds.center.y, 0);
        Debug.DrawLine(centerLeftInWorld, bounds.center, Color.magenta);
        left = Camera.main.WorldToViewportPoint(centerLeftInWorld).x;

        Vector3 centerRightInWorld = new Vector3(bounds.center.x + bounds.extents.x, bounds.center.y, 0);
        Debug.DrawLine(centerRightInWorld, bounds.center, Color.green);
        right = Camera.main.WorldToViewportPoint(centerRightInWorld).x;

        Vector3 centerTopInWorld = new Vector3(bounds.center.x, bounds.center.y + bounds.extents.y, 0);
        Debug.DrawLine(centerTopInWorld, bounds.center, Color.yellow);
        top = Camera.main.WorldToViewportPoint(centerTopInWorld).y;

        Vector3 centerBotInWorld = new Vector3(bounds.center.x, bounds.center.y - bounds.extents.y, 0);
        Debug.DrawLine(centerTopInWorld, bounds.center, Color.cyan);
        bot = Camera.main.WorldToViewportPoint(centerBotInWorld).y;
    }

    private void Draw()
    {
        Vector3 raw_vport = Camera.main.ScreenToViewportPoint(Input.mousePosition);

        if (raw_vport.x < left
            || raw_vport.x > right
            || raw_vport.y > top
            || raw_vport.y < bot)
        {
            prevCoord = -Vector3.one;
            return;
        }

        Vector3 cropped_vport = Vector3.zero;
        cropped_vport.x = Mathf.InverseLerp(left, right, raw_vport.x);
        cropped_vport.y = Mathf.InverseLerp(bot, top, raw_vport.y);

        coords.text = cropped_vport.ToString();
        if (prevCoord == -Vector3.one)
            prevCoord = cropped_vport;

        Vector3 runner = prevCoord;
        do
        {
            currentTex.DrawFilledCircle(resolution - (int)(runner.x * resolution), (int)(runner.y * aspectY * resolution), BrushSize, currentBrushColor);
            runner = Vector3.MoveTowards(runner, cropped_vport, LineDensity);
        } while (runner != cropped_vport);

        currentTex.Apply();

        prevCoord = cropped_vport;
    }

    public void IncreaseBrush()
    {
        BrushSize = Mathf.Min(BrushSize + 2, 10);
    }
    
    public void DecreaseBrush()
    {
        BrushSize = Mathf.Max(BrushSize - 2, 1);
    }

    public void Undo()
    {
        SoundEffectsPlayer.Instance.Play("sfx-tile-efeito-verde"); //mudar para botao
        Graphics.CopyTexture(savedTex, currentTex);
        currentTex.Apply();
        frameRenderer.material.SetTexture(0, currentTex);
    }

    public void Done()
    {
        SaveTex();
        LeanTween.rotateAround(frameRenderer.gameObject, Vector3.forward, 360, 0.6f).setEaseInOutBack()
            .setOnComplete(() =>
            {
                ExportTexture();
                UnityEngine.SceneManagement.SceneManager.LoadScene(0);
            });
    }

    public void SetColor(int l)
    {
        currentBrushColor = allColors[l];
    }

    public void ToggleEraser()
    {
        Erasing = !Erasing;

        if (Erasing)
        {
            EraserText.text = "Eraser ON";
            currentBrushColor = EraserColor;
        }
        else
        {
            EraserText.text = "Eraser OFF";
            currentBrushColor = BrushColor;
        }
    }

    [ContextMenu("Export")]
    public void ExportTexture()
    {
        System.IO.File.WriteAllBytes(Application.persistentDataPath + "/drawing.jpg", savedTex.EncodeToJPG());
    }
    [ContextMenu("Import")]
    public void ImportTexture()
    {
        byte[] jpg = System.IO.File.ReadAllBytes(Application.persistentDataPath + "/drawing.jpg");
        currentTex.LoadImage(jpg);
        currentTex.Apply();
        //Debug.Log(currentTex.width + ", " + currentTex.height);
        SaveTex();
    }
    public void ExportToRawImg()
    {
        SaveTex();
        rawImg.texture = savedTex;
    }
}

