using MWS.Library.Enums;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml;

namespace MWS.Library.Common
{
    public static class Tool
    {
        private static readonly ConcurrentDictionary<Enum, string> _CacheDescriptions = new ConcurrentDictionary<Enum, string>();
        public static string GenUUID()
        {
            return System.Guid.NewGuid().ToString("N");
        }
        /// <summary>
        /// 把对象转换为JSON字符串
        /// </summary>
        /// <param name="o">对象</param>
        /// <returns>JSON字符串</returns>
        public static string ToJSON(this object o)
        {
            if (o == null)
            {
                return null;
            }
            return JsonConvert.SerializeObject(o);
        }
        /// <summary>
        /// 把Json文本转为实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="input"></param>
        /// <returns></returns>
        public static T FromJSON<T>(this string input)
        {

            try
            {
                return JsonConvert.DeserializeObject<T>(input);
            }
            catch (Exception ex)
            {
                return default(T);
            }
        }
        /// <summary>
        /// 单位转换 单位 id 0 正常 1 档位 2 重量 3 行程、高度 4 载荷  5 电流 6 电压 7 速度 8 振幅 9 温度 10 力矩  11 频率 12 虚拟档位
        /// </summary>
        /// <param name="unitStr"></param>
        /// <returns></returns>
        public static string UintTran(string unitStr)
        {
            string result = "";
            switch (unitStr)
            {
                case "0":
                    result = "";
                    break;
                case "2":
                    result = " T";
                    break;
                case "3":
                    result = " m";
                    break;
                case "4":
                    result = " T";
                    break;
                case "5":
                    result = " A";
                    break;
                case "6":
                    result = " V";
                    break;
                case "7":
                    result = " m/s";
                    break;
                case "9":
                    result = " ℃";
                    break;
                case "8":
                    result = " mm";
                    break;
                case "11":
                    result = " Hz";
                    break;
                case "10":
                    result = " Nm";
                    break;

                case "12":
                    result = " ";
                    break;
                default:
                    break;
            }
            return result;
        }
        /// <summary>
        /// 挡位转换
        /// </summary>
        /// <param name="mecType"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GearConvert(MecType mecType, string value)
        {
            int gear = 0;
            try
            {

                gear = System.Convert.ToInt32(value);

            }
            catch (Exception)
            {
                gear = 0;

            }
            //MecType mecType = (MecType)parameter;
            string s1 = "";
            string s2 = "";
            string ret = "";

            switch (mecType)
            {
                // 起升机构
                case MecType.Hoist:
                    //case MecType.ViceHoist:
                    //case MecType.MainViceHoist:
                    //case MecType.ViceViceHoist:
                    s1 = "上升";
                    s2 = "下降";
                    break;
                //大车机构
                case MecType.BigCar:
                    s1 = "左行";
                    s2 = "右行";
                    break;
                //小车机构
                case MecType.SmallCar:
                    //case MecType.ViceCar:
                    s1 = "前行";
                    s2 = "后行";
                    break;
            }

            if (gear > 0)
            {
                ret = s1 + gear + "档";
            }
            if (gear < 0)
            {
                ret = s2 + (-gear) + "档";
            }
            if (gear == 0)
            {
                ret = "0档";
            }
            return ret;
        }
        public static string GetLightColor(int switchType, string value)
        {
            string Light = "";
            switch (switchType)
            {
                case 1:
                    if (value == "True")
                    {
                        Light = "#4BD77B";
                    }
                    else
                    {
                        Light = "#90919E";
                    }
                    break;
                case 2:
                    if (value == "True")
                    {
                        Light = "#FFA100";
                    }
                    else
                    {
                        Light = "#4BD77B";
                    }
                    break;
                case 3:
                    if (value == "True")
                    {
                        Light = "#F24660";
                    }
                    else
                    {
                        Light = "#4BD77B";
                    }
                    break;
                default:
                    break;
            }
            return Light;
            //if (!bool.TryParse(value, out bool boolValue))
            //{
            //    return @"/Resources/RealTime/gray.png";
            //}
            //if (boolValue)
            //{
            //    return switchType == 1 ? @"/Resources/RealTime/green.png" : switchType == 2 ? @"/Resources/RealTime/yellow.png" : @"/Resources/RealTime/red.png";
            //}
            //else
            //{
            //    return switchType == 1 ? @"/Resources/RealTime/gray.png" : @"/Resources/RealTime/green.png";
            //}

        }

