using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using GcDevicePc.IniParam;

namespace GcDevicePc
{
    class GcDataReq
    {
        string strIP = null;
        ushort netPost = 0;
        bool setflag = false;
      //  int losenum = 0;
        Modbus m_modbus;
        public float[] gctemp = new float[12] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        public uint[] gcstate = new uint[6] { 0, 0, 0, 0, 0, 0 };
        public byte[] valvestate = new byte[4];
        public byte[] detstate = new byte[3];

        //public int[] channel1_timer = new int[30];
        //public float[] channel1_data = new float[30];
        GcDevicePc.DevParam.UNION_TEMP channel1_value;
        GcDevicePc.DevParam.UNION_TEMP utemp;

        public int Max_Time;
        public int Get_Channel1_ValueNum;

        Thread t_GetData;
        Thread t_GetChannelData;
        Thread t_WriteData;

        public GcDataReq(string ip, ushort post)
        {

           
           if (IsValidIp(ip) && post > 0)
           {
               m_modbus = new Modbus();
               this.strIP = ip;
               this.netPost = post;
               this.setflag = true;
           }
           else
           {
               this.setflag = false;
           }
        }

        ~GcDataReq()
        {
            this.strIP = null;
            this.netPost = 0;
            this.setflag = false;
        }

        bool IsValidIp(string strIn)
        {
            return true;
            //return Regex.IsMatch(strIn, @"^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$");
        }

        public void GetVal(ushort address ,ref UInt16 []buf)
        {
            System.UInt16[] dest = new System.UInt16[2] { 0, 0};
            if (this.setflag)
                m_modbus.ReadHoldingReg(0, 1, this.strIP, this.netPost, ref dest);  
        
           // Console.WriteLine(dest[0].ToString());
           // Console.WriteLine(dest[1].ToString());
        }

        //读设备温度
        public void GetTemp(ushort address, ushort num, ref float []temp)
        {
            System.UInt16[] dest = new System.UInt16[num];
            int ret;
        
            ret = m_modbus.ReadHoldingReg(address, num, this.strIP, this.netPost, ref dest);        

            for (int i = 0; i < 12; i +=2)
            {
                utemp.t.usCurTemp_Word1 = dest[i];
                utemp.t.usCurTemp_Word2 = dest[i+1];
                temp[i/2] = utemp.fCurTemp;
            }

            int no = 6;
            for (int j = 16; j < 22; j++)
            {
                temp[no] = (dest[j]);
                no++;
            }
        }

