using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using GcDevicePc;
using GcDevicePc.Common;
using GcDevicePc.Controls;
using Ini.Net;

namespace GcDevicePc.ProThread
{
    class CPipeCtl
    {
        ManualResetEvent datamre = new ManualResetEvent(false);

        Thread s_data;

        public void DataToSPStart()
        {
            if (datamre != null)
            {
                datamre.Reset();
            }
            s_data = new Thread(GetIniConfig);
            s_data.IsBackground = true;
            s_data.Start();
        }

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

        #region 系统变量

        /// <summary>
        /// 初始通气时间
        /// </summary>
        public int Initialtime { get; set; }

        /// <summary>
        /// 间隔延时时间
        /// </summary>
        public int Intervaltime { get; set; }

        /// <summary>
        /// 清洗管路时间
        /// </summary>
        public int Cleantime { get; set; }

        /// <summary>
        /// 压缩样气时间
        /// </summary>
        public int Compresstime { get; set; }

        /// <summary>
        /// 定量进样时间
        /// </summary>
        public int Entrytime { get; set; }

        /// <summary>
        /// 样气平衡时间
        /// </summary>
        public int Balancetime { get; set; }

        /// <summary>
        /// 采数时间
        /// </summary>
        public int Acquisitiontime { get; set; }

        /// <summary>
        /// 等待结束时间
        /// </summary>
        public int Waitingtime { get; set; }

        /// <summary>
        /// 循环次数
        /// </summary>
        public int Cycletimes { get; set; }

        /// <summary>
        /// 当前控制器状态
        /// </summary>
        public char NowCtlstate { get; set; }

        /// <summary>
        /// 通气管路
        /// </summary>
        public int Nowpipe { get; set; }

        /// <summary>
        /// 采数管路
        /// </summary>
        //public int Lastpipe { get; set; }

        /// <summary>
        /// 控制器状态
        /// </summary>
        public enum CTLState
        {
            //通气
            STATE_AERATOIN_A = 65,
            //延时
            STATE_DELAY_B = 66,
            //清洗
            STATE_CLEAR_C = 67,
            //压缩
            STATE_COMPRESS_D = 68,
            //进样
            STATE_SAMPLE_E = 69,
            //平衡
            STATE_BALANCE_F = 70,
            //采数
            STATE_COLLECT_G = 71,
            //结束
            STATE_END_H = 72,
            //停止
            STATE_STOP_N = 78
        }

        /// <summary>
        /// 单独继电器
        /// </summary>
        public enum Relay
        {
            RELAY_SAMPLE = 13,
            RELAY_CLEAR,
            RELAY_CTLVALVE,
            RELAY_PUMP
            
        }

        //当前循环的管路序号
        private int CurrentLoops;

        //循环管路数量
        private int pipeCount;
        
        //设备在线状态
        public bool onlineState;

        //开始循环状态
        public bool runState;

        private static string Path = @".\Switch.ini";//配置文件位置

        //private string[] command = iniFile.ReadString("Command", "Command").Split(',');//协议内容

        //循环束管
        private StringBuilder tap = new StringBuilder();

        //配置文件实例
        private static IniFile iniFile;


        //private static HMIControl hmiControl = new HMIControl(globaldata.connection_ip,502);


        //串口实例
        private SerialPort comport = new SerialPort();
        
        delegate void HandleInterfaceUpdateDelegate(string text);

        #endregion

        //协议解析
        public void Protocol(string protocol)
        {
            string[] m = protocol.Split(' ');
            switch (m[0].Length > 1 ? m[0][1].ToString() : "Y")
            {
                case "G":
                    if (onlineState && !runState)
                    {
                        //if (globaldata.m_hmibuffer.gcinfo.methodstatus == 3)
                        {
                            runState = true;

                            Nowpipe = 0;

                            CurrentLoops = 0;

                            TimerStop();

                            GetPipe();

                            StartLoop();
                        }
                    }

                    break;
                case "H":
                    if (onlineState && runState)
                    {
                        runState = false;

                        NowCtlstate = (char) CTLState.STATE_STOP_N;

                        Nowpipe = 0;

                        CurrentLoops = 0;

                        TimerStop();

                        switchController.SwitchAllClose();
                        switchController.SwitchClose((int)Relay.RELAY_CTLVALVE);
                        switchController.SwitchClose((int)Relay.RELAY_PUMP);
                    }

                    break;
                case "I":
                    if (!onlineState)
                    {
                        onlineState = true;
                    }

                    break;
                case "J":
                    if (onlineState)
                    {
                        onlineState = false;
                    }

                    break;
                case "L":
                    if (onlineState && !runState)
                    {
                        //MessageBox.Show("控制器向前选择路管号");
                    }

                    break;
                case "N":
                    if (onlineState && !runState)
                    {
                        //MessageBox.Show("控制器向后选择路管号");
                    }

                    break;
                case "Q":
                    if (onlineState && !runState)
                    {
                        SetConfig(m);
                    }

                    break;
                case "R":
                    if (onlineState && !runState)
                    {
                        SetConfig(m);
                    }

                    break;
                case "T":
                    if (onlineState && !runState)
                    {
                        SetConfig(m);
                    }

                    break;
                default:
                    break;
            }
        }

