using System;
using NationalInstruments.DAQmx;
using CRVM.Entity;
using CRVM.Utility;
using System.Timers;

namespace CRVM.Driver
{
    public class DaqDriver
    {
        private double[,] vibdata1 = new double[4, SysParam.Instance.samplePoint];
        private double[,] vibdata2 = new double[4, SysParam.Instance.samplePoint];
        private double[,] speeddata = new double[8, SysParam.Instance.samplePoint];//F1~F5速度,轧制距离
        private double[] cutdata = new double[8];
        private double[] lendata;
        private bool[] cutflags = new bool[8];//剪切信号--第0位采集箱cz02状态，第1位--剪切信号
        private bool[] cz02State = new bool[8];//采集箱cz03状态 第0位
        public bool[] CutFlags { get { return cutflags; } }

        public bool[] CZconnected { get; set; }//CZ02 CZ03 通电状态

        private Task myTask_Analog1, myTask_Analog2, myTask_Speed;// myTask_Cut, myTask_cz03;
        private AnalogMultiChannelReader analogInReader1, analogInReader2, analogSpeedReader;
        private DigitalSingleChannelReader myDigitalReader, myDigitalReader2;
        //private AnalogSingleChannelReader analogCutReader, analogLenReader;
        private Task runningTask1, runningTask2, runningTask3;
        private AsyncCallback analogCallback1, analogCallback2, analogCallback3;

        //private System.Timers.Timer Cut_timer = new System.Timers.Timer();
        //private System.Timers.Timer CZ03_timer = new System.Timers.Timer();
        int count = 0;
        public DaqDriver()
        {
            //修改为线程池任务
            new System.Threading.Tasks.Task(() => DaqStart()).Start();
        }

