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

public interface IVideoCallSession
{
    void OnAnswer();
    void OnDecline();
    void OnHangup();
    void OnDraw();
    void OnEndDraw(byte[] image);
    }

public class RemoteClickAction : MonoBehaviour, IVideoCallSession
{
    uint SessionCallerId;
    const int SCREENSHOT_SUPER_SIZE = 2;

    private enum STATE
    {
        RELEASED,
        SHOWING_REMOTE,
        DRAWING,
        CAPTURING_SCREENSHOT,
        SCREENSHOT_CAPTURING_COROUTINE
    };
    private STATE state_ = STATE.RELEASED;
    //bool pointerDown_ = false;

    private IVideoCallSession session_;

    private RectTransform remoteImageRt_;

    private GameObject callCanvas_;
    private Button answerButton_;
    private Button declineButton_;
    private Text callerName_;

    private GameObject onConnectCanvas_;
    private Button drawButton_;
    private Button hangupButton_;

    private GameObject background_;
    private GameObject remoteCanvas_;
    private GameObject drawCanvas_;
    private RawImage drawImage_;
    private RectTransform curDrawTextRt_;
    private GameObject drawTextPattern_;

    private GameObject drawToolsCanvas_;
    private Button sendImageButton_;
    private Button cancelDrawButton_;

    DrawControl drawControl_;
    private GameObject toolsCanvas;
    private GameObject loginCanvas;
    private AspectRatioFitter fit;
    public RawImage remoteCamImage;
    GameObject RemoteCameraView_;

    // Use this for initialization
    void Start ()
    {
        Client.instance.RemoteAssistCanvas = GameObject.Find("RemoteAssistCanvas");        
        var lst = Client.instance.RemoteAssistCanvas.GetComponentsInChildren<RectTransform>(true);


        foreach (var l in lst)
        {
            switch (l.name)
            {
                case "background": fit = l.gameObject.GetComponent<AspectRatioFitter>();
                    background_ = l.gameObject;
                    break;
                case "RemoteCameraView": remoteCamImage = l.gameObject.GetComponent<RawImage>();
                    remoteImageRt_ = l.gameObject.GetComponent<RectTransform>();
                    RemoteCameraView_ = l.gameObject;
                    break;
                case "ToolsCanvas": toolsCanvas = l.gameObject; break;
                case "RemoteCanvas": remoteCanvas_ = l.gameObject; break;
                case "LoginCanvas": loginCanvas = l.gameObject; break;
                case "CallCanvas": callCanvas_ = l.gameObject; break;
                case "AnswerButton": answerButton_ = l.gameObject.GetComponent<Button>(); break;
                case "DeclineButton": declineButton_ = l.gameObject.GetComponent<Button>(); break;
                case "CallerName": callerName_ = l.gameObject.GetComponent<Text>(); break;
                case "OnConnectCanvas": onConnectCanvas_ = l.gameObject; break;
                case "DrawButton": drawButton_ = l.gameObject.GetComponent<Button>(); break;
                case "HangupButton": hangupButton_ = l.gameObject.GetComponent<Button>(); break;
                case "DrawCanvas": drawCanvas_ = l.gameObject; break;
                case "DrawImage": drawImage_ = l.gameObject.GetComponent<RawImage>(); break;
                case "DrawTextPattern": drawTextPattern_ = l.gameObject; break;
                case "DrawControlCanvas": drawToolsCanvas_ = l.gameObject; break;
                case "SendImageButton": sendImageButton_ = l.gameObject.GetComponent<Button>(); break;
                case "CancelDrawButton": cancelDrawButton_ = l.gameObject.GetComponent<Button>(); break;
            }
         //   Debug.Log("asdsa " + l.name);
        }

               
        answerButton_.onClick.AddListener(this.OnAnswer);
        declineButton_.onClick.AddListener(this.OnDecline);
        callCanvas_.SetActive(false);        
        drawButton_.onClick.AddListener(this.OnDraw);
        hangupButton_.onClick.AddListener(this.OnHangup);
        onConnectCanvas_.SetActive(false);
        drawCanvas_.SetActive(false); //TODO
        drawControl_ = FindObjectOfType<DrawControl>();
        sendImageButton_.onClick.AddListener(this.OnSendImage);
        cancelDrawButton_.onClick.AddListener(this.OnCancelDraw);
        drawToolsCanvas_.SetActive(false); //TODO
        RemoteTextureTestFill();
        Client.instance.RemoteAssistCanvas.SetActive(false);
    }

    public uint GetCallerID()
    {
        return SessionCallerId;
    }

    private void RemoteTextureTestFill()
    {
        //RawImage image = GameObject.Find("RemoteCameraView").GetComponent<RawImage>();

        /*int WIDTH = (int)remoteCanvasRt_.sizeDelta.x;
        int HEIGHT = (int)remoteCanvasRt_.sizeDelta.y;

        Texture2D texture = new Texture2D(WIDTH, HEIGHT);

        for (int i = 0; i < HEIGHT; ++i)
        {
            texture.SetPixel(HEIGHT - i, i, Color.blue);
        }

        texture.Apply();

        image.texture = texture;*/
        remoteCamImage.texture = Texture2D.whiteTexture;
        //image.texture = Texture2D.whiteTexture;
        //image.texture = Texture2D.blackTexture;
    }