        //停止时间
        private void TimerStop()
        {
            tAcquisition.Stop();
            tBalance.Stop();
            tClean.Stop();
            tCompress.Stop();
            tEntry.Stop();
            tInitial.Stop();
            tInterval.Stop();
            tWait.Stop();
        }

        //获取管路
        private void GetPipe()
        {
            string[] port = iniFile.ReadString("ControllerSet", "kQ").Split(' ');
            StringBuilder sb = new StringBuilder();
            
            foreach (string b in port)
            {
                if (b.Equals("0"))
                {
                    sb.Append("0000");
                }
                else
                {
                    string t = "";
                    Int32 tmp = Convert.ToInt32(b, 16);
                    t = Convert.ToString(tmp, 2);
                    for (int i = 0; i < 4 - t.Length; i++)
                    {
                        sb.Append("0");
                    }
                    sb.Append(t);
                    //sb.Append(Convert.ToString(Convert.ToInt32(b, 16), 2));
                }
            }

            tap.Clear();
            for (int i = 0; i < sb.Length; i++)
            {
                if (Convert.ToInt32(sb[i].ToString()) == 1)
                {
                    tap.Append((i + 1) + " ");
                }
            }

            pipeCount = tap.ToString().Split(' ').Length - 1;
            Cycletimes = int.Parse(iniFile.ReadString("ControllerSet", "kR").Split(' ')[0]);

            SendProtocol(tap.ToString());
            SendProtocol(sb.ToString());

        }

        #region 发送协议
        /// <summary>
        /// 发送控制器状态
        /// </summary>
        /// <param name="state"></param>
        /// <param name="now"></param>
        public void SendCtlState(char state, int now)
        {
            //int lastpipe = 0;
            //if (CurrentLoops == 0)
            //{
            //    lastpipe = 0;
            //}
            //else
            //{
            //    lastpipe = Convert.ToInt32(tap.ToString().Split(' ')[CurrentLoops - 1]);
            //}
            

            string s = string.Format("kU {0} {1:D2} {2:D2}\r", state, now, now);
            SendProtocol(s);
        }

        /// <summary>
        /// 回馈
        /// </summary>
        /// <param name="text"></param>
        public void SendProtocol(string text)
        {
            if (!comport.IsOpen)
                return;
            try
            {
                // Send the user's text straight out the port
                comport.Write(text);
                //LogManage.Instance.AddLogOper("发送："+text);
            }
            catch (FormatException)
            {
                //MessageBox.Show("send error.");
            }
           
        }

        /// <summary>
        /// 发送循环状态
        /// </summary>
        /// <param name="count">剩余循环次数</param>
        public void SendLoops(int count)
        {
            string s = string.Format("kV {0:D2}\r", count);
            SendProtocol(s);
        }

        /// <summary>
        /// 启动工作站信息
        /// </summary>
        public void Sendoffline()
        {
            string s = string.Format("kW\r");
            SendProtocol(s);
        }

        /// <summary>
        /// 发送联机状态
        /// </summary>
        public void Sendonline()
        {
            string s = string.Format("kZ\r");
            SendProtocol(s);
        }

        /// <summary>
        /// 启动工作站信息
        /// </summary>
        public void SendColl()
        {
            string s = string.Format("kX\r");
            SendProtocol(s);
        }


        //public void SendStarColl()
        //{
        //    string s = string.Format("kN\r");
        //    SendProtocol(s);
        //}

        //public void SendinitStar()
        //{
        //    string s = string.Format("kG\r");
        //    SendProtocol(s);
        //}
        #endregion

        //public delegate void testDelegate(string text);

        //public event testDelegate mainThread;

        //获取协议
        public void UpdateReceiveText(string text)
        {
            //mainThread(text);
            string[] schar = text.Split('\r');
            //LogManage.Instance.AddLogOper("获取："+text);

            for (int i = 0; i < schar.Length; i++)
            {
                Protocol(schar[i].ToString());
                
            }

        }

