using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Windows.Forms;
using System.Xml.Serialization;
namespace Helper
{
    [ComVisible(true)]
    public static class ConvertEx
    {
        /// <summary>
        /// unicode转字符串
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string UnicodeToString(string source)
        {
            return new Regex(@"\\u([0-9A-F]{4})", RegexOptions.IgnoreCase | RegexOptions.Compiled).Replace(
                         source, x => string.Empty + Convert.ToChar(Convert.ToUInt16(x.Result("$1"), 16)));
        }
        /// <summary>
        /// 中文符转英文符
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string SignToEnglish(string str)
        {
            str = str.Replace("，", ",").Replace("。", ".").Replace("：", ":")
     .Replace("（", "(").Replace("）", ")").Replace("；", ";")
     .Replace("“", "\"").Replace("”", "\"").Replace("【", "[")
     .Replace("】", "]").Replace("？", "?").Replace("《", "<")
     .Replace("》", ">").Replace("！", "!").Replace("、", "\\")
     .Replace("{", "{").Replace("}", "}");
            return str;
        }
        /// <summary>
        /// 字符串转整数
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="str">默认值</param>
        /// <returns>成功返回结果,失败返回默认值</returns>
        public static int ToInt32(string str, int defultValue = 0)
        {
            try { return int.Parse(str); }
            catch (Exception)
            { return defultValue; }
        }
        /// <summary>
        /// base64解码
        /// </summary>
        /// <param name="code"></param>
        /// <param name="en"></param>
        /// <returns></returns>
        public static string DecodeBase64(string code, Encoding en)
        {
            byte[] bytes = Convert.FromBase64String(code);
            try
            {
                return en.GetString(bytes);
            }
            catch
            {
                return code;
            }
        }
        /// <summary>
        /// url格式编码
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string UrlEncode(string str)
        {
            byte[] byt = Encoding.Default.GetBytes(str);
            string ret = HttpUtility.UrlEncode(byt);
            return ret;
        }
        /// <summary>
        /// DataGridView转DataTable
        /// </summary>
        /// <param name="dgv"></param>
        /// <returns></returns>
        public static DataTable DgvToTable(DataGridView dgv)
        {
            DataTable dt = new DataTable();
            // 列强制转换
            for (int count = 0; count < dgv.Columns.Count; count++)
            {
                DataColumn dc = new DataColumn(dgv.Columns[count].Name.ToString());
                dt.Columns.Add(dc);
            }
            // 循环行
            for (int count = 0; count < dgv.Rows.Count; count++)
            {
                DataRow dr = dt.NewRow();
                for (int countsub = 0; countsub < dgv.Columns.Count; countsub++)
                { dr[countsub] = Convert.ToString(dgv.Rows[count].Cells[countsub].Value); }
                dt.Rows.Add(dr);
            }
            return dt;
        }
        /// <summary>  
        /// 时间转时间戳
        /// </summary>  
        /// <param name="time">时间</param>  
        /// <returns></returns>  
        public static int TimeToStamp(DateTime time)
        {
            DateTime startTime = new DateTime(1970, 1, 1, 8, 0, 0, 0);
            return (int)(time - startTime).TotalSeconds;
        }
        /// <summary>        
        /// 时间戳转时间        
        /// </summary>        
        /// <param name=”timeStamp”></param>        
        /// <returns></returns>        
        public static DateTime StampToTime(int stamp)
        {
            DateTime dtStart = new DateTime(1970, 1, 1, 8, 0, 0, 0);
            return dtStart.AddSeconds(stamp);
        }
        /// <summary>
        /// 将对象转换为byte数组
        /// </summary>
        /// <param name="obj">被转换对象</param>
        /// <returns>转换后byte数组</returns>
        public static byte[] Object2Bytes(object obj)
        {
            byte[] buff;
            using (MemoryStream ms = new MemoryStream())
            {
                IFormatter iFormatter = new BinaryFormatter();
                iFormatter.Serialize(ms, obj);
                buff = ms.GetBuffer();
            }
            return buff;
        }
        /// <summary>
        /// 将byte数组转换成对象
        /// </summary>
        /// <param name="buff">被转换byte数组</param>
        /// <returns>转换完成后的对象</returns>
        public static object Bytes2Object(byte[] buff)
        {
            object obj;
            using (MemoryStream ms = new MemoryStream(buff))
            {
                IFormatter iFormatter = new BinaryFormatter();
                obj = iFormatter.Deserialize(ms);
            }
            return obj;
        }
        public static string ObjectToBase64(object o)
        {
            return Convert.ToBase64String(Object2Bytes(o));
        }
        public static object Base64ToObject(string code)
        {
            return Bytes2Object(Convert.FromBase64String(code));
        }

        /// <summary>
        /// 根据Json返回DateTable,JSON数据格式如:
        /// {table:[{column1:1,column2:2,column3:3},{column1:1,column2:2,column3:3}]}
        /// </summary>
        /// <param name="strJson">Json字符串</param>
        /// <returns></returns>
        public static DataTable JsonToDataTable(string json)
        {
           return  JsonConvert.DeserializeObject<DataTable>(json);
        }