        /// <summary>
        /// 判断两个相同引用类型的对象的属性值是否相等
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj1">对象1</param>
        /// <param name="obj2">对象2</param>
        /// <param name="type">按type类型中的属性进行比较</param>
        /// <returns></returns>
        public static bool CompareProperties<T>(T obj1, T obj2, Type type)
        {
            //为空判断
            if (obj1 == null && obj2 == null)
                return true;
            else if (obj1 == null || obj2 == null)
                return false;

            Type t = type;
            PropertyInfo[] props = t.GetProperties();
            foreach (var po in props)
            {
                if (IsCanCompare(po.PropertyType))
                {
                    if (!po.GetValue(obj1).Equals(po.GetValue(obj2)))
                    {
                        return false;
                    }
                }
                else
                {
                    return CompareProperties(po.GetValue(obj1), po.GetValue(obj2), po.PropertyType);
                }
            }

            return true;
        }

        /// <summary>
        /// 该类型是否可直接进行值的比较
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        private static bool IsCanCompare(Type t)
        {
            if (t.IsValueType)
            {
                return true;
            }
            else
            {
                //String是特殊的引用类型，它可以直接进行值的比较
                if (t.FullName == typeof(String).FullName)
                {
                    return true;
                }
                return false;
            }
        }


        #region 获取url字符串 参数
        /// <summary>
        /// 将查询字符串解析转换为名值集合.
        /// </summary>
        /// <param name="queryString"></param>
        /// <returns></returns>
        public static NameValueCollection GetQueryString(string queryString)
        {
            return GetQueryString(queryString, null, true);
        }