    private void Update()
    {
        switch (state_)
        {
            case STATE.CAPTURING_SCREENSHOT:
                CheckScreenshot();
                break;
        }
    }

    public void StartSession(uint callerID)
    {
        session_ = this;
        SessionCallerId = callerID;
        remoteCanvas_.SetActive(true);
        RemoteCameraView_.SetActive(true);
        background_.SetActive(true);
        drawCanvas_.SetActive(true);
        callCanvas_.SetActive(true);
        callerName_.text = "call from " + callerID + "...";        
    }
    public void OnEndDraw(byte[] image)
    {
        //if (image != null)
        //{
        //    videoCalled_.SendImage(image);
        //}
        //else
        //{
        //    videoCalled_.Resume();
        //}
    }

    public void StopSession()
    {
        SessionCallerId = 0;
        callCanvas_.SetActive(false);
        onConnectCanvas_.SetActive(false);
        drawToolsCanvas_.SetActive(false);
        drawCanvas_.SetActive(false);
        RemoteTextureTestFill();

        session_ = null;
    }

    public void OnAnswer()
    {
        if (session_ != null)
        {
            Debug.Log("OnAnswer");
            callCanvas_.SetActive(false);
            onConnectCanvas_.SetActive(true);
            Client.instance.RemoteAssistRequestVideoCall(SessionCallerId, RemoteAssistCMD.videoCallRequest);
        }
    }

    public void OnDraw()
    {
        drawControl_.Clear();
        onConnectCanvas_.SetActive(false);
        drawToolsCanvas_.SetActive(true);
        drawCanvas_.SetActive(true);
        state_ = STATE.DRAWING;
    }
    public void OnHangup()
    {
        onConnectCanvas_.SetActive(false);
        Client.instance.RemoteAssistRequestVideoCall(SessionCallerId, RemoteAssistCMD.callStop);
        if (session_ != null)
        {
            StopSession();
        }
        Client.instance.RemoteAssistCanvas.SetActive(false);
    }

    public void OnDecline()
    {
        Debug.Log("OnDecline " + SessionCallerId);
        callCanvas_.SetActive(false);
        Client.instance.RemoteAssistRequestVideoCall(SessionCallerId, RemoteAssistCMD.callStop);
        if (session_ != null)
        {
            StopSession();
        }
        Client.instance.RemoteAssistCanvas.SetActive(false);
    }

    private void OnSendImage()
    {
        drawToolsCanvas_.SetActive(false);
        //ScreenCapture.CaptureScreenshot(SCREENSHOT_FILE_NAME, SCREENSHOT_SUPER_SIZE);
        state_ = STATE.CAPTURING_SCREENSHOT;
    }

    public void OnCancelDraw()
    {
        drawToolsCanvas_.SetActive(false);
        //ScreenCapture.CaptureScreenshot(SCREENSHOT_FILE_NAME, SCREENSHOT_SUPER_SIZE);
        state_ = STATE.CAPTURING_SCREENSHOT;
    }

    private void CheckScreenshot()
    {
        if (state_ == STATE.CAPTURING_SCREENSHOT)
        {
            StartCoroutine(RecordFrame());
            state_ = STATE.SCREENSHOT_CAPTURING_COROUTINE;
        }
    }

    IEnumerator RecordFrame()
    {
        yield return new WaitForEndOfFrame();
        Texture2D tex = null;
        try
        {
            tex = ScreenCapture.CaptureScreenshotAsTexture(SCREENSHOT_SUPER_SIZE);
        }
        catch (Exception ex)
        {
            Debug.Log(ex.Message);
        }

        drawCanvas_.SetActive(false);
        onConnectCanvas_.SetActive(true);

        int width = (int)remoteImageRt_.rect.width * SCREENSHOT_SUPER_SIZE;
        int height = (int)remoteImageRt_.rect.height * SCREENSHOT_SUPER_SIZE;

        var srceenPos = remoteImageRt_.TransformPoint(new Vector2(0, 0));
        int x = (int)srceenPos.x * SCREENSHOT_SUPER_SIZE;
        int y = (int)srceenPos.y * SCREENSHOT_SUPER_SIZE;

        width = x + width > tex.width ? tex.width - x : width;
        height = y + height > tex.height ? tex.height - y : height;

        Color[] col = tex.GetPixels(x, y, width, height);

        Texture2D m2Texture = new Texture2D(width, height);
        m2Texture.SetPixels(col);
        m2Texture.Apply();

        byte[] compress = m2Texture.EncodeToJPG();
        File.WriteAllBytes("test.jpg", compress);

        if (session_ != null)
        {
            session_.OnEndDraw(compress);
        }

        state_ = STATE.SHOWING_REMOTE;
    }

}
