using AR;
using Emgu.CV;
using Emgu.CV.Structure;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using UIControl;

namespace Project
{
    public partial class FMain : Form
    {
        DateTime CameraConTimeL = DateTime.Now;
        DateTime CameraConTimeR = DateTime.Now;
        DateTime BarcodeConTime = DateTime.Now;
        DateTime KeyenceConTimeF = DateTime.Now;
        DateTime KeyenceConTimeR = DateTime.Now;
        DateTime PrintLConTime = DateTime.Now;
        DateTime PrintRConTime = DateTime.Now;
        DateTime swPLCConTime = DateTime.Now;
        Boolean bRunConnection = true;

        
        void bwDeviceConnection()
        {
            while (bRunConnection && this.Disposing == false && this.Disposing == false)
            {
                //초기혹은 파괴상태는 처리안함
                if (PUB.keyenceF != null && PUB.keyenceF.disposed &&
                    PUB.keyenceR != null && PUB.keyenceR.disposed)
                {
                    System.Threading.Thread.Sleep(1000);
                    continue;
                }

                if (ConnectSeq == 0)    //키엔스
                {
                    var tscam = DateTime.Now - KeyenceConTimeF;
                    if (tscam.TotalSeconds > 5 && PUB.flag.get(eVarBool.FG_KEYENCE_OFFF) == false)
                    {
                        if (AR.SETTING.Data.Keyence_IPF.isEmpty() == false)
                        {
                            if (PUB.keyenceF != null && PUB.keyenceF.IsConnect == false)
                            {
                                PUB.keyenceF.Connect();
                                KeyenceConTimeF = DateTime.Now;
                            }
                            else
                            {
                                //연결이 되어있다면 상태값을 요청한다
                                KeyenceConTimeF = DateTime.Now.AddSeconds(-4);
                            }
                        }
                        else KeyenceConTimeF = DateTime.Now.AddSeconds(-4);
                    }
                    ConnectSeq += 1;
                }
                else if (ConnectSeq == 1)    //키엔스
                {
                    var tscam = DateTime.Now - KeyenceConTimeR;
                    if (tscam.TotalSeconds > 5 && PUB.flag.get(eVarBool.FG_KEYENCE_OFFR) == false)
                    {
                        if (AR.SETTING.Data.Keyence_IPR.isEmpty() == false)
                        {
                            if (PUB.keyenceR != null && PUB.keyenceR.IsConnect == false)
                            {
                                PUB.keyenceR.Connect();
                                KeyenceConTimeR = DateTime.Now;
                            }
                            else
                            {
                                //연결이 되어있다면 상태값을 요청한다
                                KeyenceConTimeR = DateTime.Now.AddSeconds(-4);
                            }
                        }
                        else KeyenceConTimeR = DateTime.Now.AddSeconds(-4);
                    }
                    ConnectSeq += 1;
                }
                else if (ConnectSeq == 2) //카메라(왼)
                {
                    var tscam = DateTime.Now - CameraConTimeL;
                    if (tscam.TotalSeconds > 7)
                    {
                        //if (COMM.SETTING.Data.EnableExtVision)
                        if (PUB.wsL == null || PUB.wsL.Connected == false)
                        {
                            if (AR.SETTING.Data.Log_CameraConn)
                                PUB.log.Add($"Camera(L) connection attempt ({AR.SETTING.Data.HostIPL}:{AR.SETTING.Data.HostPortL})");
                            if (PUB.wsL != null)
                            {
                                DetachCameraEventL(); //이벤트 종료
                                PUB.wsL.Dispose();
                            }

                            PUB.wsL = new WatsonWebsocket.WatsonWsClient(AR.SETTING.Data.HostIPL, AR.SETTING.Data.HostPortL, false);
                            AttachCameraEventL();
                            try
                            {
                                PUB.wsL.StartWithTimeout();
                            }
                            catch (Exception ex)
                            {
                                PUB.log.AddE(ex.Message); //220214
                            }

                            CameraConTimeL = DateTime.Now;
                        }
                        else
                        {
                            //연결이 되어있다면 상태값을 요청한다
                            //if (PUB.flag.get(eVarBool.FG_RDY_CAMERA_L) == false)
                            {
                                //마지막 수신시간으로 부터 5초가 지나면 전송한다
                                //var tsRecv = DateTime.Now - lastRecvWSL;
                                //if (tsRecv.TotalSeconds >= 15)
                                //{
                                //    PUB.wsL.Dispose();
                                //}
                                //else if (tsRecv.TotalSeconds >= 5)
                                {
                                    WS_Send(eWorkPort.Left, PUB.wsL, string.Empty, "STATUS", "");
                                }
                                CameraConTimeL = DateTime.Now.AddSeconds(-4);
                            }
                        }
                    }
                    ConnectSeq += 1;
                }
                else if (ConnectSeq == 3) //카메라(우)
                {
                    var tscam = DateTime.Now - CameraConTimeR;
                    if (tscam.TotalSeconds > 7)
                    {
                        //if (COMM.SETTING.Data.EnableExtVision)
                        if (PUB.wsR == null || PUB.wsR.Connected == false)
                        {
                            if (AR.SETTING.Data.Log_CameraConn)
                                PUB.log.Add($"Camera(R) connection attempt ({AR.SETTING.Data.HostIPR}:{AR.SETTING.Data.HostPortR})");
                            if (PUB.wsR != null)
                            {
                                DetachCameraEventR(); //이벤트 종료
                                PUB.wsR.Dispose();
                            }

                            PUB.wsR = new WatsonWebsocket.WatsonWsClient(AR.SETTING.Data.HostIPR, AR.SETTING.Data.HostPortR, false);
                            AttachCameraEventR();

                            try
                            {
                                PUB.wsR.Start();
                            }
                            catch (Exception ex)
                            {
                                PUB.log.AddE(ex.Message); //220214
                            }


                            CameraConTimeR = DateTime.Now;
                        }
                        else
                        {
                            //연결이 되어있다면 상태값을 요청한다
                            //if (PUB.flag.get(eVarBool.FG_RDY_CAMERA_R) == false)
                            {
                                //마지막 수신시간으로 부터 5초가 지나면 전송한다
                                //var tsRecv = DateTime.Now - lastRecvWSR;
                                //if (tsRecv.TotalSeconds >= 15)
                                //{
                                //    PUB.wsR.Dispose();
                                //}
                                //else if (tsRecv.TotalSeconds >= 5)
                                {
                                    WS_Send(eWorkPort.Right, PUB.wsR, string.Empty, "STATUS", "");
                                }
                                CameraConTimeR = DateTime.Now.AddSeconds(-4);




                            }
                        }
                    }
                    ConnectSeq += 1;
                }
                else if (ConnectSeq == 4)   //바코드연결
                {
                    var tscam = DateTime.Now - BarcodeConTime;
                    if (tscam.TotalSeconds > 5)
                    {
                        if (AR.SETTING.Data.Barcode_Port.isEmpty() == false)
                        {
                            if (PUB.BarcodeFix == null || PUB.BarcodeFix.IsOpen() == false)
                            {
                                PUB.BarcodeFix.PortName = AR.SETTING.Data.Barcode_Port;
                                PUB.BarcodeFix.BaudRate = AR.SETTING.Data.Barcode_Baud;
                                PUB.BarcodeFix.Open();
                                BarcodeConTime = DateTime.Now;
                            }
                            else
                            {
                                //연결이 되어있다면 상태값을 요청한다
                                BarcodeConTime = DateTime.Now.AddSeconds(-4);
                            }
                        }
                        else BarcodeConTime = DateTime.Now.AddSeconds(-4);
                    }
                    ConnectSeq += 1;
                }
                else if (ConnectSeq == 5) //프린터(좌)
                {
                    var tscam = DateTime.Now - PrintLConTime;
                    if (tscam.TotalSeconds > 5)
                    {
                        if (AR.SETTING.Data.PrintL_Port.isEmpty() == false)
                        {
                            if (PUB.PrinterL == null || PUB.PrinterL.IsOpen == false)
                            {
                                try
                                {
                                    PUB.PrinterL.PortName = AR.SETTING.Data.PrintL_Port;
                                    PUB.PrinterL.BaudRate = AR.SETTING.Data.PrintL_Baud;
                                    PUB.PrinterL.Open();
                                    PrintLConTime = DateTime.Now;
                                }
                                catch (Exception ex)
                                {
                                    PUB.log.AddE($"Printer(L) {ex.Message}");
                                }
                            }
                            else
                            {
                                //연결이 되어있다면 상태값을 요청한다
                                PrintLConTime = DateTime.Now.AddSeconds(-4);
                            }
                        }
                        else PrintLConTime = DateTime.Now.AddSeconds(-4);
                    }
                    ConnectSeq += 1;
                }
                else if (ConnectSeq == 6) //프린터(우)
                {
                    var tscam = DateTime.Now - PrintRConTime;
                    if (tscam.TotalSeconds > 5)
                    {
                        if (AR.SETTING.Data.PrintR_Port.isEmpty() == false)
                        {
                            if (PUB.PrinterR == null || PUB.PrinterR.IsOpen == false)
                            {
                                try
                                {
                                    PUB.PrinterR.PortName = AR.SETTING.Data.PrintR_Port;
                                    PUB.PrinterR.BaudRate = AR.SETTING.Data.PrintR_Baud;
                                    PUB.PrinterR.Open();
                                    PrintRConTime = DateTime.Now;
                                }
                                catch (Exception ex) {
                                    PUB.log.AddE($"Printer(R) {ex.Message}");
                                }
                            }
                            else
                            {
                                //연결이 되어있다면 상태값을 요청한다
                                PrintRConTime = DateTime.Now.AddSeconds(-4);
                            }
                        }
                        else PrintRConTime = DateTime.Now.AddSeconds(-4);
                    }
                    ConnectSeq = 7;
                }
                else if (ConnectSeq == 7) //swPLC 230725
                {
                    var tscam = DateTime.Now - swPLCConTime;
                    if (tscam.TotalSeconds > 5)
                    {
                        if (PUB.plc != null && PUB.plc.Init == false)
                        {
                            PUB.plc.Start();
                        }
                        swPLCConTime = DateTime.Now;
                    }
                    ConnectSeq = 0;
                }
                System.Threading.Thread.Sleep(2000);

            }
            Console.WriteLine("Close : bwDeviceConnection");
        }


