using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections;
using System.Net.NetworkInformation;
using GcDevicePc.Common;
using System.IO;

namespace GcDevicePc.ProThread
{
    class HMISearch
    {
        private UdpClient client;
        private IPEndPoint endpoint;
        Thread searchth;
        ManualResetEvent mre = new ManualResetEvent(false);
        public globaldata.DeviceInfo m_DeviceInfo;
        public ArrayList myHMIList = new ArrayList();

        private string FMAC = null;

        private string _localip = null;

        /// <summary>
        /// 构造函数
        /// </summary>
        public HMISearch(String hmimac)
        {
            this.FMAC = hmimac;
            myHMIList.Clear();
            globaldata.DeviceList.Clear();
            GetHmiIp();
        }

        public void ReGetHmiIp()
        {
            GetHmiIp();
        }

        private void GetHmiIp()
        {
            Log.Info("Start Get PC Local IP...");
            try
            {
                string file = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.StartupPath), "GC_Config\\GC_Set\\启动参数\\startup.ini");

                INIOperation test = new INIOperation(file);
                string Meshport = test.INIGetStringValue("NetWorkConfig", "网口", null);

                if (string.IsNullOrEmpty(Meshport))
                {
                    Meshport = "本地连接";
                }

                NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
                foreach (NetworkInterface adapter in nics)
                {
                    if (adapter.Name == Meshport)
                    {
                        bool pd1 = (adapter.NetworkInterfaceType == NetworkInterfaceType.Ethernet || adapter.NetworkInterfaceType == NetworkInterfaceType.Wireless80211); //判断是否是以太网连接
                        if (pd1)
                        {
                            IPInterfaceProperties ip = adapter.GetIPProperties();     //IP配置信息
                            UnicastIPAddressInformationCollection ipCollection = ip.UnicastAddresses;
                            foreach (UnicastIPAddressInformation ipadd in ipCollection)
                            {
                                if (ipadd.Address.AddressFamily == AddressFamily.InterNetwork)
                                    this._localip = ipadd.Address.ToString();//获取ip
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error(e.Message);
            }
        }

        public Boolean ThStart()
        {
            if (String.IsNullOrEmpty(this._localip))
            {
                return false;
            }
            else
            {
                if (mre != null)
                    mre.Reset();
                Log.Info("Start Search HMI...");
                searchth = new Thread(ThreadMethod);
                searchth.IsBackground = true;
                searchth.Start();

                return true;
            }       
        }

        public void ThStop()
        {
            Log.Info("Stop Search HMI...");
            mre.Set();
        }

        public int HMICount()
        {
            return myHMIList.Count;
        }

        private void ThreadMethod()
        {
            //byte[] sendBytes = new byte[] { 0x57, 0x54, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x55, 0xAA };
            byte[] sendBytes = new byte[] { 0x57, 0x54, 0x04, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x55, 0xAA };
            int iReadBytes = 0;

            try
            {
               // client = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
               client = new UdpClient(new IPEndPoint(IPAddress.Parse(this._localip), 0));
                endpoint = new IPEndPoint(IPAddress.Parse("255.255.255.255"), 233);
             //   endpoint = new IPEndPoint(IPAddress.Parse("192.168.10.230"), 233);
                client.Send(sendBytes, sendBytes.Length, endpoint);
                Thread.Sleep(500);

                byte[] recvBytes;
                client.Client.Blocking = false;
                while (!mre.WaitOne(500))
                {
                    iReadBytes = 30;
                    int buffSizeCurrent;
                    buffSizeCurrent = client.Client.Available;
                    if (buffSizeCurrent > 0)
                    {
                        recvBytes = client.Receive(ref endpoint);
                        iReadBytes = recvBytes.Length;
                        DoRecvDataCallBack(recvBytes, iReadBytes);
                    }
                }
            }catch (Exception e)
            {
                Console.WriteLine(e.Message);
            } 
        }

        private Boolean DoRecvDataCallBack(byte[] pcData, int iRecvLength)
        {
            int i;
            int count = 0;
            byte[] pBuf = pcData;
            int iDataLength = 0;
         
            if (iRecvLength < 8)
                return false;

            if ((pBuf[0] == (byte)0x57) && (pBuf[1] == (byte)0x54) && (pBuf[iRecvLength - 2] == (byte)0x55) && (pBuf[iRecvLength - 1] == (byte)0xAA))
            {
                iDataLength = (int)(pBuf[2] & 0xFF)
                                | (int)((pBuf[3] & 0xFF) << 8)
                                | (int)((pBuf[4] & 0xFF) << 16)
                                | (int)((pBuf[5] & 0xFF) << 24);

                if ((iDataLength >= 4) && (iRecvLength == 8 + iDataLength))
                {                   
                    ASCIIEncoding asciiEncoding = new ASCIIEncoding();
                    m_DeviceInfo.bActive = false;
                                      
                    for (i = 0; i < 100; i++ )
                    {
                        if (asciiEncoding.GetString(pBuf, 6 + i, 1) == "\0")
                            break;
                        count++;
                    }
                    m_DeviceInfo.ModuleName = String.Format("{0}", asciiEncoding.GetString(pBuf, 6, count));
                    //脱机
                    //m_DeviceInfo.ModuleName = String.Format("{0}{1}{2}{3}", asciiEncoding.GetString(pBuf, 6, 1),
                    //                                                                  asciiEncoding.GetString(pBuf, 7, 1),
                    //                                                                    asciiEncoding.GetString(pBuf, 8, 1),
                    //                                                                    asciiEncoding.GetString(pBuf, 9, 1));
                    //m_DeviceInfo.MacAddr = String.Format("{0}:{1}:{2}:{3}:{4}:{5}", pBuf[10], pBuf[11], pBuf[12], pBuf[13], pBuf[14], pBuf[15]);
                    //m_DeviceInfo.IpAddr = String.Format("{0}.{1}.{2}.{3}", pBuf[16], pBuf[17], pBuf[18], pBuf[19]);
                    //m_DeviceInfo.Netmask = String.Format("{0}.{1}.{2}.{3}", pBuf[20], pBuf[21], pBuf[22], pBuf[23]);
                    //m_DeviceInfo.Gateway = String.Format("{0}.{1}.{2}.{3}", pBuf[24], pBuf[25], pBuf[26], pBuf[27]);

                    m_DeviceInfo.MacAddr = String.Format("{0:X2}:{1:X2}:{2:X2}:{3:X2}:{4:X2}:{5:X2}", pBuf[106], pBuf[107], pBuf[108], pBuf[109], pBuf[110], pBuf[111]);
                    m_DeviceInfo.IpAddr = String.Format("{0}.{1}.{2}.{3}", pBuf[112], pBuf[113], pBuf[114], pBuf[115]);
                    m_DeviceInfo.Netmask = String.Format("{0}.{1}.{2}.{3}", pBuf[116], pBuf[117], pBuf[118], pBuf[119]);
                    m_DeviceInfo.Gateway = String.Format("{0}.{1}.{2}.{3}", pBuf[120], pBuf[121], pBuf[122], pBuf[123]);

                    string tmpmac = String.Format("{0:X2}:{1:X2}:{2:X2}:{3:X2}:{4:X2}:{5:X2}", pBuf[106], pBuf[107], pBuf[108], pBuf[109], pBuf[110], pBuf[111]);
                    if (!string.IsNullOrEmpty(FMAC))
                    {
                        if (FMAC == tmpmac)
                        {
                            if (m_DeviceInfo.IpAddr != "0.0.0.0")
                            {
                                globaldata.DeviceList.Add(m_DeviceInfo);
                                myHMIList.Add(m_DeviceInfo);
                            }
                        }
                    }else
                    {
                        globaldata.DeviceList.Add(m_DeviceInfo);
                        myHMIList.Add(m_DeviceInfo);
                    }   
                    return true;
                }
            }
            return false;
        }
    }
}