        /// <summary>
        /// 根据DataTable返回JSON数据格式如:
        /// {table:[{column1:1,column2:2,column3:3},{column1:1,column2:2,column3:3}]}
        /// </summary>
        /// <param name="tb">需要转换的表</param>
        /// <returns></returns>
        public static string DateTableToJson( DataTable dt)
        {
         return   JsonConvert.SerializeObject(dt);
        }
    }
    /// <summary>
    /// 实体转换辅助类
    /// </summary>
    [ComVisible(true)]
    public class ModelConvertHelper<T> where T : new()
    {
        public static string XmlSerialize<T>(T obj)
        {
            using (System.IO.StringWriter sw = new StringWriter())
            {
                Type t = obj.GetType();
                System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
                serializer.Serialize(sw, obj);
                sw.Close();
                return sw.ToString();
            }
        }
        public static T XmlDESerializer<T>(string strXML) where T : class
        {
            try
            {
                using (StringReader sr = new StringReader(strXML))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    return serializer.Deserialize(sr) as T;
                }
            }
            catch (Exception ex)
            {
                return null;
            }
        } 
        /// <summary>
        /// List泛型转换DataTable.
        /// </summary>
        public DataTable ListToDataTable<T>(List<T> items)
        {
            var tb = new DataTable(typeof(T).Name);
            PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (PropertyInfo prop in props)
            {
                Type t = GetCoreType(prop.PropertyType);
                tb.Columns.Add(prop.Name, t);
            }
            foreach (T item in items)
            {
                var values = new object[props.Length];
                for (int i = 0; i < props.Length; i++)
                {
                    values[i] = props[i].GetValue(item, null);
                }
                tb.Rows.Add(values);
            }
            return tb;
        }
        /// <summary>
        /// model转换DataTable
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="items"></param>
        /// <returns></returns>
        public DataTable ModelToDataTable<T>(T items)
        {
            var tb = new DataTable(typeof(T).Name);
            PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (PropertyInfo prop in props)
            {
                Type t = GetCoreType(prop.PropertyType);
                tb.Columns.Add(prop.Name, t);
            }
            var values = new object[props.Length];
            for (int i = 0; i < props.Length; i++)
            {
                values[i] = props[i].GetValue(items, null);
            }
            tb.Rows.Add(values);
            return tb;
        }
        /// <summary>
        /// Determine of specified type is nullable
        /// </summary>
        public static bool IsNullable(Type t)
        {
            return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
        }
        /// <summary>
        /// Return underlying type if type is Nullable otherwise return the type
        /// </summary>
        public static Type GetCoreType(Type t)
        {
            if (t != null && IsNullable(t))
            {
                if (!t.IsValueType)
                {
                    return t;
                }
                else
                {
                    return Nullable.GetUnderlyingType(t);
                }
            }
            else
            {
                return t;
            }
        }
        /// <summary>
        /// DataTable转换泛型List
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static List<T> DataTableToList(DataTable dt)
        {
            // 定义集合
            List<T> ts = new List<T>();
            // 获得此模型的类型
            Type type = typeof(T);
            string tempName = "";
            foreach (DataRow dr in dt.Rows)
            {
                T t = new T();
                // 获得此模型的公共属性
                PropertyInfo[] propertys = t.GetType().GetProperties();
                foreach (PropertyInfo pi in propertys)
                {
                    tempName = pi.Name;  // 检查DataTable是否包含此列
                    if (dt.Columns.Contains(tempName))
                    {
                        try
                        {
                            // 判断此属性是否有Setter
                            if (!pi.CanWrite) continue;
                            object value = dr[tempName];
                            if (value != DBNull.Value)
                                pi.SetValue(t, value, null);
                        }
                        catch (Exception)
                        { }
                    }
                }
                ts.Add(t);
            }
            return ts;
        }
        public static T DataTableToModel(DataTable dt)
        {
            // 定义实体
            T t = new T();
            // 获得此模型的类型
            Type type = typeof(T);
            string tempName = "";
            foreach (DataRow dr in dt.Rows)
            {
                // 获得此模型的公共属性
                PropertyInfo[] propertys = t.GetType().GetProperties();
                foreach (PropertyInfo pi in propertys)
                {
                    tempName = pi.Name;  // 检查DataTable是否包含此列
                    if (dt.Columns.Contains(tempName))
                    {
                        // 判断此属性是否有Setter
                        if (!pi.CanWrite) continue;
                        object value = dr[tempName];
                        if (value != DBNull.Value)
                            pi.SetValue(t, value, null);
                    }
                }
                break;
            }
            return t;
        }
        public T Row2Model<T>(DataRow dr)
        {
            if (dr == null)
            {
                return default(T);
            }
            T model = (T)Activator.CreateInstance(typeof(T));
            for (int i = 0; i < dr.Table.Columns.Count; i++)
            {
                PropertyInfo propertyInfo = model.GetType().GetProperty(dr.Table.Columns[i].ColumnName);
                if (propertyInfo != null && dr[i] != DBNull.Value)
                    propertyInfo.SetValue(model, dr[i], null);
                else continue;
            }
            //foreach (PropertyInfo propertyInfo in typeof(T).GetProperties())
            //{
            //    if (dr.Table.Columns.Contains(propertyInfo.Name) && dr[propertyInfo.Name] != DBNull.Value)
            //        propertyInfo.SetValue(model, dr[propertyInfo.Name], null);
            //    else continue;
            //}
            return model;
        }
    }
}
namespace System.Runtime.CompilerServices
{
    public class ExtensionAttribute : Attribute { }
}