        public string PostFromUrl(string url, string jsonStr, out Boolean isError, string authid = "", string authpw = "", int _timeout = 0)
        {
            isError = false;
            string result = "";
            try
            {
                var timeout = 1000;
                //RaiseMessage(false, "POST : " + url);
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url));
                if (_timeout == 0)
                {
                    request.Timeout = timeout;
                    request.ReadWriteTimeout = timeout;
                }
                else
                {
                    request.Timeout = _timeout;
                    request.ReadWriteTimeout = _timeout;
                }


                if (string.IsNullOrEmpty(authid) == false && string.IsNullOrEmpty(authpw) == false)
                {
                    string authInfo = $"{authid}:{authpw}";
                    authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
                    request.Headers["Authorization"] = "Basic " + authInfo;
                }

                request.Method = "POST";
                request.ContentType = "application/json";
                request.ContentLength = jsonStr.Length;
                request.MaximumAutomaticRedirections = 4;
                request.MaximumResponseHeadersLength = 4;
                request.Credentials = CredentialCache.DefaultCredentials;

                using (StreamWriter sw = new StreamWriter(request.GetRequestStream()))
                {
                    sw.Write(jsonStr);
                    sw.Flush();
                    sw.Close();

                    var response = request.GetResponse() as HttpWebResponse;
                    using (var txtReader = new StreamReader(response.GetResponseStream()))
                    {
                        result = txtReader.ReadToEnd();
                    }
                }

                // LastQueryBUF = result;
                //LastQueryURL = url;
                //RaiseRawMessage(url, "RESULT\n" + result);   //181026 - show data
            }
            catch (WebException wex)
            {
                isError = true;
                result = wex.ToString();// new StreamReader(wex.Response.GetResponseStream()).ReadToEnd();
                //RaiseMessage(true, "POST-ERROR\n" + result);
            }

            return result;
        }
    }
}