        public void Get_Channel1_Data(ushort address, ushort num) // ref int[] ctimer, ref float[] cvalue)
        {
            Get_Channel1_ValueNum = 0;
            System.UInt16[] dest = new System.UInt16[num];
            int ret;
            if (this.setflag)
                ret = m_modbus.ReadHoldingReg(address, num, this.strIP, this.netPost, ref dest);

            int tmp;
            int j = 0;

            for (int i = 0; i < num; )
            {
                tmp = dest[i + 1];
                tmp  <<= 16;
                tmp = tmp + dest[i];

                if(Max_Time < tmp)
                {
                    Max_Time = tmp;
                    globaldata.Channel1_Port.ctimer = tmp;
                    channel1_value.t.usCurTemp_Word1 = dest[i + 2];
                    channel1_value.t.usCurTemp_Word2 = dest[i + 3];
                    globaldata.Channel1_Port.cdata = channel1_value.fCurTemp;
                    j++;
                    Get_Channel1_ValueNum ++;
                    globaldata.Draw_Port.Add(globaldata.Channel1_Port);
                }                   
                i += 4;
            }         
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="address"></param>
        /// <param name="num"></param>
        /// <param name="temp"></param>
        public void GetValveState(ushort address, ushort num, ref byte[] temp)
        {          
            if (this.setflag)
               m_modbus.ReadCoilStatus(address, num, this.strIP, this.netPost, ref temp);
        }

        public void GetDetectorState(ushort address, ushort num, ref byte[] temp)
        {
            if (this.setflag)
                m_modbus.ReadCoilStatus(address, num, this.strIP, this.netPost, ref temp);
        }

        public void GetState(ushort address, ushort num, ref uint []state )
        {
            System.UInt16[] dest = new System.UInt16[num];
            if (this.setflag)
                m_modbus.ReadHoldingReg(address, num, this.strIP, this.netPost, ref dest);

            for (int i = 0; i < num; i ++)
            {
                state[i] = dest[i];
            }       
        }

        //获取数据
        //获取温度数据
        public void GetGCTemp( ref float []temp)
        {     
            GetTemp(globaldata.tempstart , 24, ref temp);    
        }

        //获取状态数据
        public void GetGCState(ref uint []state)
        {
            GetState(globaldata.statusstart, 6,ref state);
        }

        //获取链路数据
        public void get_channel_data()
        {
            Get_Channel1_Data(160, 120);
        }

        public void update_data()
        {
            GetGCTemp(ref this.gctemp);
           
            CProfileDevice.m_DevParam.port[0].fHeaterTempActual = gctemp[0];
            CProfileDevice.m_DevParam.port[1].fHeaterTempActual = gctemp[4];
            CProfileDevice.m_DevParam.col.fCurTemp.fCurTemp = gctemp[3];
            CProfileDevice.m_DevParam.col.fColTempActual = gctemp[3];

            if (CProfileDevice.m_DevParam.syspara.u16DetFront == 1)
            {
                if (CProfileDevice.m_DevParam.syspara.u16DetFrontType == 1)  //TCD
                {
                    CProfileDevice.m_DevParam.fid[0].fHeaterActualTemp = gctemp[1];
                    if(globaldata.system_Statue)
                        CProfileDevice.m_DevParam.fid[0].fHeaterTempSet = gctemp[7];

                }
                else if (CProfileDevice.m_DevParam.syspara.u16DetFrontType == 0)
                {
                    CProfileDevice.m_DevParam.tcd[0].fHeaterTempActual = gctemp[1];
                    if (globaldata.system_Statue)
                        CProfileDevice.m_DevParam.tcd[0].fHeaterTempSet = gctemp[7];
                }
            }

            if (CProfileDevice.m_DevParam.syspara.u16DetInter == 1)
            {
                if (CProfileDevice.m_DevParam.syspara.u16DetInterType == 1)  //TCD
                {
                    CProfileDevice.m_DevParam.fid[1].fHeaterActualTemp = gctemp[2];
                    if (globaldata.system_Statue)
                        CProfileDevice.m_DevParam.fid[1].fHeaterTempSet = gctemp[8];

                }
                else if (CProfileDevice.m_DevParam.syspara.u16DetInterType == 0)
                {
                    CProfileDevice.m_DevParam.tcd[1].fHeaterTempActual = gctemp[2];
                    if (globaldata.system_Statue)
                        CProfileDevice.m_DevParam.tcd[1].fHeaterTempSet = gctemp[8];
                }
            }

            if (CProfileDevice.m_DevParam.syspara.u16DetBehind == 1)
            {

                if (CProfileDevice.m_DevParam.syspara.u16DetBehindType == 1)  //TCD
                {
                    CProfileDevice.m_DevParam.fid[2].fHeaterActualTemp = gctemp[5];
                    if (globaldata.system_Statue)
                        CProfileDevice.m_DevParam.fid[2].fHeaterTempSet = gctemp[11];

                }
                else if (CProfileDevice.m_DevParam.syspara.u16DetBehindType == 0)
                {
                    CProfileDevice.m_DevParam.tcd[2].fHeaterTempActual = gctemp[5];
                    if (globaldata.system_Statue)
                        CProfileDevice.m_DevParam.tcd[2].fHeaterTempSet = gctemp[11];
                }
            }


            if (CProfileDevice.m_DevParam.syspara.u16AuxHeaterNum > 0)
            {
                if (CProfileDevice.m_DevParam.syspara.u16AuxHeater1 == 1)  //TCD
                {
                    CProfileDevice.m_DevParam.aux.fActualTemp_HeatArea1 = gctemp[2];
                    if (globaldata.system_Statue)
                        CProfileDevice.m_DevParam.aux.fSetTemp_HeatArea1 = gctemp[8];
                }
                
                if (CProfileDevice.m_DevParam.syspara.u16AuxHeater2 == 1)
                {
                    CProfileDevice.m_DevParam.aux.fActualTemp_HeatArea2 = gctemp[5];
                    if (globaldata.system_Statue)
                        CProfileDevice.m_DevParam.aux.fSetTemp_HeatArea2 = gctemp[11];                 
                }

            }

            if (globaldata.system_Statue)
            {
                CProfileDevice.m_DevParam.port[0].fHeaterSetTempm = gctemp[6];
                CProfileDevice.m_DevParam.port[1].fHeaterSetTempm = gctemp[10];
                CProfileDevice.m_DevParam.col.fColTempSet = gctemp[9];
            }
           
            GetGCState(ref this.gcstate);


            GetValveState(globaldata.valusstatus, 4, ref valvestate);

            CProfileDevice.m_DevParam.valve.ValveStatus[0] = (((valvestate[0] >> 0) & 0x1) == 1) ? '1' : '0';
            CProfileDevice.m_DevParam.valve.ValveStatus[1] = (((valvestate[0] >> 1) & 0x1) == 1) ? '1' : '0';
            CProfileDevice.m_DevParam.valve.ValveStatus[2] = (((valvestate[0] >> 2) & 0x1) == 1) ? '1' : '0';
            CProfileDevice.m_DevParam.valve.ValveStatus[3] = (((valvestate[0] >> 3) & 0x1) == 1) ? '1' : '0';
             
     
            GetDetectorState(globaldata.detstatus, 3, ref detstate);          
            CProfileDevice.m_DevParam.fid[0].u16IsFire =(ushort) ((((detstate[0] >> 0) & 0x1) == 1) ? 1 : 0);
            CProfileDevice.m_DevParam.fid[1].u16IsFire =(ushort) ((((detstate[0] >> 0) & 0x1) == 1) ? 1 : 0);
            CProfileDevice.m_DevParam.fid[2].u16IsFire =(ushort) ((((detstate[0] >> 0) & 0x1) == 1) ? 1 : 0);
              
        }

        public void WriteSingleVal()
        {
            int ret;
            ushort mystate = (ushort)0x1;
            if (globaldata.connection_ip != null)
                ret = m_modbus.WriteHoldingReg(147, mystate, globaldata.connection_ip, globaldata.datamodbusport);
        }

        public void WriteBatVal()
        {
            int ret;
            ushort mystate = (ushort)0x1;
            if (globaldata.connection_ip != null)
                ret = m_modbus.WriteHoldingReg(148, mystate, globaldata.connection_ip, globaldata.datamodbusport);
        }

        public void WriteOpenVal()
        {
            int ret;
            ushort mystate = (ushort)0x1;
            if (globaldata.connection_ip != null)
                ret = m_modbus.WriteHoldingReg(150, mystate, globaldata.connection_ip, globaldata.datamodbusport);
        }


        public void WriteStartVal()
        {
            int ret;
            if (globaldata.connection_ip != null)
                ret = m_modbus.WriteSingleCoil(30, (ushort)65280, globaldata.connection_ip, globaldata.datamodbusport);          

        }

        public void WriteStopVal()
        {
            int ret;
            if (globaldata.connection_ip != null)
                ret = m_modbus.WriteSingleCoil(31, (ushort)65280, globaldata.connection_ip, globaldata.datamodbusport);

        }

        public void WriteEndVal()
        {
            int ret;
            if (globaldata.connection_ip != null)
                ret = m_modbus.WriteSingleCoil(33, (ushort)65280, globaldata.connection_ip, globaldata.datamodbusport);

        }

        public void WriteCancalVal()
        {
            int ret;
            if (globaldata.connection_ip != null)
                ret = m_modbus.WriteSingleCoil(32, (ushort)65280, globaldata.connection_ip, globaldata.datamodbusport);
        }

        public ushort ReadRunStatus()
        {
            ushort num = 0;;
            System.UInt16[] dest = new System.UInt16[1] { 0};
            if (globaldata.connection_ip != null)
            {
                m_modbus.ReadHoldingReg(149, 1, globaldata.connection_ip, globaldata.datamodbusport, ref dest);
                num = dest[0];              
            }
            return num;
        }

        public void FireUPWork(ushort time1,ushort time2)
        {
            //int ret;
            ushort mystate = (ushort)0x1;
            if (globaldata.connection_ip != null)
            {
                m_modbus.WriteHoldingReg(153, time1, globaldata.connection_ip, globaldata.datamodbusport);
                m_modbus.WriteHoldingReg(154, time2, globaldata.connection_ip, globaldata.datamodbusport);
                m_modbus.WriteHoldingReg(155, mystate, globaldata.connection_ip, globaldata.datamodbusport);
            }              
        }


        public void WriteStart()
        {
            t_WriteData = new Thread(WriteProc);
            t_WriteData.IsBackground = true;
            t_WriteData.Start();
        }

        public void Start()
        {
            t_GetData = new Thread(GetDataProc);
            t_GetData.IsBackground = true;
            t_GetData.Start();

            t_GetChannelData = new Thread(GetChannelDataProc);
            t_GetChannelData.IsBackground = true;
            t_GetChannelData.Start();
        }

        public void WriteStop()
        {
            t_WriteData.Abort();
        }

        public void Stop()
        {
            if(t_GetData.ThreadState  == ThreadState.Running)
            {
                t_GetData.Abort();
            }

            if (t_GetChannelData.ThreadState == ThreadState.Running)
            {
                t_GetChannelData.Abort();
            } 
        }

        public void WriteProc()
        {
            while (true)
            {
                //WriteVal();
                Thread.Sleep(1000);
            }
        }

        public void GetDataProc()
        {
            while(true)
            {
                update_data();
                Thread.Sleep(1000);
            }

        }

        public void GetChannelDataProc()
        {
            while (true)
            {
                get_channel_data();
                Thread.Sleep(50);
            }
        }
    }
}