        public void DaqStart()
        {
            DevelopLog.DeBug.WriteLogFile("DaqStart", "DaqStart");
            try
            {
                myTask_Analog1 = new Task();
                myTask_Analog2 = new Task();
                myTask_Speed = new Task();

                /* ---------------------剪切信号采集任务--------------------*/
                //Cut_timer.Interval = 200; //执行间隔时间,单位为毫秒; 
                //Cut_timer.Elapsed += new System.Timers.ElapsedEventHandler(updateCutFlag);
                /* ---------------------CZ03状态采集任务--------------------*/
               // CZ03_timer.Interval = 200;
                //CZ03_timer.Elapsed += new System.Timers.ElapsedEventHandler(updateCZFlag);

                //振动信号 加速度信号 1~8通道 1~5通道对应1~5机架的振动信号 6~8通道预留
                for (int i = 0; i < 4; i++)
                {
                    myTask_Analog1.AIChannels.CreateAccelerometerChannel("Vib1/ai" + i.ToString(), "", AITerminalConfiguration.Pseudodifferential, -5.0, 5.0,
                        SysParam.Instance.channel[i].vibSens, AIAccelerometerSensitivityUnits.MillivoltsPerG, AIExcitationSource.Internal, Convert.ToSingle(0.004), AIAccelerationUnits.G);
                }

                for (int i = 0; i < 4; i++)
                {
                    myTask_Analog2.AIChannels.CreateAccelerometerChannel("Vib2/ai" + i.ToString(), "", AITerminalConfiguration.Pseudodifferential, -5.0, 5.0,
                        SysParam.Instance.channel[4 + i].vibSens, AIAccelerometerSensitivityUnits.MillivoltsPerG, AIExcitationSource.Internal, Convert.ToSingle(0.004), AIAccelerationUnits.G);
                }



                //轧制速度 ai0-ai4通道为模拟电流信号4-20mA  1机架0-550mpm   2机架0-1000mpm   3~5机架0-1700mpm  单位(m/min) ai5：轧制距离 模拟电流信号4-20mA  0-200m锯齿波 单位m  ai6:剪切信号 模拟电流信号4-20mA  <12 无剪切   >12剪切
                // 1#--- 300mpm   2#--  3#---   4#----    -5#--1550mpm 卷取机--1580mpm
                for (int i = 0; i < 8; i++)
                {
                    myTask_Speed.AIChannels.CreateCurrentChannel("L1signal/ai" + i.ToString(), "", (AITerminalConfiguration)(-1), -0.02, 0.02, AICurrentUnits.Amps);
                    //myTask_Cut.DIChannels.CreateChannel("L1bool/ai"+i.ToString(),"", ChannelLineGrouping.OneChannelForAllLines);

                }
                //剪切信号
               // myTask_Cut = new Task();
                //myTask_Cut.DIChannels.CreateChannel(
                //  "L1bool/port0",
                //  "myChannel",
                 // ChannelLineGrouping.OneChannelForAllLines);
                //myDigitalReader = new DigitalSingleChannelReader(myTask_Cut.Stream);

                //cz03
                //myTask_cz03 = new Task();

                //myTask_cz03.DIChannels.CreateChannel(
                 //   "CZ03bool/port0",
                 // "myChannel",
                 // ChannelLineGrouping.OneChannelForAllLines);
               // myDigitalReader2 = new DigitalSingleChannelReader(myTask_cz03.Stream);

                ////轧制距离 模拟电流信号4-20mA  0-200m锯齿波 单位m
                //myTask_Len.AIChannels.CreateCurrentChannel("L1signal/ai5", "", (AITerminalConfiguration)(-1), -0.02, 0.02, AICurrentUnits.Amps);
                ////剪切信号 模拟电流信号4-20mA  <12 无剪切   >12剪切
                //myTask_Cut.AIChannels.CreateCurrentChannel("L1signal/ai6", "", (AITerminalConfiguration)(-1), -0.02, 0.02, AICurrentUnits.Amps);


                //采样速率
                myTask_Analog1.Timing.ConfigureSampleClock("", Convert.ToDouble(SysParam.Instance.sampleFre), SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, 1024);
                myTask_Analog2.Timing.ConfigureSampleClock("", Convert.ToDouble(SysParam.Instance.sampleFre), SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, 1024);
                myTask_Speed.Timing.ConfigureSampleClock("", Convert.ToDouble(SysParam.Instance.sampleFre), SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, 1024);

                ////声明采集任务
                string time1 = DateTime.Now.Second.ToString() + ":" + DateTime.Now.Millisecond.ToString();
                myTask_Analog2.Control(TaskAction.Verify);
                string time2 = DateTime.Now.Second.ToString() + ":" + DateTime.Now.Millisecond.ToString();
                myTask_Analog1.Control(TaskAction.Verify);
                string time3 = DateTime.Now.Second.ToString() + ":" + DateTime.Now.Millisecond.ToString();
                myTask_Speed.Control(TaskAction.Verify);

                ////声明采集任务
                /*string time4 = DateTime.Now.Second.ToString() + ":" + DateTime.Now.Millisecond.ToString();
                myTask_Analog2.Control(TaskAction.Verify);
                string time5 = DateTime.Now.Second.ToString() + ":" + DateTime.Now.Millisecond.ToString();
                myTask_Analog1.Control(TaskAction.Verify);
                string time6 = DateTime.Now.Second.ToString() + ":" + DateTime.Now.Millisecond.ToString();
                myTask_Speed.Control(TaskAction.Verify);*/

                //数据采集
                runningTask1 = myTask_Analog1;
                runningTask2 = myTask_Analog2;
                runningTask3 = myTask_Speed;
                //runningTask4 = myTask_Cut;

                analogInReader1 = new AnalogMultiChannelReader(myTask_Analog1.Stream);
                analogInReader2 = new AnalogMultiChannelReader(myTask_Analog2.Stream);
                analogSpeedReader = new AnalogMultiChannelReader(myTask_Speed.Stream);
                //digitalReader = new DigitalMultiChannelReader(myTask_Cut.Stream);

                analogCallback1 = new AsyncCallback(AnalogInCallback1);
                analogCallback2 = new AsyncCallback(AnalogInCallback2);
                analogCallback3 = new AsyncCallback(AnalogInCallback3);
                //digitalCallback4 = new AsyncCallback(DigitalCallback4);


                myTask_Analog2.Start();
                myTask_Speed.Start();
                //启动采集
                //模拟通道采集同步
                analogInReader1.SynchronizeCallbacks = true;
                analogInReader2.SynchronizeCallbacks = true;
                analogSpeedReader.SynchronizeCallbacks = true;

                analogInReader1.BeginReadMultiSample(SysParam.Instance.samplePoint, analogCallback1, myTask_Analog1);
                analogInReader2.BeginReadMultiSample(SysParam.Instance.samplePoint, analogCallback2, myTask_Analog2);
                analogSpeedReader.BeginReadMultiSample(SysParam.Instance.samplePoint, analogCallback3, myTask_Speed);
                SysParam.Instance.isDatahandlered = true;


               // Cut_timer.Enabled = true;
              //  Cut_timer.Start();
              //  CZ03_timer.Enabled = true;
               // CZ03_timer.Start();
               // CZconnected = new bool[2] { false, false };//CZ02 CZ03 通电状态
            }
            catch (DaqException ex)
            {
                DevelopLog.DeBug.WriteLogFile("ex", ex.ToString());
                throw new Exception("没连接上仪器，请重新连接仪器并重新启动重新" + ex.Message);
            }
        }

        public void DaqStop()
        {
            runningTask1 = null;
            runningTask2 = null;
            runningTask3 = null;
            if (myTask_Analog1 != null)
            {
                myTask_Analog1.Stop();
            }
            if (myTask_Analog2 != null)
            {
                myTask_Analog2.Stop();
            }
            //if (myTask_Cut != null)
            //{
            //    myTask_Cut.Stop();
            //}
            //if (myTask_Len != null)
            //{
            //    myTask_Len.Stop();
            //}
            if (myTask_Speed != null)
            {
                myTask_Speed.Stop();
            }
        //    if (Cut_timer.Enabled)
         //   {
          //      Cut_timer.Stop();
          //  }
           // if (CZ03_timer.Enabled) { 
           //     CZ03_timer.Stop();
           // }
        }