        ushort mparity;
        int mubaudrate;
        byte muport;
        int mutimeout;

        int tBaudRate;
        int tDataBits;
        StopBits tStopBits;
        Parity tParity;
        string tPortName;

        public void GetIniConfig()
        {
            try
            {
                iniFile = new IniFile(Path);

                this.mparity = Convert.ToUInt16(iniFile.ReadInteger("RTUMasterSet", "parity"));
                this.mubaudrate = iniFile.ReadInteger("RTUMasterSet", "ubaudrate");
                this.muport = (byte)iniFile.ReadInteger("RTUMasterSet", "uport");
                this.mutimeout = iniFile.ReadInteger("RTUMasterSet", "utimeout");

                this.tBaudRate = iniFile.ReadInteger("PortSet", "Baud");
                this.tDataBits = iniFile.ReadInteger("PortSet", "Databits");
                //this.tStopBits = iniFile.ReadInteger("PortSet", "StopBits") == 1 ? StopBits.One : StopBits.One;
                //this.tParity = iniFile.ReadInteger("PortSet", "Parity") == 0 ? Parity.None : Parity.None;

                this.tParity = Parity.None;
                this.tStopBits = StopBits.One;
                this.tPortName = iniFile.ReadString("PortSet", "Ports");

                PipInitial(mparity, mubaudrate, muport, mutimeout, tBaudRate, tDataBits, tStopBits, tParity, tPortName);

            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
            }

        }

        SwitchController switchController;
        //继电器初始
        public bool PipInitial(ushort mparity, int mubaudrate, byte muport, int mutimeout, int tBaudRate, int tDataBits, StopBits tStopBits, Parity tParity, string tPortName)
        {

            switchController = SwitchController.GetInstance(mparity, mubaudrate, muport, mutimeout);


            if (switchController.OpenModbusRtu() && SetPort(tBaudRate, tDataBits, tStopBits, tParity, tPortName))
            {
                NowCtlstate = (char)CTLState.STATE_STOP_N;
                SetTimePro();

                comport.DataReceived += new SerialDataReceivedEventHandler(comport_DataReceived);

                switchController.SwitchAllClose();
                switchController.SwitchClose((int)Relay.RELAY_CTLVALVE);

                RegTimers();

                _otherTimer.Tick += tElectrified_Tick; ;
                _otherTimer.Interval = 100; //每秒执行
                _otherTimer.Start();

                return true;
            }
            else
            {
                return false;
            }

        }

        //缓冲区
        private List<byte> buffer = new List<byte>(1024);

        public void comport_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;

            int bytes = sp.BytesToRead;

            byte[] buf = new byte[bytes];

            comport.Read(buf, 0, bytes);

            buffer.AddRange(buf);

            if (buf[buf.Length-1]==13)
            {
                string data = String.Empty;
                for (int i = 0; i < buffer.Count; i++)
                {
                    data = data + (char)buffer[i];
                }
                UpdateReceiveText(data);
                
                buffer.Clear();
            }
            
            
        }

        //设置配置文件
        private void SetConfig (string[] m)
        {
            StringBuilder str = new StringBuilder();

            for (int i = 1; i < m.Length; i++)
            {
                str.Append(" " + m[i]);
            }
            iniFile.WriteString("ControllerSet", m[0].ToString(), str.ToString());

        }

        //开始循环
        public void StartLoop()
        {
            if (CurrentLoops > pipeCount-1)
            {
                CurrentLoops = 0;
            }

            Nowpipe = Convert.ToInt32(tap.ToString().Split(' ')[CurrentLoops]);

            switchController.SwitchAllClose();

            switchController.SwitchClose((int)Relay.RELAY_PUMP);
            NowCtlstate = (char)CTLState.STATE_AERATOIN_A;
            
            time = Initialtime;
            tInitial.Start();
            
            

        }

        //所需timer控件
        private MillisecondTimer _otherTimer = new MillisecondTimer();

        private MillisecondTimer tInitial = new MillisecondTimer();

        private MillisecondTimer tInterval = new MillisecondTimer();

        private MillisecondTimer tBalance = new MillisecondTimer();

        private MillisecondTimer tCompress = new MillisecondTimer();

        private MillisecondTimer tEntry = new MillisecondTimer();

        private MillisecondTimer tAcquisition = new MillisecondTimer();

        private MillisecondTimer tClean = new MillisecondTimer();