        /// <summary>
        /// 将查询字符串解析转换为名值集合.
        /// </summary>
        /// <param name="queryString"></param>
        /// <param name="encoding"></param>
        /// <param name="isEncoded"></param>
        /// <returns></returns>
        public static NameValueCollection GetQueryString(string queryString, Encoding encoding, bool isEncoded)
        {
            queryString = queryString.Split('?')[1];
            NameValueCollection result = new NameValueCollection(StringComparer.OrdinalIgnoreCase);
            if (!string.IsNullOrEmpty(queryString))
            {
                int count = queryString.Length;
                for (int i = 0; i < count; i++)
                {
                    int startIndex = i;
                    int index = -1;
                    while (i < count)
                    {
                        char item = queryString[i];
                        if (item == '=')
                        {
                            if (index < 0)
                            {
                                index = i;
                            }
                        }
                        else if (item == '&')
                        {
                            break;
                        }
                        i++;
                    }
                    string key = null;
                    string value = null;
                    if (index >= 0)
                    {
                        key = queryString.Substring(startIndex, index - startIndex);
                        value = queryString.Substring(index + 1, (i - index) - 1);
                    }
                    else
                    {
                        key = queryString.Substring(startIndex, i - startIndex);
                    }
                    if (isEncoded)
                    {
                        result[MyUrlDeCode(key, encoding)] = MyUrlDeCode(value, encoding);
                    }
                    else
                    {
                        result[key] = value;
                    }
                    if ((i == (count - 1)) && (queryString[i] == '&'))
                    {
                        result[key] = string.Empty;
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 解码URL.
        /// </summary>
        /// <param name="encoding">null为自动选择编码</param>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string MyUrlDeCode(string str, Encoding encoding)
        {
            if (encoding == null)
            {
                Encoding utf8 = Encoding.UTF8;
                //首先用utf-8进行解码                     
                string code = HttpUtility.UrlDecode(str.ToUpper(), utf8);
                //将已经解码的字符再次进行编码.
                string encode = HttpUtility.UrlEncode(code, utf8).ToUpper();
                if (str == encode)
                    encoding = Encoding.UTF8;
                else
                    encoding = Encoding.GetEncoding("gb2312");
            }
            return HttpUtility.UrlDecode(str, encoding);
        }
        #endregion


        public static string Hump2Underline(string str)
        {
            string ret = "";  //目标字符串
            for (int j = 0; j < str.Length; j++)  //strItem是原始字符串
            {
                string temp = str[j].ToString();
                if (Regex.IsMatch(temp, "[A-Z]"))
                {
                    temp = temp.ToLower();
                    if (!j.Equals(0))
                    {
                        temp = "_" + temp;
                    }
                }
                ret += temp;
            }
            return ret;
        }
        /// <summary>
        /// 移除开头字符串
        /// </summary>
        /// <param name="str">待处理字符串</param>
        /// <param name="removeStr">要移除掉的字符串</param>
        /// <returns></returns>
        public static string RemoveStarWithString(string str, string[] removeStr)
        {
            foreach (var item in removeStr)
            {
                if (!item.IsNullOrEmptyOrWhiteSpace())
                {
                    if (str.IndexOf(item) == 0)
                    {
                        return str.Substring(item.Length);
                    }
                }

            }
            return str;
        }

        /// <summary>
        /// 执行Cmd命令
        /// </summary>
        /// <param name="workingDirectory">要启动的进程的目录</param>
        /// <param name="command">要执行的命令</param>
        public static void StartCmd(String workingDirectory, String command)
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.WorkingDirectory = workingDirectory;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            p.Start();
            p.StandardInput.WriteLine(command);
            p.StandardInput.WriteLine("exit");
        }


        [DllImport("gdi32.dll", SetLastError = true)]
        private static extern bool DeleteObject(IntPtr hObject);


        public static bool PathToByte(string path, out byte[] buffer)
        {
            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
            try
            {
                buffer = new byte[fs.Length];
                fs.Read(buffer, 0, (int)fs.Length);
                return true;
            }
            catch (Exception ex)
            {
                buffer = null;
                return false;
            }
            finally
            {
                if (fs != null)
                {
                    //关闭资源   
                    fs.Close();
                }
            }

        }
        public static void ModifyAppConfigAppSetting(string path, string key, string value)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(path);
            XmlNode node = doc.SelectSingleNode(@"//add[@key='" + key + "']");
            XmlElement ele = (XmlElement)node;
            ele.SetAttribute("value", value);
            doc.Save(path);
        }

        public static void ModifyAppConfigConStr(string path, string key, string value)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(path);
            XmlNode node = doc.SelectSingleNode(@"//add[@name='" + key + "']");
            XmlElement ele = (XmlElement)node;
            ele.SetAttribute("connectionString", value);
            doc.Save(path);
        }
        public static void UpdateAppConfig(string newKey, string newValue)
        {
            bool isModified = false;
            foreach (string key in ConfigurationManager.AppSettings)
            {
                if (key == newKey)
                {
                    isModified = true;
                }
            }
            System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            if (isModified)
            {
                config.AppSettings.Settings.Remove(newKey);
            }
            config.AppSettings.Settings.Add(newKey, newValue);
            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");
        }
        public static T ToEnum<T>(string name)
        {
            Type typeFromHandle = typeof(T);
            if (typeFromHandle.IsEnum)
            {
                return (T)Enum.Parse(typeof(T), name, true);
            }
            throw new InvalidCastException("必须是枚举类型才能转换。");
        }
        /// <summary>
        /// ping IP
        /// </summary>
        /// <param name="ipStr"></param>
        /// <returns></returns>
        public static IPStatus GetIpStatus(string ipStr)
        {
            try
            {

                Ping pingSender = new Ping();
                return pingSender.Send(ipStr, 1).Status;//第一个参数为ip地址，第二个参数为ping的时间

            }
            catch (Exception)
            {
                return IPStatus.Unknown;
            }
        }

        /// <summary>
        /// 计算两个时间差 多少秒
        /// </summary>
        /// <param name="DateTime1"></param>
        /// <param name="DateTime2"></param>
        /// <returns></returns>
        public static int DateDiffSecond(DateTime DateTime1, DateTime DateTime2)
        {
            TimeSpan ts = DateTime1.Subtract(DateTime2).Duration();
            return Convert.ToInt32(ts.TotalSeconds);
        }
        /// <summary>
        /// 计算两个时间差 多少毫秒秒
        /// </summary>
        /// <param name="DateTime1"></param>
        /// <param name="DateTime2"></param>
        /// <returns></returns>
        public static int DateDiffMillisecond(DateTime DateTime1, DateTime DateTime2)
        {
            TimeSpan ts = DateTime1.Subtract(DateTime2).Duration();
            return Convert.ToInt32(ts.TotalMilliseconds);
        }

        /// <summary>
        /// 计算两个时间差多少分钟
        /// </summary>
        /// <param name="DateTime1"></param>
        /// <param name="DateTime2"></param>
        /// <returns></returns>
        public static int DateDiffMin(DateTime DateTime1, DateTime DateTime2)
        {
            TimeSpan ts = DateTime1.Subtract(DateTime2).Duration();
            return Convert.ToInt32(ts.TotalMinutes);
        }
        public static String GetEnumDesc(this Type e, int? value)
        {
            FieldInfo[] fields = e.GetFields();
            for (int i = 1, count = fields.Length; i < count; i++)
            {
                if ((int)System.Enum.Parse(e, fields[i].Name) == value)
                {
                    DescriptionAttribute[] EnumAttributes = (DescriptionAttribute[])fields[i].
                GetCustomAttributes(typeof(DescriptionAttribute), false);
                    if (EnumAttributes.Length > 0)
                    {
                        return EnumAttributes[0].Description;
                    }
                }
            }
            return "";
        }
        public static String GetEnumDescForMecType(this Type e, int? value)
        {
            FieldInfo[] fields = e.GetFields();
            for (int i = 1, count = fields.Length; i < count-1; i++)
            {
                if ((int)System.Enum.Parse(e, fields[i].Name) == value)
                {
                    DescriptionAttribute[] EnumAttributes = (DescriptionAttribute[])fields[i].
                GetCustomAttributes(typeof(DescriptionAttribute), false);
                    if (EnumAttributes.Length > 0)
                    {
                        return EnumAttributes[0].Description;
                    }
                }
            }
            return "";
        }
        public static string GetWeek(DayOfWeek week)
        {
            switch (week)
            {
                case DayOfWeek.Sunday:
                    return "星期日";
                case DayOfWeek.Monday:
                    return "星期一";
                case DayOfWeek.Tuesday:
                    return "星期二";
                case DayOfWeek.Wednesday:
                    return "星期三";
                case DayOfWeek.Thursday:
                    return "星期四";
                case DayOfWeek.Friday:
                    return "星期五";
                case DayOfWeek.Saturday:
                    return "星期六";
                default:
                    return "未知";
            }

        }
        public static string GetDay(string time)
        {

            var dateTime = Convert.ToDateTime(DateTime.Now.Year + "-" + time);
            return dateTime.ToString("MM月dd号");

        }
        public static string GetMonth(int month)
        {

            switch (month)
            {
                case 1:
                    return "一月";
                case 2:
                    return "二月";
                case 3:
                    return "三月";
                case 4:
                    return "四月";
                case 5:
                    return "五月";
                case 6:
                    return "六月";
                case 7:
                    return "七月";
                case 8:
                    return "八月";
                case 9:
                    return "九月";
                case 10:
                    return "十月";
                case 11:
                    return "十一月";
                case 12:
                    return "十二月";
                default:
                    return "未知";
            }

        }

    }


}