        int countTest = 0;
        private void AnalogInCallback1(IAsyncResult ar)
        {
            if (runningTask1 != null && runningTask1 == ar.AsyncState)
            {
                try
                {
                    //DevelopLog.DeBug.WriteLogFile("AnalogInCallback1", "");
                    analogInReader1.BeginReadMultiSample(SysParam.Instance.samplePoint, analogCallback1, myTask_Analog1);
                    //DevelopLog.DeBug.WriteLogFile("analogInReader1", "");
                    vibdata1 = analogInReader1.EndReadMultiSample(ar);

                    //DevelopLog.DeBug.WriteLogFile("speedInReader2", "");
                    if (countTest == 0)
                    {
                        speeddata = analogSpeedReader.ReadMultiSample(SysParam.Instance.samplePoint);

                        //DevelopLog.DeBug.WriteLogFile("analogInReader2", "");
                        vibdata2 = analogInReader2.ReadMultiSample(SysParam.Instance.samplePoint);
                        countTest++;
                    }

                    if (SysParam.Instance.isDatahandlered)//数据处理未能及时完成时，该帧数据不触发回调
                    {
                        SysParam.Instance.isDatahandlered = false;
                        if (DaqDataChangEvent != null)
                        {
                            DaqDataChangEvent.Invoke(new Daqdata(vibdata1, vibdata2, speeddata, lendata, cutdata));

                        }

                    }

                }
                catch (Exception ex)
                {
                    DevelopLog.DeBug.WriteLogFile("AnalogInCallback1", ex.ToString());
                    //analogInReader1.BeginReadMultiSample(SysParam.Instance.samplePoint, analogCallback1, myTask_Analog1);
                }

            }
        }
        private void AnalogInCallback2(IAsyncResult ar)
        {
            if (runningTask2 == ar.AsyncState)
            {
                //DevelopLog.DeBug.WriteLogFile("AnalogInCallback2", "");
                analogInReader2.BeginReadMultiSample(SysParam.Instance.samplePoint, analogCallback2, myTask_Analog2);
                vibdata2 = analogInReader2.EndReadMultiSample(ar);
            }
        }
        private void AnalogInCallback3(IAsyncResult ar)
        {
            if (runningTask3 == ar.AsyncState)
            {
                //DevelopLog.DeBug.WriteLogFile("AnalogInCallback3", "");
                analogSpeedReader.BeginReadMultiSample(SysParam.Instance.samplePoint, analogCallback3, myTask_Speed);
                speeddata = analogSpeedReader.EndReadMultiSample(ar);
            }
        }

        //private void DigitalCallback4(IAsyncResult ar)
        //{
        //    if (runningTask4 == ar.AsyncState)
        //    {
        //        digitalReader.BeginReadSingleSampleSingleLine(digitalCallback4, myTask_Cut);
        //    }
        //}


        /// <summary>
        /// cz02 剪切信号采集箱
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        public void updateCutFlag(object source, ElapsedEventArgs e)
        {
            try
            {
                bool[] readData;
                //DevelopLog.DeBug.WriteLogFile("updateCutFlag", "test------1-------");
                //Read the digital channel
                readData = myDigitalReader.ReadSingleSampleMultiLine();
                if (readData.Length > 7)
                {
                    CZconnected[0] = readData[0];//cz02状态
                    for (int i = 0; i < 8; i++)
                    {
                        cutdata[i] = (readData[i]) ? 1.0 : 0.0;
                        //DevelopLog.DeBug.WriteLogFile("cutdata", $"[{i}]={cutdata[i]},readData[{i}]={readData[i]}");
                    }
                }

            }
            catch (Exception ex)
            {
                DevelopLog.DeBug.WriteLogFile("updateCutFlag", ex.ToString());
            }
        }

        public void updateCZFlag(object source, ElapsedEventArgs e)
        {
            try
            {
                bool[] readData;
                //DevelopLog.DeBug.WriteLogFile("updateCZFlag", "test------1-------");
                //Read the digital channel
                readData = myDigitalReader2.ReadSingleSampleMultiLine();
                if (readData.Length > 7)
                {
                    CZconnected[1] = readData[0];//cz03状态 
                }

            }
            catch (Exception ex)
            {
                DevelopLog.DeBug.WriteLogFile("updateCZFlag", ex.ToString());
            }
        }

        public delegate void DriverCollectDataHandle(Daqdata data);
        public event DriverCollectDataHandle DaqDataChangEvent;
    }

    public class Daqdata : EventArgs
    {
        public double[,] vibData1;
        public double[,] vibData2;
        public double[,] speedData;
        public double[] lenData;
        public double[] cutData;

        public Daqdata(double[,] indata1, double[,] indata2, double[,] speeddata, double[] lendata, double[] cutdata)
        {
            this.vibData1 = indata1;
            this.vibData2 = indata2;
            this.cutData = cutdata;
            this.lenData = lendata;
            this.speedData = speeddata;
        }
    }

}