using System;
using System.Collections;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using Common;
//using System.Windows.Forms;

namespace BeltScaleSystem
{
    public class SA600Meas 
    {
        /******************* 网络 ***********************/  
        TcpClient tcpClient;              // TCP 类
        string ipAddr = "192.168.185.111";   // IP 地址
        Int32 port = 502;               // 端口
        bool m_alive = false;             // 会话状态
        NetworkStream m_stream = null;    // 数据流
        IPAddress addr = null;            // 端点
        /******************* 可变参数 ***********************/
        byte[] request = new byte[100]; // 请求指令
        byte[] requestz = new byte[100]; // 请求指令
        byte[] respons = new byte[100]; // 响应结果
        byte[] request1 = new byte[100]; // 请求指令//202103LIAO
        byte[] respons1 = new byte[100]; // 响应结果//202103LIAO
        int msgLen = 0;
        int msgLen1 = 0;//202103LIAO
        #region <属性>
        public float Flow;             // 瞬时流量
        public float Total;            // 总累计量
        public float BeltSpeed;        // 皮带速度
        public float FieldTemp;        // 现场温度
        public int Progress;         // 定次进度
        public int ProgressTime;     // 定次时间 
        public float CalibrateValue;   // 校零数值
        //public int StdValue;         // 标定数值//20210201
        public float  StdValue;         // 标定数值  //20210201
        public bool CalibrateFlag = false;//校零完成标志
        public bool MeasStatus = false;//仪表计量状态 true校秤 false计量
        public bool IsConnect = true;//连接状态

        private int connectTimes = 0;//连接次数
        private const int maxConnectTimes = 10;//最大连接次数
        private Log l = Log.GetInstance(); //日志
        //public 
        /// IP地址
        public string IP
        {
            get{
                return ipAddr;
            }
            set
            {
                ipAddr = value;
                connect();
            }
        }       
        #endregion

