using System.Globalization;
using System.Text;

namespace PlcSiemens.Core.Common
{
    /// <summary>
    /// 一些转换功能
    /// </summary>
    public class DefaultConvert
    {
        /// <summary>
        /// obj对象转int
        /// </summary>
        /// <param name="value">转换对象</param>
        /// <param name="defaultValue">缺省值</param>
        /// <returns></returns>
        public virtual int ToInt(object value, int defaultValue)
        {
            if (value == null) return defaultValue;

            var s = value as string;
            if (s != null)
            {
                var str = s;
                str = ToDbc(str).Trim();
                if (string.IsNullOrEmpty(str)) return defaultValue;

                int n;
                if (int.TryParse(str, out n)) return n;

                return defaultValue;
            }
            var bytes = value as byte[];
            if (bytes != null)
            {
                var buf = bytes;
                if (buf.Length < 1) return defaultValue;

                switch (buf.Length)
                {
                    case 1:
                        return buf[0];

                    case 2:
                        return BitConverter.ToInt16(buf, 0);

                    case 3:
                        return BitConverter.ToInt32(new byte[] { buf[0], buf[1], buf[2], 0 }, 0);

                    case 4:
                        return BitConverter.ToInt32(buf, 0);
                }
            }

            try
            {
                return Convert.ToInt32(value);
            }
            catch
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// obj对象转double
        /// </summary>
        /// <param name="value">转换对象</param>
        /// <param name="defaultValue">缺省值</param>
        /// <returns></returns>
        public virtual double ToDouble(object value, double defaultValue)
        {
            if (value == null) return defaultValue;

            // 特殊处理字符串，也是最常见的
            var s = value as string;
            if (s != null)
            {
                var str = s;
                str = ToDbc(str).Trim();
                if (string.IsNullOrEmpty(str)) return defaultValue;

                double n;
                if (double.TryParse(str, out n)) return n;
                return defaultValue;
            }
            var bytes = value as byte[];
            if (bytes != null)
            {
                var buf = bytes;
                if (buf.Length < 1) return defaultValue;

                switch (buf.Length)
                {
                    case 1:
                        return buf[0];

                    case 2:
                        return BitConverter.ToInt16(buf, 0);

                    case 3:
                        return BitConverter.ToInt32(new byte[] { buf[0], buf[1], buf[2], 0 }, 0);

                    case 4:
                        return BitConverter.ToInt32(buf, 0);

                    default:
                        // 凑够8字节
                        if (buf.Length < 8)
                        {
                            var bts = new byte[8];
                            Buffer.BlockCopy(buf, 0, bts, 0, buf.Length);
                            buf = bts;
                        }
                        return BitConverter.ToDouble(buf, 0);
                }
            }

            try
            {
                return Convert.ToDouble(value);
            }
            catch
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// obj对象转bool
        /// </summary>
        /// <param name="value">转换对象</param>
        /// <param name="defaultValue">缺省值</param>
        /// <returns></returns>
        public virtual bool ToBoolean(object value, bool defaultValue)
        {
            if (value == null) return defaultValue;

            // 特殊处理字符串，也是最常见的
            var s = value as string;
            if (s != null)
            {
                var str = s;
                str = ToDbc(str).Trim();
                if (string.IsNullOrEmpty(str)) return defaultValue;

                bool b;
                if (bool.TryParse(str, out b)) return b;

                if (string.Equals(str, bool.TrueString, StringComparison.OrdinalIgnoreCase)) return true;
                if (string.Equals(str, bool.FalseString, StringComparison.OrdinalIgnoreCase)) return false;

                // 特殊处理用数字0和1表示布尔型
                int n;
                if (int.TryParse(str, out n)) return n > 0;

                return defaultValue;
            }

            try
            {
                return Convert.ToBoolean(value);
            }
            catch
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// obj对象转DateTime
        /// </summary>
        /// <param name="value">转换对象</param>
        /// <param name="defaultValue">缺省值</param>
        /// <returns></returns>
        public virtual DateTime ToDateTime(object value, DateTime defaultValue)
        {
            if (value == null) return defaultValue;

            // 特殊处理字符串，也是最常见的
            var s = value as string;
            if (s != null)
            {
                var str = s;
                str = ToDbc(str).Trim();
                if (string.IsNullOrEmpty(str)) return defaultValue;

                DateTime n;
                if (DateTime.TryParse(str, out n)) return n;
                if (str.Contains("-") && DateTime.TryParseExact(str, "yyyy-M-d", null, DateTimeStyles.None, out n))
                    return n;
                if (str.Contains("/") && DateTime.TryParseExact(str, "yyyy/M/d", null, DateTimeStyles.None, out n))
                    return n;
                if (DateTime.TryParse(str, out n)) return n;
                return defaultValue;
            }

            try
            {
                return Convert.ToDateTime(value);
            }
            catch
            {
                return defaultValue;
            }
        }

        private static string ToDbc(string str)
        {
            var ch = str.ToCharArray();
            for (var i = 0; i < ch.Length; i++)
            {
                // 全角空格
                if (ch[i] == 0x3000)
                    ch[i] = (char)0x20;
                else if (ch[i] > 0xFF00 && ch[i] < 0xFF5F)
                    ch[i] = (char)(ch[i] - 0xFEE0);
            }
            return new string(ch);
        }

        /// <summary>
        /// obj对象转DateTime
        /// </summary>
        /// <param name="value">转换对象</param>
        /// <param name="emptyValue">缺省值</param>
        /// <returns></returns>
        public virtual string ToFullString(DateTime value, string emptyValue = null)
        {
            if (emptyValue != null && value <= DateTime.MinValue) return emptyValue;

            //return value.ToString("yyyy-MM-dd HH:mm:ss");

            var dt = value;
            var sb = new StringBuilder();
            sb.Append(dt.Year.ToString().PadLeft(4, '0'));
            sb.Append("-");
            sb.Append(dt.Month.ToString().PadLeft(2, '0'));
            sb.Append("-");
            sb.Append(dt.Day.ToString().PadLeft(2, '0'));
            sb.Append(" ");

            sb.Append(dt.Hour.ToString().PadLeft(2, '0'));
            sb.Append(":");
            sb.Append(dt.Minute.ToString().PadLeft(2, '0'));
            sb.Append(":");
            sb.Append(dt.Second.ToString().PadLeft(2, '0'));

            return sb.ToString();
        }

        /// <summary>
        /// obj对象转DateTime
        /// </summary>
        /// <param name="value">转换对象</param>
        /// <param name="format">转换格式</param>
        /// <param name="emptyValue">缺省值</param>
        /// <returns></returns>
        public virtual string ToString(DateTime value, string format, string emptyValue)
        {
            if (emptyValue != null && value <= DateTime.MinValue) return emptyValue;

            if (format == null || format == "yyyy-MM-dd HH:mm:ss") return ToFullString(value, emptyValue);

            return value.ToString(format);
        }
    }
}
