using System;
using System.Collections.Generic;
using System.Text;

namespace Apewer.Internals
{

    internal class ClockHelper
    {

        /// <summary>为字符串前添加字符“0”。</summary>
        /// <param name="argNumber">原字符串,内容应为整数、小数或十六进制数,若格式不符则返回原字符串。</param>
        /// <param name="argLength">新字符串的长度,若大于原数字长度,则不添加额外的“0”。</param>
        private static string PreZero(string argNumber, int argLength = 0)
        {
            string result = string.IsNullOrEmpty(argNumber) ? "" : argNumber.Trim();
            if (result.StartsWith(".")) result = "0" + result;
            while (result.Length < argLength) result = "0" + result;
            return result;
        }

        /// <summary>判断是否为闰年。</summary>
        public static bool LeapYear(int argYear)
        {
            if (argYear % 400 == 0) return true;
            if (argYear % 100 == 0) return false;
            if (argYear % 4 == 0) return true;
            return false;
        }

        /// <summary>获取指定年月的天数。</summary>
        public static int MonthDays(int argYear, int argMonth)
        {
            switch (argMonth)
            {
                case 1: return 31;
                case 2: return LeapYear(argYear) ? 29 : 28;
                case 3: return 31;
                case 4: return 30;
                case 5: return 31;
                case 6: return 30;
                case 7: return 31;
                case 8: return 31;
                case 9: return 30;
                case 10: return 31;
                case 11: return 30;
                case 12: return 31;
                default: return 0;
            }
        }

        public static string ToString(ClockValue argValue, bool argLucid)
        {
            if (argLucid)
            {
                var result = new TextBuilder();
                result.Append(TextModifier.PreZero(argValue.Year.ToString(), 4));
                result.Append("-");
                result.Append(TextModifier.PreZero(argValue.Month.ToString(), 2));
                result.Append("-");
                result.Append(TextModifier.PreZero(argValue.Day.ToString(), 2));
                result.Append(" ");
                result.Append(TextModifier.PreZero(argValue.Hour.ToString(), 2));
                result.Append(":");
                result.Append(TextModifier.PreZero(argValue.Minute.ToString(), 2));
                result.Append(":");
                result.Append(TextModifier.PreZero(argValue.Second.ToString(), 2));
                result.Append(".");
                result.Append(TextModifier.PreZero(argValue.Millisecond.ToString(), 3));
                return result.Value;
            }
            else
            {
                string result = "";
                result += TextModifier.PreZero(argValue.Year.ToString(), 4);
                result += TextModifier.PreZero(argValue.Month.ToString(), 2);
                result += TextModifier.PreZero(argValue.Day.ToString(), 2);
                result += TextModifier.PreZero(argValue.Hour.ToString(), 2);
                result += TextModifier.PreZero(argValue.Minute.ToString(), 2);
                result += TextModifier.PreZero(argValue.Second.ToString(), 2);
                result += TextModifier.PreZero(argValue.Millisecond.ToString(), 3);
                return result;
            }
        }

        /// <summary>表示当前时钟的字节数组。</summary>
        public static byte[] ToBinary(ClockValue argValue)
        {
            var bs = new byte[9];
            bs[0] = (byte)(argValue.Year / 256);
            bs[1] = (byte)(argValue.Year % 256);
            bs[2] = (byte)(argValue.Day / 256);
            bs[3] = (byte)(argValue.Month / 256);
            bs[4] = (byte)(argValue.Hour / 256);
            bs[5] = (byte)(argValue.Minute / 256);
            bs[6] = (byte)(argValue.Second / 256);
            bs[7] = (byte)(argValue.Millisecond / 256);
            bs[8] = (byte)(argValue.Millisecond % 256);
            return bs;
        }

        /// <summary>由指定字节数组创建对象。</summary>
        public static ClockValue FromBinary(byte[] argBytes)
        {
            var bs = argBytes;
            if (bs != null)
            {
                var clock = new ClockValue();
                if (argBytes.Length >= 4)
                {
                    clock.Year = bs[0] * 256 + bs[1];
                    clock.Month = bs[2];
                    clock.Day = bs[3];
                }
                if (argBytes.Length >= 7)
                {
                    clock.Hour = bs[4];
                    clock.Minute = bs[5];
                    clock.Millisecond = bs[6] * 256 + bs[7];
                }
                return clock;
            }
            else
            {
                return ClockValue.Create(0, 0, 0, 0, 0, 0, 0);
            }
        }

        public static long Stamp(TimeSpan argSpan, bool argMilleSecond = true)
        {
            try
            {
                if (argSpan == null) return 0;
                var total = argMilleSecond ? argSpan.TotalMilliseconds : argSpan.TotalSeconds;
                var result = Convert.ToInt64(total);
                return result;
            }
            catch { return 0; }
        }

        public static long Stamp(DateTime argCurrent, bool argMilleSecond = true)
        {
            try
            {
                var origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
                var span = argCurrent - origin;
                return Stamp(span, argMilleSecond);
            }
            catch { return 0; }
        }

        /// <summary>解析 DateTime 对象。</summary>
        public static DateTime Resolve(Object argDateTime)
        {
            if (argDateTime != null)
            {
                try
                {
                    if (argDateTime.GetType().Equals(typeof(DateTime)))
                    {
                        return (DateTime)argDateTime;
                    }
                }
                finally { }
            }
            return new DateTime(0, 0, 0, 0, 0, 0, 0);
        }

        /// <summary>解析用 String 表示的 DateTime 对象。</summary>
        public static DateTime Resolve(string argDateTime)
        {
            if (!string.IsNullOrEmpty(argDateTime))
            {
                try
                {
                    return Resolve(DateTime.Parse(argDateTime));
                }
                finally { }
            }
            return new DateTime(0, 0, 0, 0, 0, 0, 0);
        }

    }

}