using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Management;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AssistClient.Utils
{
    public static class Util
    {
        private static Regex RegNumber = new Regex("^[0-9]+$");                     //匹配　整数（不可以带正负号）

        public static string byteArrayToHexString(byte[] data)
        {
            StringBuilder sb = new StringBuilder(data.Length * 3);
            foreach (byte b in data)
            {
                sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));
            }

            return sb.ToString().ToUpper();
        }
        /// <summary>
        /// 获取适合大小
        /// </summary>
        /// <param name="sourceSize"></param>
        /// <param name="targetSize"></param>
        /// <returns></returns>
        public static Size getNewSize(Size sourceSize, Size targetSize)
        {
            if (sourceSize.Width <= targetSize.Width && sourceSize.Height <= targetSize.Height)
                return sourceSize;

            int num = sourceSize.Width / targetSize.Width;
            int num2 = sourceSize.Height / targetSize.Height;
            int num3 = (num < num2) ? num2 : num;
            return new Size(sourceSize.Width / num3, sourceSize.Height / num3);
        }
        /// <summary>
        /// 等比计算宽高
        /// </summary>
        /// <param name="sourceSize"></param>
        /// <param name="targetSize"></param>
        /// <returns></returns>
        public static SizeF getNewSize(SizeF sourceSize, SizeF targetSize)
        {
            if (sourceSize.Width <= targetSize.Width && sourceSize.Height <= targetSize.Height)
                return sourceSize;

            float num = sourceSize.Width / targetSize.Width;
            float num2 = sourceSize.Height / targetSize.Height;
            float num3 = (num < num2) ? num2 : num;
            return new SizeF(sourceSize.Width / num3, sourceSize.Height / num3);
        }
        ///  <summary>
        ///   写INI文件
        ///  </summary>
        ///  <param  name="Section">Section</param>
        ///  <param  name="Key">Key</param>
        ///  <param  name="value">value</param>
        public static void WriteIniValue(string filePath, string Section, string Key, string value)
        {
            API.WritePrivateProfileString(Section, Key, value, filePath);
        }

        ///  <summary>
        ///    读取INI文件指定部分
        ///  </summary>
        ///  <param  name="Section">Section</param>
        ///  <param  name="Key">Key</param>
        ///  <returns>String</returns>  
        public static string ReadIniValue(string filePath, string Section, string Key)
        {
            StringBuilder temp = new StringBuilder(255);
            int i = API.GetPrivateProfileString(Section, Key, "", temp, 255, filePath);
            return temp.ToString().Trim();
        }
        /// <summary>
        /// 整数
        /// </summary>
        /// <param name="inputData"></param>
        /// <returns></returns>
        public static bool IsNumber(string inputData)
        {
            Match m = RegNumber.Match(inputData);
            return m.Success;
        }
        public static string file2Base64(string filePath)
        {
            return Convert.ToBase64String(File.ReadAllBytes(filePath));
        }
        /// <summary>
        /// 结构体转byte数组
        /// </summary>
        /// <param name="structObj">要转换的结构体</param>
        /// <returns>转换后的byte数组</returns>
        public static byte[] StructToBytes(object structObj)
        {
            int size = Marshal.SizeOf(structObj);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.StructureToPtr(structObj, buffer, false);
                byte[] bytes = new byte[size];
                Marshal.Copy(buffer, bytes, 0, size);
                return bytes;
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }

        }
        /// <summary>
        /// byte数组转结构体
        /// </summary>
        /// <param name="bytes">byte数组</param>
        /// <param name="type">结构体类型</param>
        /// <returns>转换后的结构体</returns>
        public static object BytesToStruct(byte[] bytes, Type strcutType)
        {
            int size = Marshal.SizeOf(strcutType);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(bytes, 0, buffer, size);
                return Marshal.PtrToStructure(buffer, strcutType);
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }
        /// <summary>
        /// 是否为系统不可操作窗体（如桌面、任务栏等）
        /// </summary>
        /// <returns></returns>
        public static bool IsSysWin(IntPtr WinHwnd)
        {
            if (WinHwnd != IntPtr.Zero)
            {
                StringBuilder lsbClassName = new StringBuilder(256);
                API.GetClassName(WinHwnd, lsbClassName, 256 - 1);

                string lsWinClassName = lsbClassName.ToString().ToLower();
                return (lsWinClassName == "progman" || lsWinClassName == "shell_traywnd");
            }

            return false;
        }

        public static bool DisableDevice(string sDeviceID)
        {
            try
            {
                if (sDeviceID == null || sDeviceID.Trim() == "" || !System.IO.File.Exists(System.Environment.SystemDirectory + "\\devcon.exe"))
                    return false;

                string[] lsDeviceIDs = sDeviceID.Split(new char[] { ';', ',' });
                ProcessStartInfo info;

                for (int i = 0; i < lsDeviceIDs.Length; i++)
                {
                    if (lsDeviceIDs[i].Trim() == "") continue;

                    info = new ProcessStartInfo();
                    info.FileName = System.Environment.SystemDirectory + "\\devcon.exe";    // 要启动的程序
                    info.Arguments = "disable " + lsDeviceIDs[i];               //传递给程序的参数
                    info.WindowStyle = ProcessWindowStyle.Hidden;   //隐藏窗口
                    Process pro = Process.Start(info); //启动程序
                }
                return true;
            }
            catch
            {
                return false;
            }
        }
        public static bool EnableDevice(string sDeviceID)
        {
            try
            {
                if (sDeviceID == null || sDeviceID.Trim() == "" || !System.IO.File.Exists(System.Environment.SystemDirectory + "\\devcon.exe"))
                    return false;

                string[] lsDeviceIDs = sDeviceID.Split(new char[] { ';' });
                ProcessStartInfo info;

                for (int i = 0; i < lsDeviceIDs.Length; i++)
                {
                    if (lsDeviceIDs[i].Trim() == "") continue;

                    info = new ProcessStartInfo();
                    info.FileName = System.Environment.SystemDirectory + "\\devcon.exe";    // 要启动的程序
                    info.Arguments = "enable " + lsDeviceIDs[i];               //传递给程序的参数
                    info.WindowStyle = ProcessWindowStyle.Hidden;   //隐藏窗口
                    Process pro = Process.Start(info); //启动程序
                }
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 获取时间戳   
        /// </summary>
        public static string GetTimestamp()
        {
            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            DateTime dtNow = DateTime.Now;
            TimeSpan toNow = dtNow.Subtract(dtStart);
            System.Random rand = new Random();

            string timeStamp = toNow.Ticks.ToString() + rand.Next(9);
            return timeStamp;
        }

        /// <summary>
        /// 获取MD5串(未转大小写)   
        /// </summary>
        public static string GetMD5(string str)
        {
            return GetMD5(str, Encoding.UTF8);
        }
        public static string GetMD5(string str, Encoding ed)
        {
            byte[] data = ed.GetBytes(str);
            data = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(data);

            string ret = "";
            for (int i = 0; i < data.Length; i++)
            {
                ret += data[i].ToString("x1").PadLeft(2, '0');//ToString("x1"):转换为16进制
            }
            return ret;
        }
        /// <summary>
        /// 获取MD5串(未转大小写)   
        /// </summary>
        public static string GetMD5(byte[] data)
        {
            data = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(data);

            string ret = "";
            for (int i = 0; i < data.Length; i++)
            {
                ret += data[i].ToString("x1").PadLeft(2, '0');//ToString("x1"):转换为16进制
            }
            return ret;
        }

        /// <summary>
        /// MD5 16位加密 
        /// </summary>
        /// <param name="ConvertString"></param>
        /// <returns></returns>
        public static string GetMd5_16bit(string data)
        {
            System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(data)), 4, 8);
            t2 = t2.Replace("-", "");
            return t2;
        }
        public static string GetMd5_16bit(byte[] data)
        {
            System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            string t2 = BitConverter.ToString(md5.ComputeHash(data), 4, 8);
            t2 = t2.Replace("-", "");
            return t2;
        }
        public static string subString(string text, int leftLen)
        {
            if (text == null || text.Length < leftLen)
                return text;

            return text.Substring(0, leftLen) + "...";
        }
        public static string GetHardwareIDHashCode()
        {
            string lsID = GetCpuID() + GetHDID() + GetMacID();
            return lsID;
        }
        //cpu序列号
        private static string GetCpuID()
        {
            try
            {
                string cpuInfo = "";
                ManagementClass cimobject = new ManagementClass("Win32_Processor");
                ManagementObjectCollection moc = cimobject.GetInstances();
                foreach (ManagementObject mo in moc)
                {
                    cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
                    //label1.Text += "cpu序列号：" + cpuInfo.ToString() + "\n";
                }

                return cpuInfo;
            }
            catch { return ""; }
        }
        //获取硬盘ID
        private static string GetHDID()
        {
            try
            {
                string HDid = "";
                ManagementClass cimobject1 = new ManagementClass("Win32_DiskDrive");
                ManagementObjectCollection moc1 = cimobject1.GetInstances();
                foreach (ManagementObject mo in moc1)
                {
                    HDid = (string)mo.Properties["Model"].Value;
                    //label1.Text += "硬盘序列号：" + HDid.ToString() + "\n";
                }

                return HDid;
            }
            catch { return ""; }
        }
        //获取网卡硬件MAC地址
        private static string GetMacID()
        {
            try
            {
                string Mac1 = "";
                ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
                ManagementObjectCollection moc2 = mc.GetInstances();
                foreach (ManagementObject mo in moc2)
                {
                    if ((bool)mo["IPEnabled"] == true)
                    {
                        Mac1 = mo["MacAddress"].ToString();
                        //label1.Text += "MAC address\t{0}" + Mac1 + "\n";
                        mo.Dispose();
                        break;
                    }
                    mo.Dispose();
                }

                return Mac1;
            }
            catch { return ""; }
        }

        //获取计算机其它信息
        public static string GetPCOtherInfo()
        {
            string lsInfo;
            string lsName = System.Net.Dns.GetHostName();
            lsInfo = "计算机名称：" + lsName + " ";

            // 获得本机局域网IP地址 
            System.Net.IPAddress addr = new System.Net.IPAddress(System.Net.Dns.GetHostByName(lsName).AddressList[0].Address);
            lsInfo += "局域网内IP地址：" + addr.ToString();

            //
            return lsInfo;
        }

        /// <summary>
        /// 模糊匹配字符串
        /// </summary>
        /// <param name="fullValue"></param>
        /// <param name="allKeys"></param>
        /// <param name="matchCase"></param>
        /// <param name="mustFirst"></param>
        /// <returns></returns>
        public static bool find_Fuzzy(string fullValue, List<string> allKeys, bool matchCase = true, bool mustFirst = true)
        {
            if (!matchCase)
                fullValue = fullValue.ToLower();

            string keyName = "";
            allKeys.ForEach(key => {
                int index = fullValue.IndexOf(matchCase ? key : key.ToLower());
                if (index > -1)
                {
                    if (mustFirst)
                    {
                        if (index == 0)
                        {
                            keyName = key;
                            return;
                        }
                    }
                    else
                    {
                        keyName = key;
                        return;
                    }
                }
            });

            return keyName != "";
        }

        public static JObject getPropertys(Object o, string[] skipPropertys)
        {
            JObject data = new JObject();

            Type t = o.GetType();//获得该类的Type 
            //再用Type.GetProperties获得PropertyInfo[],然后就可以用foreach 遍历了
            foreach (PropertyInfo pi in t.GetProperties())
            {
                object value1 = pi.GetValue(o, null);//用pi.GetValue获得值
                string name = pi.Name;//获得属性的名字,后面就可以根据名字判断来进行些自己想要的操作
                                      //获得属性的类型,进行判断然后进行以后的操作,例如判断获得的属性是整数
                if (value1 == null)
                {
                    data.Add(name, null);
                }
                else
                {
                    Type type = value1.GetType();
                    if (type == typeof(string) || type == typeof(int) || type == typeof(float) || type == typeof(double) || type == typeof(decimal))
                    {
                        data.Add(name, value1.ToString());
                    }
                }
            }
            return data;
        }

        /// <summary>  
        /// 获取文件对应MIME类型  
        /// </summary>  
        /// <param name="fileExtention">文件扩展名,如.jpg</param>  
        /// <returns></returns>  
        public static string GetContentType(string fileExtention)
        {
            if (string.Compare(fileExtention, ".html", true) == 0 || string.Compare(fileExtention, ".htm", true) == 0)
                return "text/html;charset=utf-8";
            else if (string.Compare(fileExtention, ".js", true) == 0)
                return "application/javascript";
            else if (string.Compare(fileExtention, ".css", true) == 0)
                return "text/css";
            else if (string.Compare(fileExtention, ".png", true) == 0)
                return "image/png";
            else if (string.Compare(fileExtention, ".jpg", true) == 0 || string.Compare(fileExtention, ".jpeg", true) == 0)
                return "image/jpeg";
            else if (string.Compare(fileExtention, ".gif", true) == 0)
                return "image/gif";
            else if (string.Compare(fileExtention, ".swf", true) == 0)
                return "application/x-shockwave-flash";
            else if (string.Compare(fileExtention, ".bcmap", true) == 0)
                return "image/svg+xml";
            else if (string.Compare(fileExtention, ".properties", true) == 0)
                return "application/octet-stream";
            else if (string.Compare(fileExtention, ".map", true) == 0)
                return "text/plain";
            else if (string.Compare(fileExtention, ".svg", true) == 0)
                return "image/svg+xml";
            else if (string.Compare(fileExtention, ".pdf", true) == 0)
                return "application/pdf";
            else if (string.Compare(fileExtention, ".txt", true) == 0)
                return "text/*";
            else if (string.Compare(fileExtention, ".dat", true) == 0)
                return "text/*";
            else
                return "application/octet-stream";//application/octet-stream

        }

        /// <summary>
        /// mm转像素
        /// </summary>
        /// <param name="mm"></param>
        /// <param name="dpi">PDF=72(默认) 显示器=96</param>
        /// <returns></returns>
        public static int mm2px(float mm, int dpi = 72)
        {
            return (int)((dpi / 25.4f) * mm);
        }
        /// <summary>
        /// 像素转mm
        /// </summary>
        /// <param name="px"></param>
        /// <param name="dpi">PDF=72(默认) 显示器=96</param>
        /// <returns></returns>
        public static float px2mm(int px, int dpi = 72)
        {
            return px / (dpi / 25.4f);
        }
         
        public static void addKey(JObject obj, string key, JToken value)
        {
            if (obj.ContainsKey(key))
                obj[key] = value;
            else
                obj.Add(key, value);
        }
        /// <summary>
        /// IO二进制数据格式化到8位 XXXX10X0
        /// </summary>
        /// <param name="datas"></param>
        /// <returns></returns>
        public static string[] IODataFormatBinaryStr(string[] datas, bool clone,char defaultPadChar='X')
        {
            string[] datas2= new string[datas.Length];
            for(int i = 0;i < datas.Length; i++)
            {
                if (clone)
                {
                    datas2[i] = datas[i].Replace(" ", "");
                    if (datas2[i].Length > 8)
                        datas2[i] = datas2[i].Substring(datas2[i].Length - 8);
                    else if (datas2[i].Length < 8)
                        datas2[i] = datas2[i].PadLeft(8, defaultPadChar);
                }
                else
                {
                    datas[i] = datas[i].Replace(" ", "");
                    if (datas[i].Length > 8)
                        datas[i] = datas[i].Substring(datas[i].Length - 8);
                    else if (datas[i].Length < 8)
                        datas[i] = datas[i].PadLeft(8, defaultPadChar);

                    datas2 = datas;
                }
            }

            return datas2;
        }
        public static byte[] IOFormatBinary2bytes(string[] datas)
        {
            byte[] result=new byte[datas.Length];
            string str;
            for (int i = 0; i < datas.Length; i++)
            {
                str = "";
                datas[i] = datas[i].Replace(" ", "");
                for (int j = 0; j < datas[i].Length; j++)
                { 
                    if (datas[i][j] == '1' || datas[i][j] == 'H')
                        str += "1";
                    else
                        str += "0";
                }
                result[i] = Convert.ToByte(str, 2);
            }

            return result;
        }
        public static void showRowNum_onDataGrid_RowPostPaint(DataGridView dgv, object sender, DataGridViewRowPostPaintEventArgs e)
        {
            Rectangle rectangle = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y, dgv.RowHeadersWidth - 4, e.RowBounds.Height);
            TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(), dgv.RowHeadersDefaultCellStyle.Font, rectangle, dgv.RowHeadersDefaultCellStyle.ForeColor, TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="op_show_list">[XXHL XXXX,XXXX XXXX,...]</param>
        /// <param name="currIoDatas">[byte,byte,byte,byte]</param>
        /// <returns></returns>
        public static bool compareIOInput(string[] op_show_list, byte[] currIoDatas)
        {
            int isok = 0;//1-true 2-false
            string IN_OP_SHOW;
            for (int i = 0; i < currIoDatas.Length; i++)
            {
                IN_OP_SHOW = op_show_list[i].Replace(" ", "").PadLeft(8, 'X');
                if (IN_OP_SHOW.IndexOf('H') < 0 && IN_OP_SHOW.IndexOf('L') < 0)
                    continue;

                for (int j = 7; j >= 0; j--)
                {
                    byte bit = (byte)(1 << 7 - j);
                    if (IN_OP_SHOW[j] == 'H')
                    {
                        if ((bit & currIoDatas[i]) > 0)
                            isok = 1;
                        else
                        {
                            isok = 2;
                            break;
                        }
                    }
                    else if (IN_OP_SHOW[j] == 'L')
                    {
                        if ((currIoDatas[i] ^ (currIoDatas[i] | bit)) > 0)
                            isok = 1;
                        else
                        {
                            isok = 2;
                            break;
                        }
                    }
                }

                //已经不符
                if (isok == 2) break;
            }

            //
            return isok == 1;
        }
       

    }
}