        #region <构造函数>     
        public SA600Meas()
        {
            initNet();
           
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="addr">IP 地址</param>
        public SA600Meas(string addr)
        {
            ipAddr = addr;
            initNet();
            //initCommand();
        }
        #endregion
        void SwapByte(byte[] data, int startIndex, int endIndex)
        {
            byte temp = 0x00;            
            for (int j = startIndex; j < endIndex; j = j + 4)
            {
                for(int i = 0; i < 4; i= i+2)
                {
                    temp = data[i + j];
                    data[i + j] = data[i + j + 1];
                    data[i + j + 1] = temp;
                    //Swap(ref data[i + j], ref data[i + j + 1]);                    
                }
            }
        }

        private string Byte2String(byte[] data)
        {
            string str = "";
            for (int i = 0; i < data.Length; i++)
            {
                str = str + data[i].ToString("X2") + " ";
            }
            return str;

        }

        public int ReadRing()
        {
            int ret = 0;
            string strCmd = "00 00 00 00 00 06 01 03 03 E8 00 16";//老的，读其它的正常的
             // string strCmd = "00 00 00 00 00 06 01 03 00 02 00 02";  //读标定系数
            string[] arrayHex = strCmd.Split(' ');            
            int  i = 0;
            int dataLen = 0;
            foreach (string hex in arrayHex)
            {
                int intValue = Convert.ToInt32(hex, 16);
                request[i] = Convert.ToByte(intValue);
                i++;
            }
            msgLen = i;
            dataLen = request[msgLen - 1];
            try { 
            m_stream.Write(request, 0, msgLen);
            msgLen = 9 + request[msgLen - 1] * 2;
            ret = m_stream.Read(respons, 0, respons.Length);
            IsConnect = true;
            connectTimes = 0;
                }
            catch (Exception ex)
            {
                if(++connectTimes > maxConnectTimes)IsConnect = false;
                string msg_error = ex.Message;
                connect();
            }

            string strHex1 = Byte2String(respons);
            SwapByte(respons, 9, ret);
            string strHex2 = Byte2String(respons);

            //LogHelper.WriteLogs("sa600", strHex2);

            int startIndex = 9;
            byte[] bts = new byte[4];
            Array.Copy(respons,startIndex,bts,0,4);
            BitArray bits = new BitArray(bts);
            MeasStatus = bits[0];//仪表计量状态
            CalibrateFlag = bits[3];//校秤完成状态
            string str = bits.Length.ToString() + "  ";
            for (int j = 0; j < bits.Length; j++)
            {
                str += bits[j].ToString() + ",";
            }
            startIndex += 4;

            startIndex += 4;

            startIndex += 4;
            Flow = (float)BitConverter.ToUInt32(respons, startIndex) / 100;

            startIndex = startIndex + 4;
            Total = (float)BitConverter.ToUInt32(respons, startIndex) / 1000;

            startIndex = startIndex + 4;
            BeltSpeed = (float)BitConverter.ToUInt32(respons, startIndex) / 100;

            startIndex = startIndex + 4;
            FieldTemp = (float)BitConverter.ToUInt32(respons, startIndex) / 100 - 100;

            startIndex = startIndex + 4;
            Progress = (int)BitConverter.ToUInt32(respons, startIndex);
            startIndex = startIndex + 4;
            ProgressTime = (int)BitConverter.ToUInt32(respons, startIndex);
         
            startIndex = startIndex + 4;
            CalibrateValue = (float)BitConverter.ToUInt32(respons, startIndex)/100000;

            //startIndex = startIndex + 4;  //202103LIAO
            //StdValue = (int)BitConverter.ToUInt32(respons, startIndex);//202103LIAO
            return ret;
        }

        //20210301读标定系数
        public int ReadRingbt()
        {
            int ret1 = 0;
            //string strCmd = "00 00 00 00 00 06 01 03 03 E8 00 16";//老的，读其它的正常的
            string strCmd = "00 00 00 00 00 06 01 03 00 02 00 02";  //读标定系数
            string[] arrayHex = strCmd.Split(' ');
            int i = 0;
            int dataLen = 0;
            foreach (string hex in arrayHex)
            {
                int intValue = Convert.ToInt32(hex, 16);
                request1[i] = Convert.ToByte(intValue);
                i++;
            }
            msgLen1 = i;
            dataLen = request1[msgLen1 - 1];
            try
            {
                m_stream.Write(request1, 0, msgLen1);
                //msgLen = 9 + request[msgLen - 1] * 2;
                if (m_stream!=null) {
                    ret1 = m_stream.Read(respons1, 0, respons1.Length);
                    IsConnect = true;
                    connectTimes = 0;
                }
            }
            catch (Exception ex)
            {
                if (++connectTimes > maxConnectTimes) IsConnect = false;
                string msg_error = ex.Message;
                connect();
            }

            string strHex1 = Byte2String(respons1);
            strHex1 = strHex1.Substring(27, 5);
            //strHex1 ="0x"+strHex1;
            strHex1 = strHex1.Replace(" ", "");
          int xx = Convert.ToInt32(strHex1,16);
          StdValue = (float)xx/10000;
          //  strHex1 = (double)BitConverter.ToUInt32(strHex1,0);
            //startIndex = startIndex + 4;
            //StdValue = (double)BitConverter.ToUInt32(respons, startIndex);

            return ret1;
        }

        //20210301读标定系数

        void InitCmdBuf()
        {
            //文件头
            request[0] = 0x00;
            request[1] = 0x00;
            request[2] = 0x00;
            request[3] = 0x00;
            request[4] = 0x00;
            request[5] = 0x0B;
            //地址
            request[6] = 0x01;
            //功能号
            request[7] = 0x10;
            // 起始地址
            request[8] = 0x00;
            request[9] = 0x00;
            //寄存器数量
            request[10] = 0x00;
            request[11] = 0x02;
            //数据字节数
            request[12] = 0x04;
            //数据
            request[13] = 0x00;
            request[14] = 0x00;
            request[15] = 0x00;
            request[16] = 0x00;
            return ;
        }
       

        private int WriteRing(byte[] data)
        {
                int ret = -1;
            try
            {
                InitCmdBuf();
                if (data.Length == 1)
                {
                    request[14] = data[0];
                }
                else
                {
                    request[13] = data[0];
                    request[14] = data[1];
                }
                msgLen = 17;
                m_stream.Write(request, 0, msgLen);
                msgLen = 8 + request[12];
                ret = m_stream.Read(respons, 0, respons.Length);
                ret = respons[msgLen - ret];

                byte[] bts = new byte[4];
                Array.Copy(respons, 9, bts, 0, 4);
                BitArray bits = new BitArray(bts);
                MeasStatus = bits[2];//仪表计量状态
            }
           catch(Exception ex)
            {
                
                connect();  // 重连
                string msg_error = ex.Message;
               
            }
            return ret;
        }
       // 累计量清零
        public int ClearTotal()
        {
            return WriteRing(new byte[] { 0x40 });
        }

        // 开始校零操作 读校零结果调用ReadRing
        public int StartCalibrateZero()
        {
            return WriteRing(new byte[] { 0x04 });

        }
        // 结束校零操作
        public int StopCalibrateZero()
        {
            int ret = WriteRing(new byte[] { 0x08 });
            CalibrateFlag = false;
            return ret;

        }

        // 保存校零结果
        public int SaveCalibrateValue()
        {
            int ret = WriteRing(new byte[] { 0x01, 0x00 });
            CalibrateFlag = false;
            return ret;

        }
        // 保存标定值
        public int SaveBaseValue(byte[] byteArray)
        {
            //   return WriteRing(byteArray);
            return WriteRing2(byteArray);
        }
        void InitCmdBuf2()
        {
            //0x00 0x00 0x00 0x00 0x00 0x0B 0x01 0x10 0x00 0x02 0x00 0x02 0x04 0x79 0x18 0x00 0x00
            //0    1     2    3    4    5     6   7    8    9     10   11   12   13  14   15   16
            //文件头
            requestz[0] = 0x00;
            requestz[1] = 0x00;
            requestz[2] = 0x00;
            requestz[3] = 0x00;
            requestz[4] = 0x00;
            requestz[5] = 0x0B;
            //地址
            requestz[6] = 0x01;
            //功能号
            requestz[7] = 0x10;
            // 起始地址
            requestz[8] = 0x00;
            requestz[9] = 0x02;
            //寄存器数量
            requestz[10] = 0x00;
            requestz[11] = 0x02;
            //数据字节数
            requestz[12] = 0x04;
            //数据
            requestz[13] = 0x79;
            requestz[14] = 0x18;
            requestz[15] = 0x00;
            requestz[16] = 0x00;
            return;
        }
        private int WriteRing2(byte[] data)
        {
            int ret = -1;
            try
            {
                InitCmdBuf2();
                if (data.Length == 1)
                {
                    requestz[14] = data[0];
                }
                else
                {
                    requestz[13] = data[0];
                    requestz[14] = data[1];
                }
                msgLen = 17;
                m_stream.Write(requestz, 0, msgLen);
                msgLen = 8 + requestz[12];
                ret = m_stream.Read(respons, 0, respons.Length);
                ret = respons[msgLen - ret];

                byte[] bts = new byte[4];
                Array.Copy(respons, 9, bts, 0, 4);
                BitArray bits = new BitArray(bts);
                MeasStatus = bits[2];//仪表计量状态
            }
            catch (Exception ex)
            {

                connect();  // 重连
                string msg_error = ex.Message;
                l.WriteLog(22, "皮带秤写物料参数" + msg_error);
            }
            return ret;
        }
        // 重置仪表
        public int Reset()
        {
            return WriteRing(new byte[] { 0x80});
        }

        /// <summary>
        /// 端口
        /// </summary>
        public Int32 Port
        {
            get
            {
                return port;
            }
            set
            {
                port = value;
            }
        }

        /// <summary>
        ///  初始化网络设置
        /// </summary>
        protected void initNet()
        {
            tcpClient = new TcpClient();
            port = 502;
            m_alive = false;
            addr = IPAddress.Parse(ipAddr);
            // thread = new Thread(sendHeart);
        }    
       
         /// <summary>
        /// 连接
        /// </summary>
        /// <returns>连接状态</returns>
        public void  connect()
        {            
            try
            {
                if (m_stream != null)
                    m_stream.Close();
                if (tcpClient != null)
                    tcpClient.Close();
                tcpClient = new TcpClient();
                addr = IPAddress.Parse(ipAddr);
                tcpClient.Connect(addr, port);
                m_stream = tcpClient.GetStream();
                //m_stream.ReadTimeout = 1000;
                //m_stream.WriteTimeout = 1000;
                m_alive = true;
            }
            catch (Exception ex)
            {
                string error = ex.Message;
                m_alive = false;
                throw new Exception("连接仪表失败！"+ex.Message);
            }              
        }

        // 发送指令给打印机
        public void sendMessage(byte[] data)
        {
            if (!alive()) throw new Exception("发送失败，请检查仪表连接！",null);
                //connect();   
            try
            {
                if (alive())
                {
                    m_stream.Write(data, 0, data.Length);                    
                }
            }
            catch (Exception ex)
            {
                string error = ex.Message;
                //m_alive = false;
                throw new Exception("数据发送失败"+ ex.Message);     //showErrorMessage("数据发送失败！" + ex.Message);                
            }           
        }

        // 判断连接状态
        protected bool alive()
        {
            return m_alive;
        }       

        protected void sendCommand(string strCmd)
        {
            sendMessage(Encoding.Default.GetBytes(strCmd));
        }

    }
}