        private MillisecondTimer tWait = new MillisecondTimer();

        private void RegTimers()
        {
            tInitial.Interval = 100;
            tInterval.Interval = 100;
            tBalance.Interval = 100;
            tCompress.Interval = 100;
            tEntry.Interval = 100;
            tAcquisition.Interval = 100;
            tClean.Interval = 100;
            tWait.Interval = 100;

            tInitial.Tick += tInitial_Tick;
            tInterval.Tick += tInterval_Tick;
            tBalance.Tick += tBalance_Tick;
            tCompress.Tick += tCompress_Tick;
            tEntry.Tick += tEntry_Tick;
            tAcquisition.Tick += tAcquisition_Tick;
            tClean.Tick += tClean_Tick;
            tWait.Tick += tWait_Tick;

        }

        //设置流程时间
        public void SetTimePro()
        {
            string[] kt = iniFile.ReadString("ControllerSet", "kT").Split(' ');
            Intervaltime = int.Parse(kt[1]) * 600;
            Initialtime = int.Parse(kt[0]) * 600;
            Entrytime = int.Parse(kt[4]) * 600;
            Cycletimes = int.Parse(iniFile.ReadString("ControllerSet", "kR").Split(' ')[0]);
            Compresstime = int.Parse(kt[3]) * 600;
            Cleantime = int.Parse(kt[2]) * 600;
            Balancetime = int.Parse(kt[5]) * 600;
            Acquisitiontime = int.Parse(kt[6]) * 600;
            Waitingtime = int.Parse(kt[7]) * 600;

        }

