using GcDevicePc.GCBuffer;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace GcDevicePc.ProThread
{
    public class SendDataToZB
    {
        [DllImport(@"SendData.dll",EntryPoint = "GcSendDataToZb", CallingConvention = CallingConvention.Cdecl)]
        public static extern void GcSendDataToZb(int data1, int data2, int data3);


        #region 私有变量
        ManualResetEvent datamre = new ManualResetEvent(false);

        Thread t_DataToHw;
        #endregion

        #region 

        public void StartSendDataToZB()
        {
            GcSendDataToZb(1, 0, 1);
            GcSendDataToZb(0, 1, 1);
            //GcSendDataToZb(0, 1, 3);
            //GcSendDataToZb(1, 0, 3);
            //GcSendDataToZb(1, 1, 1);

        }

        private void StopSendDataToZB()
        {
            GcSendDataToZb(1, 0, 2);
            GcSendDataToZb(0, 1, 2);
            //GcSendDataToZb(0, 1, 4);
            //GcSendDataToZb(1, 0, 4);
            //GcSendDataToZb(1, 1, 2);

        }

        private void SendDataToZB_A(Int32 data)
        {
            //GcSendDataToZb(data, 0, 3);
            //GcSendDataToZb(0, 0, 4);

            GcSendDataToZb(1, 0, 1);
            GcSendDataToZb(0, 1, 2);
        }

        private void SendDataToZB_B(Int32 data)
        {
            GcSendDataToZb(0, 1, 1);
            GcSendDataToZb(1, 0, 2);
        }

        private void SendDataToZB_AB(Int32 dataA, Int32 dataB)
        {
            //GcSendDataToZb(1, 1, 1);

            //double bz = 8388608 / 1120400;

            //int da = dataA * 0.298;//8388608 = 2^23
            //int db = dataB * 0.298;
            int da = Convert.ToInt32(dataA);

            int db = Convert.ToInt32(dataB);
            GcSendDataToZb(da, db, 0);
            //GcSendDataToZb(10, 20, 0);

        }

        public void testzb(Int32 dataA, Int32 dataB)
        {
            //GcSendDataToZb(1, 1, 1);
            GcSendDataToZb(dataA, dataB, 0);
            //GcSendDataToZb(dataA, dataB, 0);
            //GcSendDataToZb(10, 20, 0);

        }

        public void testzba()
        {
            //GcSendDataToZb(1, 1, 1);

            GcSendDataToZb(1, 0, 1);
            GcSendDataToZb(1, 0, 3);

            GcSendDataToZb(0, 1, 2);
            GcSendDataToZb(0, 1, 4);


            //GcSendDataToZb(10, 20, 0);

        }

        public void testzbb()
        {
            //GcSendDataToZb(1, 1, 1);

            GcSendDataToZb(0, 1, 1);
            GcSendDataToZb(1, 0, 2);

            //GcSendDataToZb(0, 1, 3);
            //GcSendDataToZb(1, 0, 4);
            //GcSendDataToZb(10, 20, 0);

        }

        public void testzbb(int a,int b,int c)
        {
            //GcSendDataToZb(1, 1, 1);

            GcSendDataToZb(a, b, c);

            //GcSendDataToZb(0, 1, 3);
            //GcSendDataToZb(1, 0, 4);
            //GcSendDataToZb(10, 20, 0);

        }
        #endregion


        #region 数据输出逻辑
        private ushort CheckNumandTime(int num, ushort[] Det, ushort[] Time)
        {
            ushort count = 0;
            for (int i = 0; i < Det.Length; i++)
            {
                if (num == Det[i] || num == Time[i])
                {
                    break;
                }
                else
                {
                    count++;
                }
            }
            return count;
        }

        private void CleanAllToZBData()
        {

            lock (globaldata.channelA_A)
            {
                globaldata.channelA_A.Clear();
            }

            lock (globaldata.channelA_B)
            {
                globaldata.channelA_B.Clear();
            }

            lock (globaldata.channelA_C)
            {
                globaldata.channelA_C.Clear();
            }

            lock (globaldata.channelB_A)
            {
                globaldata.channelB_A.Clear();
            }

            lock (globaldata.channelB_B)
            {
                globaldata.channelB_B.Clear();
            }

            lock (globaldata.channelB_C)
            {
                globaldata.channelB_C.Clear();
            }
        }

        private void InitSendToZBData()
        {
            int mydataA = 0;
            int mydataB = 0;
            int i = 0;
            for (i = 0; i < 5; i++)
            {
                try
                {
                    switch (methodconfig.signal.uDetA[0])
                    {
                        case 1:
                            if (globaldata.channelA_A.Count >= 1)
                            {
                                mydataA = Int32.Parse(globaldata.channelA_A[globaldata.channelA_A.Count - 1].ToString());
                                globaldata.channelA_A.RemoveAt(0);
                            }
                            break;
                        case 2:
                            if (globaldata.channelA_B.Count >= 1)
                            {
                                mydataA = Int32.Parse(globaldata.channelA_B[globaldata.channelA_B.Count - 1].ToString());
                                globaldata.channelA_B.RemoveAt(0);
                            }
                            break;
                        case 3:
                            if (globaldata.channelA_C.Count >= 1)
                            {
                                mydataA = Int32.Parse(globaldata.channelA_C[globaldata.channelA_C.Count - 1].ToString());
                                globaldata.channelA_C.RemoveAt(0);
                            }
                            break;
                    }

                    switch (methodconfig.signal.uDetB[0])
                    {
                        case 1:
                            if (globaldata.channelB_A.Count >= 1)
                            {
                                mydataB = Int32.Parse(globaldata.channelB_A[globaldata.channelB_A.Count - 1].ToString());
                                globaldata.channelB_A.RemoveAt(0);
                            }
                            break;
                        case 2:
                            if (globaldata.channelB_B.Count >= 1)
                            {
                                mydataB = Int32.Parse(globaldata.channelB_B[globaldata.channelB_B.Count - 1].ToString());
                                globaldata.channelB_B.RemoveAt(0);
                            }
                            break;
                        case 3:
                            if (globaldata.channelB_C.Count >= 1)
                            {
                                mydataB = Int32.Parse(globaldata.channelB_C[globaldata.channelB_C.Count - 1].ToString());
                                globaldata.channelB_C.RemoveAt(0);
                            }
                            break;
                    }
                }
                catch
                {

                }

                ////写入A
                //if (methodconfig.signal.u16ChannelA == 1 && methodconfig.signal.u16ChannelB != 1)
                //{
                //    SendDataToZB_A(mydataA);
                //    Thread.Sleep(50);
                //}

                ////写入B
                //if (methodconfig.signal.u16ChannelA != 1 && methodconfig.signal.u16ChannelB == 1)
                //{
                //    SendDataToZB_B(mydataB);
                //    Thread.Sleep(50);
                //}

                if (methodconfig.signal.u16ChannelA == 1 || methodconfig.signal.u16ChannelB == 1)
                {
                    SendDataToZB_AB(mydataA, mydataB);
                    Thread.Sleep(50);
                }
            }


        }

        private void EndSendToZBData(ushort lastA, int offsetA, ushort lastB, int offsetB)
        {
            int mydataA = 0;
            int mydataB = 0;
            int i = 0;
            for (i = 0; i < 5; i++)
            {
                switch (methodconfig.signal.uDetA[lastA])
                {
                    case 1:
                        if (globaldata.channelA_A.Count >= 1)
                        {
                            mydataA = Int32.Parse(globaldata.channelA_A[0].ToString()) - offsetA;
                            globaldata.channelA_A.RemoveAt(0);
                        }
                        break;
                    case 2:
                        if (globaldata.channelA_B.Count >= 1)
                        {
                            mydataA = Int32.Parse(globaldata.channelA_B[0].ToString()) - offsetA;
                            globaldata.channelA_B.RemoveAt(0);
                        }
                        break;
                    case 3:
                        if (globaldata.channelA_C.Count >= 1)
                        {
                            mydataA = Int32.Parse(globaldata.channelA_C[0].ToString()) - offsetA;
                            globaldata.channelA_C.RemoveAt(0);
                        }
                        break;
                }

                switch (methodconfig.signal.uDetB[lastB])
                {
                    case 1:
                        if (globaldata.channelB_A.Count >= 1)
                        {
                            mydataB = Int32.Parse(globaldata.channelB_A[0].ToString()) - offsetB;
                            globaldata.channelB_A.RemoveAt(0);
                        }
                        break;
                    case 2:
                        if (globaldata.channelB_B.Count >= 1)
                        {
                            mydataB = Int32.Parse(globaldata.channelB_B[0].ToString()) - offsetB;
                            globaldata.channelB_B.RemoveAt(0);
                        }
                        break;
                    case 3:
                        if (globaldata.channelB_C.Count >= 1)
                        {
                            mydataB = Int32.Parse(globaldata.channelB_C[0].ToString()) - offsetB;
                            globaldata.channelB_C.RemoveAt(0);
                        }
                        break;
                }



                ////写入A
                //if (methodconfig.signal.u16ChannelA == 1 && methodconfig.signal.u16ChannelB != 1)
                //{
                //    SendDataToZB_A(mydataA);
                //    Thread.Sleep(50);
                //}

                ////写入B
                //if (methodconfig.signal.u16ChannelA != 1 && methodconfig.signal.u16ChannelB == 1)
                //{
                //    SendDataToZB_B(mydataB);
                //    Thread.Sleep(50);
                //}

                if (methodconfig.signal.u16ChannelA == 1 || methodconfig.signal.u16ChannelB == 1)
                {
                    SendDataToZB_AB(mydataA, mydataB);
                    Thread.Sleep(50);
                }
            }
        }

        public static GCMethodConfig methodconfig { get; set; }
        private void SendToZB_Draw()
        {
            DateTime StartTimeA;
            DateTime StartTimeB;
            DateTime EndTimeA;
            DateTime EndTimeB;
            TimeSpan tsA;
            TimeSpan tsB;
            int secA;
            int secB;
            int offetA = 0;
            int offetB = 0;
            bool run_stop = false;
            ushort SendNumA = 0;
            ushort SendNumB = 0;
            //int i = 0;
            bool runflag = false;

            while (!datamre.WaitOne(500))
            {
                if ((globaldata.m_hmibuffer.gcinfo.methodstatus == 4 || globaldata.m_hmibuffer.gcinfo.methodstatus == 5) && methodconfig != null && run_stop != true)
                //if ((globaldata.m_hmibuffer.gcinfo.methodstatus == 4 || globaldata.m_hmibuffer.gcinfo.methodstatus == 5) && globaldata.m_hmibuffer.gcinfo.hmistatus == 4 && run_stop != true)
                {
                    int saveB = 0;
                    int recordB = 0;
                    int recordA = 0;
                    int saveA = 0;

                    int onea = 0;
                    int oneb = 0;

                    bool ackoneA = false;
                    bool ackoneB = false;
                    InitSendToZBData();
                    //清除所有数据，准备传输
                    CleanAllToZBData();

                    //开启绘图通知
                    StartSendDataToZB();
                    //绘图通知开启flag
                    runflag = true;
                    if (methodconfig.signal.u16ChannelA == 1)
                    {
                        SendNumA = CheckNumandTime(0, methodconfig.signal.uDetA, methodconfig.signal.u16DetTimeLengthA);
                    }

                    if (methodconfig.signal.u16ChannelB == 1)
                    {
                        SendNumB = CheckNumandTime(0, methodconfig.signal.uDetB, methodconfig.signal.u16DetTimeLengthB);
                    }

                    //LogHelper.I("StepA StpeB is", SendNumA.ToString() + " "+ SendNumB.ToString());

                    ushort MAXNum = SendNumA > SendNumB ? SendNumA : SendNumB;

                    if (methodconfig.signal.u16ChannelA == 1 || methodconfig.signal.u16ChannelB == 1)
                    {

                        int StepA = 0;
                        int StepB = 0;
                        {
                            StartTimeA = DateTime.Now;
                            StartTimeB = DateTime.Now;
                            int mydataA = 0;
                            int mydataB = 0;
                            while (true)
                            {
                                EndTimeA = DateTime.Now;
                                tsA = StartTimeA.Subtract(EndTimeA).Duration();
                                secA = (int)tsA.TotalSeconds;
                                EndTimeB = DateTime.Now;
                                tsB = StartTimeB.Subtract(EndTimeB).Duration();
                                secB = (int)tsB.TotalSeconds;


                                try
                                {
                                    if (StepA < SendNumA)
                                    {
                                        if (secA <= methodconfig.signal.u16DetTimeLengthA[StepA])
                                        {
                                            int mydataA_old;
                                            //Console.WriteLine("总共:" + SendNumA.ToString() + " 阶段，现在是第" + StepA.ToString() + "个阶段：" + secA.ToString() + "/" + methodconfig.signal.u16DetTimeLengthA[StepA].ToString());

                                            switch (methodconfig.signal.uDetA[StepA])
                                            {
                                                case 1:
                                                    if (globaldata.channelA_A.Count >= 1)
                                                    {
                                                        //if (changeA_flag)
                                                        //{
                                                        //    offetA = Int32.Parse(globaldata.channelA_A[0].ToString()) - mydataA_old;
                                                        //    changeA_flag = false;
                                                        //}
                                                        mydataA = Int32.Parse(globaldata.channelA_A[0].ToString()) - offetA;

                                                        if (ackoneA)
                                                        {
                                                            onea = mydataA;
                                                            ackoneA = false;
                                                        }

                                                        if (onea > saveA)
                                                        {
                                                            mydataA = mydataA - (onea - saveA);

                                                        }
                                                        else if (onea < saveA)
                                                        {
                                                            mydataA = mydataA + (saveA - onea);

                                                        }

                                                        mydataA_old = mydataA;

                                                    }
                                                    break;
                                                case 2:
                                                    if (globaldata.channelA_B.Count >= 1)
                                                    {
                                                        //if (changeA_flag)
                                                        //{
                                                        //    offetA = Int32.Parse(globaldata.channelA_B[0].ToString()) - mydataA_old;
                                                        //    changeA_flag = false;
                                                        //}
                                                        mydataA = Int32.Parse(globaldata.channelA_B[0].ToString()) - offetA;

                                                        if (ackoneA)
                                                        {
                                                            onea = mydataA;
                                                            ackoneA = false;
                                                        }

                                                        if (onea > saveA)
                                                        {
                                                            mydataA = mydataA - (onea - saveA);

                                                        }
                                                        else if (onea < saveA)
                                                        {
                                                            mydataA = mydataA + (saveA - onea);

                                                        }
                                                        mydataA_old = mydataA;

                                                    }
                                                    break;
                                                case 3:
                                                    if (globaldata.channelA_C.Count >= 1)
                                                    {
                                                        //if (changeA_flag)
                                                        //{
                                                        //    offetA = Int32.Parse(globaldata.channelA_C[0].ToString()) - mydataA_old;
                                                        //    changeA_flag = false;
                                                        //}
                                                        mydataA = Int32.Parse(globaldata.channelA_C[0].ToString()) - offetA;

                                                        if (ackoneA)
                                                        {
                                                            onea = mydataA;
                                                            ackoneA = false;
                                                        }

                                                        if (onea > saveA)
                                                        {
                                                            mydataA = mydataA - (onea - saveA);

                                                        }
                                                        else if (onea < saveA)
                                                        {
                                                            mydataA = mydataA + (saveA - onea);

                                                        }

                                                        mydataA_old = mydataA;

                                                    }
                                                    break;
                                            }

                                            if (globaldata.channelA_A.Count >= 1)
                                            {
                                                globaldata.channelA_A.RemoveAt(0);
                                            }

                                            if (globaldata.channelA_B.Count >= 1)
                                            {
                                                globaldata.channelA_B.RemoveAt(0);
                                            }

                                            if (globaldata.channelA_C.Count >= 1)
                                            {
                                                globaldata.channelA_C.RemoveAt(0);
                                            }

                                            recordA = mydataA;
                                        }
                                        else
                                        {
                                            // LogHelper.I("StepA++ ", StepA.ToString() + " " + SendNumA.ToString());
                                            saveA = recordA;
                                            ackoneA = true;
                                            StepA++;
                                            StartTimeA = DateTime.Now;
                                        }
                                    }


                                    if (StepB < SendNumB)
                                    {
                                        if (secB <= methodconfig.signal.u16DetTimeLengthB[StepB])
                                        {
                                            int mydataB_old;
                                            //Console.WriteLine("总共:" + SendNumB.ToString() + " 阶段，现在是第" + StepB.ToString() + "个阶段：" + secB.ToString() + "/" + methodconfig.signal.u16DetTimeLengthB[i].ToString());

                                            switch (methodconfig.signal.uDetB[StepB])
                                            {
                                                case 1:
                                                    if (globaldata.channelB_A.Count >= 1)
                                                    {
                                                        //if (changeB_flag)
                                                        //{
                                                        //    offetB = Int32.Parse(globaldata.channelB_A[0].ToString()) - mydataB_old;
                                                        //    changeB_flag = false;
                                                        //}
                                                        mydataB = Int32.Parse(globaldata.channelB_A[0].ToString()) - offetB;

                                                        if (ackoneB)
                                                        {
                                                            oneb = mydataB;
                                                            ackoneB = false;
                                                        }

                                                        if (oneb > saveB)
                                                        {
                                                            mydataB = mydataB - (oneb - saveB);
                                                        }
                                                        else if (oneb < saveB)
                                                        {
                                                            mydataB = mydataB + (saveB - oneb);
                                                        }
                                                        mydataB_old = mydataB;

                                                    }
                                                    break;
                                                case 2:
                                                    if (globaldata.channelB_B.Count >= 1)
                                                    {
                                                        //if (changeB_flag)
                                                        //{
                                                        //    offetB = Int32.Parse(globaldata.channelB_B[0].ToString()) - mydataB_old;
                                                        //    changeB_flag = false;
                                                        //}
                                                        mydataB = Int32.Parse(globaldata.channelB_B[0].ToString()) - offetB;


                                                        if (ackoneB)
                                                        {
                                                            oneb = mydataB;
                                                            ackoneB = false;
                                                        }

                                                        if (oneb > saveB)
                                                        {
                                                            mydataB = mydataB - (oneb - saveB);
                                                        }
                                                        else if (oneb < saveB)
                                                        {
                                                            mydataB = mydataB + (saveB - oneb);
                                                        }

                                                        mydataB_old = mydataB;

                                                    }
                                                    break;
                                                case 3:
                                                    if (globaldata.channelB_C.Count >= 1)
                                                    {
                                                        //if (changeB_flag)
                                                        //{
                                                        //    offetB = Int32.Parse(globaldata.channelB_C[0].ToString()) - mydataB_old;
                                                        //    changeB_flag = false;
                                                        //}
                                                        mydataB = Int32.Parse(globaldata.channelB_C[0].ToString()) - offetB;


                                                        if (ackoneB)
                                                        {
                                                            oneb = mydataB;
                                                            ackoneB = false;
                                                        }

                                                        if (oneb > saveB)
                                                        {
                                                            mydataB = mydataB - (oneb - saveB);
                                                        }
                                                        else if (oneb < saveB)
                                                        {
                                                            mydataB = mydataB + (saveB - oneb);
                                                        }

                                                        mydataB_old = mydataB;

                                                    }
                                                    break;
                                            }
                                            if (globaldata.channelB_A.Count >= 1)
                                            {
                                                globaldata.channelB_A.RemoveAt(0);
                                            }
                                            if (globaldata.channelB_B.Count >= 1)
                                            {
                                                globaldata.channelB_B.RemoveAt(0);
                                            }
                                            if (globaldata.channelB_C.Count >= 1)
                                            {
                                                globaldata.channelB_C.RemoveAt(0);
                                            }
                                            recordB = mydataB;
                                        }
                                        else
                                        {
                                            // LogHelper.I("StepB  ", StepB.ToString() + " " + SendNumB.ToString());
                                            saveB = recordB;
                                            ackoneB = true;
                                            StepB++;
                                            StartTimeB = DateTime.Now;
                                        }
                                    }
                                }
                                catch
                                {

                                }




                                //写入A
                                //if (StepA < SendNumA && StepB >= SendNumB)
                                //{
                                //    // LogHelper.I("SendDataToHW_A", secA.ToString());
                                //    SendDataToZB_A(mydataA);

                                //    Thread.Sleep(50);
                                //}

                                ////写入B
                                //if (StepB < SendNumB && StepA >= SendNumA)
                                //{
                                //    // LogHelper.I("SendDataToHW_B", secB.ToString());
                                //    SendDataToZB_B(mydataB);

                                //    Thread.Sleep(50);
                                //}

                                //写入AB
                                if (StepA < SendNumA || StepB < SendNumB)
                                {
                                    //Console.WriteLine("SendDataToHW A B", secA.ToString() + " "+ secB.ToString());
                                    SendDataToZB_AB(mydataA, mydataB);

                                    Thread.Sleep(50);
                                }

                                if (StepB >= SendNumB && StepA >= SendNumA)
                                {
                                    run_stop = true;
                                    break;
                                }

                                if ((globaldata.m_hmibuffer.gcinfo.methodstatus != 4 && globaldata.m_hmibuffer.gcinfo.methodstatus != 5))
                                {
                                    //LogHelper.I("methodstatus", "stop");
                                    run_stop = true;
                                    break;
                                }
                            }

                            //if ((globaldata.m_hmibuffer.gcinfo.methodstatus != 4 && globaldata.m_hmibuffer.gcinfo.methodstatus != 5))
                            //{
                            //   break;
                            //}
                        }
                    }

                }

                if ((globaldata.m_hmibuffer.gcinfo.methodstatus != 4 && globaldata.m_hmibuffer.gcinfo.methodstatus != 5) || run_stop)
                {
                    if (runflag)
                    {
                        StopSendDataToZB();
                        CleanAllToZBData();
                        runflag = false;
                        run_stop = false;
                    }

                }
            }
        }

        #endregion


        public void DataToZBStart()
        {
            if (datamre != null)
            {
                datamre.Reset();
            }
            t_DataToHw = new Thread(SendToZB_Draw);
            t_DataToHw.IsBackground = true;
            t_DataToHw.Start();
        }

        public void DataToZBStop()
        {
            datamre.Set();
        }
    }
}