        //设置串口
        public bool SetPort(int tBaudRate, int tDataBits, StopBits tStopBits, Parity tParity, string tPortName)
        {
            try
            {
                comport.BaudRate = tBaudRate;
                comport.DataBits = tDataBits;
                comport.StopBits = tStopBits;
                comport.Parity = tParity;
                comport.PortName = tPortName;
                comport.Open();

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);

                return false;
                //throw;
            }

        }

        #region 时间控制
        
        private int time = 0;

        //初始通气
        private void tInitial_Tick(object sender, EventArgs e)
        {

            time = time - tInitial.Interval;
                
            if (time == 0)
            {
                NowCtlstate = (char)CTLState.STATE_DELAY_B;

                time = Intervaltime;
                switchController.SwitchOpen((int)Relay.RELAY_SAMPLE);
                switchController.SwitchOpen((int)Relay.RELAY_PUMP);
                switchController.SwitchOpen((int)Relay.RELAY_CTLVALVE);

                tInitial.Stop();
                tInterval.Start();
                //tCompress.Start();
            }
        }

        //间隔延时
        private void tInterval_Tick(object sender, EventArgs e)
        {
            time = time - tInterval.Interval;

            if (time == 0)
            {
                NowCtlstate = (char)CTLState.STATE_COMPRESS_D;

                time = Compresstime;
                switchController.SwitchOpen(Nowpipe);
                tInterval.Stop();
                //tBalance.Start();
                tCompress.Start();
            }
        }

        //压缩样气
        private void tCompress_Tick(object sender, EventArgs e)
        {
            time = time - tCompress.Interval;
            if (time == 0)
            {
                NowCtlstate = (char)CTLState.STATE_BALANCE_F;

                switchController.SwitchAllClose();
                switchController.SwitchClose((int)Relay.RELAY_SAMPLE);
                switchController.SwitchClose((int)Relay.RELAY_PUMP);

                time = Balancetime;

                tCompress.Stop();
                //tInterval.Start();
                tBalance.Start();
            }
        }

        //样气平衡
        private void tBalance_Tick(object sender, EventArgs e)
        {
            time = time - tBalance.Interval;
            if (time == 0)
            {
                NowCtlstate = (char)CTLState.STATE_SAMPLE_E;
                time = Entrytime;
                //int ret =  hmiControl.WriteStartVal();
                //if (ret != 0)
                //{
                //    int count = 3;
                //    while (count > 0 )
                //    {
                //        ret = hmiControl.WriteStartVal();
                //        if (ret == 0)
                //        {
                //            break;
                //        }
                //        else
                //        {
                //            Console.WriteLine("开始失败");
                //            count--;
                //            //Thread.Sleep(1000);
                //        }

                        
                //    }
                //}
                //Thread.Sleep(000);
                tBalance.Stop();
                tEntry.Start();
            }
        }

        //定量进样
        private void tEntry_Tick(object sender, EventArgs e)
        {
            if (globaldata.m_hmibuffer.gcinfo.methodstatus >= 3)
            {
                time = time - tEntry.Interval;
            }
            
            if (time == 0)
            {
                //NowCtlstate = (char)CTLState.STATE_CLEAR_C;
                NowCtlstate = (char)CTLState.STATE_COLLECT_G;

                SendColl();
                
                //SendStarColl();


                time = Acquisitiontime;
                //time = Cleantime;
                Thread.Sleep(5000);
                tEntry.Stop();
                tAcquisition.Start();
                //tClean.Start();
            }
        }

        //采集数据
        private void tAcquisition_Tick(object sender, EventArgs e)
        {
            if (globaldata.m_hmibuffer.gcinfo.methodstatus == 4 || globaldata.m_hmibuffer.gcinfo.methodstatus == 5)
            {
                if (time == 100)
                {
                    time = time + 100;
                }
                time = time - tAcquisition.Interval;
                if (time == 0)
                {
                    if (Nowpipe == Convert.ToInt32(tap.ToString().Split(' ')[pipeCount - 1]))
                    {
                        Cycletimes = Cycletimes - 1;
                    }
                    NowCtlstate = (char)CTLState.STATE_CLEAR_C;
                    switchController.SwitchOpen((int)Relay.RELAY_CLEAR);
                    switchController.SwitchOpen((int)Relay.RELAY_PUMP);
                    time = Cleantime;
                    tAcquisition.Stop();
                    tClean.Start();

                }
            }
            else if (globaldata.m_hmibuffer.gcinfo.methodstatus > 5 || globaldata.m_hmibuffer.gcinfo.methodstatus <= 3)
            {
                //hmiControl.WriteStartVal();
                //tAcquisition.Stop();
                if (Nowpipe == Convert.ToInt32(tap.ToString().Split(' ')[pipeCount - 1]))
                {
                    Cycletimes = Cycletimes - 1;
                }
                NowCtlstate = (char)CTLState.STATE_CLEAR_C;
                switchController.SwitchOpen((int)Relay.RELAY_CLEAR);
                switchController.SwitchOpen((int)Relay.RELAY_PUMP);
                time = Cleantime;
                tAcquisition.Stop();
                tClean.Start();


                //if (Cycletimes != 0)
                //{
                //    CurrentLoops++;
                //    StartLoop();
                //}
                //else
                //{
                //    Console.WriteLine("开始等待时间。。。");
                //    NowCtlstate = (char)CTLState.STATE_END_H;
                //    CurrentLoops = 0;
                //    time = Waitingtime;
                //    tWait.Start();
                //}
            }

        }

        //清洗管路
        private void tClean_Tick(object sender, EventArgs e)
        {
            time = time - tClean.Interval;
            if (time == 0)
            {
                //NowCtlstate = (char)CTLState.STATE_COLLECT_G;
                //time = Acquisitiontime;
                
                //if (Nowpipe == Convert.ToInt32(tap.ToString().Split(' ')[pipeCount - 2]))
                //{
                //    Cycletimes = Cycletimes - 1;
                //}

                if (Cycletimes != 0)
                {
                    CurrentLoops++;
                    StartLoop();
                }
                else
                {
                    Console.WriteLine("开始等待时间。。。");
                    NowCtlstate = (char)CTLState.STATE_END_H;
                    CurrentLoops = 0;
                    time = Waitingtime;
                    tWait.Start();
                }
                tClean.Stop();
            }
        }

        //等待结束
        private void tWait_Tick(object sender, EventArgs e)
        {
            time = time - tWait.Interval;
            if (time == 0)
            {
                NowCtlstate = (char)CTLState.STATE_STOP_N;
                Nowpipe = 0;
                Cycletimes = int.Parse(iniFile.ReadString("ControllerSet", "kR").Split(' ')[0]);
                tWait.Stop();
                switchController.SwitchAllClose();
                switchController.SwitchClose((int)Relay.RELAY_CTLVALVE);
                switchController.SwitchClose((int)Relay.RELAY_PUMP);
                switchController.SwitchClose((int)Relay.RELAY_CLEAR);

            }
        }

        //程序进入时开启发送
        private void tElectrified_Tick(object sender, EventArgs e)
        {
            SendCtlState(NowCtlstate, Nowpipe);
            if (NowCtlstate.Equals((char)CTLState.STATE_STOP_N))
            {
                SendLoops(0);
            }
            else
            {
                SendLoops(Cycletimes);
            }
            if (onlineState)
            {
                Sendonline();
            }
            else
            {
                Sendoffline();
            }
        }

        #endregion


    }
}
