using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;

namespace Apewer.Internals
{

    internal class TextConverter
    {

        /// <summary>将文本以 UTF-8 转换为字节数组。</summary>
        public static byte[] ToBinary(string argText)
        {
            return ToBinary(argText, Encoding.UTF8);
        }

        /// <summary>将文本以转换为字节数组。</summary>
        public static byte[] ToBinary(string argText, Encoding argEncoding)
        {
            var vnull = Constant.EmptyBytes;
            if (string.IsNullOrEmpty(argText)) return vnull;
            if (argEncoding == null) return vnull;
            try { return argEncoding.GetBytes(argText); }
            catch { return vnull; }
        }

        /// <summary>将字节数组以 UTF-8 转换为文本。</summary>
        public static string FromBinary(byte[] argBytes)
        {
            var vnull = "";
            if (argBytes.Length < 1) return vnull;
            try { return Encoding.UTF8.GetString(argBytes); }
            catch { return vnull; }
        }

        /// <summary>将字节数组转换为文本。</summary>
        public static string FromBinary(byte[] argBytes, Encoding argEncoding)
        {
            var vnull = "";
            if (argBytes.Length < 1) return vnull;
            if (argEncoding == null) return vnull;
            try { return argEncoding.GetString(argBytes); }
            catch { return vnull; }
        }

        /// <summary>将明文文本以 UTF-8 转换为 Base64 文本。</summary>
        public static string ToBase64(string argPlain)
        {
            var vbytes = ToBinary(argPlain);
            var vcipher = ByteHelper.ToBase64(vbytes);
            return vcipher;
        }

        /// <summary>将 Base64 文本以 UTF-8 转换为明文文本。</summary>
        public static string FromBase64(string argCipher)
        {
            var vbytes = ByteHelper.FromBase64(argCipher);
            var vplain = FromBinary(vbytes);
            return vplain;
        }

        /// <summary>将文本转换为 DataTable 对象。</summary>
        public static DataTable ToDataTable(List<string[]> argNestedText)
        {
            var vtable = new DataTable();
            if (argNestedText == null) return vtable;

            var vcolumns = 0;
            foreach (var vrow in argNestedText)
            {
                if (vrow == null) continue;
                if (vrow.Length > vcolumns) vcolumns = vrow.Length;
                for (int i = 0; i < vcolumns; i++) if (vrow[i] == null) vrow[i] = "";
            }

            for (int i = 0; i < vcolumns; i++) vtable.Columns.Add("Column_" + vtable.Columns.Count.ToString());
            foreach (var vrow in argNestedText) vtable.Rows.Add(vrow);
            return vtable;
        }

        /// <summary>将文本转换为 DataTable 对象。</summary>
        public static DataTable ToDataTable(List<List<string>> argNestedText)
        {
            var vtable = new DataTable();
            if (argNestedText == null) return vtable;

            var vcolumns = 0;
            foreach (var vrow in argNestedText)
            {
                if (vrow == null) continue;
                if (vrow.Count > vcolumns) vcolumns = vrow.Count;
                for (int i = 0; i < vcolumns; i++) if (vrow[i] == null) vrow[i] = "";
            }

            for (int i = 0; i < vcolumns; i++) vtable.Columns.Add("Column_" + vtable.Columns.Count.ToString());
            foreach (var vrow in argNestedText) vtable.Rows.Add(vrow.ToArray());
            return vtable;
        }

        /// <summary>byte -> plain</summary>
        public static string EncodeByte(byte argByte)
        {
            return Constant.HexCollection[argByte / 16].ToString() + Constant.HexCollection[argByte % 16].ToString();
        }

        /// <summary>binary -> plain</summary>
        public static string EncodeBinary(byte[] argBytes)
        {
            try
            {
                int vlength = argBytes.Length;
                if (vlength > 0)
                {
                    var vb = new TextBuilder();
                    for (int i = 0; i < vlength; i++) vb.Append(EncodeByte(argBytes[i]));
                    return vb.Value;
                }
            }
            finally { }
            return "";
        }

        /// <summary>text -> plain</summary>
        public static string EncodeText(string argText, bool argDelimiter = false)
        {
            if (!string.IsNullOrEmpty(argText))
            {
                if (argDelimiter)
                {
                    string vcell;
                    var vb = new TextBuilder();
                    for (int i = 0; i < argText.Length; i++)
                    {
                        vcell = argText.Substring(i, 1);
                        vcell = EncodeBinary(Encoding.UTF8.GetBytes(vcell));
                        vb.Append("<" + vcell + ">");
                    }
                    return vb.Value;
                }
                else
                {
                    return EncodeBinary(Encoding.UTF8.GetBytes(argText));
                }
            }
            else return "";
        }

        /// <summary>plain -> binary</summary>
        public static byte[] DecodeBinary(string hex)
        {
            if (string.IsNullOrEmpty(hex)) return Constant.EmptyBytes;
            string vplain = TextHelper.LCase(hex);
            byte[] vresult;
            if (TextHelper.Len(vplain) >= 2)
            {
                MemoryStream vmsold = null;
                MemoryStream vmsnew = null;
                try
                {
                    int vcell;
                    vmsold = new MemoryStream(Encoding.ASCII.GetBytes(vplain));
                    vmsnew = new MemoryStream();
                    long vlength = vmsold.Length;
                    if ((vlength % 2) == 0)
                    {
                        for (int i = 1; i <= (vlength / 2); i++)
                        {
                            vcell = GetHex(vmsold.ReadByte()) * 16;
                            vcell = vcell + GetHex(vmsold.ReadByte());
                            vmsnew.WriteByte(Convert.ToByte(vcell));
                        }
                    }
                    vresult = vmsnew.ToArray();
                }
                catch
                {
                    vresult = Constant.EmptyBytes;
                }
                finally
                {
                    vmsnew.Dispose();
                    vmsold.Dispose();
                }
            }
            else
            {
                vresult = Constant.EmptyBytes;
            }
            return vresult;
        }

        /// <summary>plain -> text</summary>
        public static string DecodeText(string argPlain)
        {
            if (string.IsNullOrEmpty(argPlain)) return "";
            string vplain = TextHelper.LCase(argPlain);
            vplain = vplain.Replace("<", "");
            vplain = vplain.Replace(">", "");
            if (vplain.Length >= 2)
            {
                byte[] vbytes = DecodeBinary(vplain);
                if (vbytes.Length > 0) return Encoding.UTF8.GetString(vbytes);
            }
            return "";
        }

        /// <summary>ascii -> hex</summary>
        public static byte GetHex(byte argAscii)
        {
            if ((argAscii >= 48) && (argAscii <= 57)) return Convert.ToByte(argAscii - 48);
            if ((argAscii >= 97) && (argAscii <= 122)) return Convert.ToByte(argAscii - 87);
            return 0;
        }

        /// <summary>ascii -> hex</summary>
        public static byte GetHex(int argAscii)
        {
            try
            {
                if ((argAscii >= 48) && (argAscii <= 57)) return Convert.ToByte(argAscii - 48);
                if ((argAscii >= 97) && (argAscii <= 122)) return Convert.ToByte(argAscii - 87);
            }
            catch { }
            return 0;
        }

        /// <summary>将字节数组格式化为字符串。</summary>
        public static string FormatX2(params byte[] argBytes)
        {
            var sb = new System.Text.StringBuilder();
            for (int i = 0; i < argBytes.Length; i++) sb.Append(argBytes[i].ToString("x2"));
            return sb.ToString();
        }

        /// <summary>获取单精度浮点对象。</summary>
        public static Single GetSingle(string text)
        {

            if (!string.IsNullOrEmpty(text))
            {
                try
                {
                    var t = text.Trim();
                    t = t.Replace(" ", "").Replace(",", "").Replace(",", "");
                    t = t.Replace("。", ".");

                    var p = 0;
                    while (t.Length > 0 && t.EndsWith("%"))
                    {
                        t = t.Substring(0, t.Length - 1);
                        p += 1;
                    }
                    var v = Convert.ToSingle(t);
                    if (p > 0) v /= Convert.ToSingle(Math.Pow(100D, p));
                    return v;
                    // if (TextVerifier.IsNumber(argValue)) return Convert.ToSingle(argValue);
                }
                catch { }
            }
            return 0F;
        }

        /// <summary>获取双精度浮点对象。</summary>
        public static Double GetDouble(string text)
        {
            if (!string.IsNullOrEmpty(text))
            {
                try
                {
                    var t = text.Trim();
                    t = t.Replace(" ", "").Replace(",", "").Replace(",", "");
                    t = t.Replace("。", ".");

                    var p = 0;
                    while (t.Length > 0 && t.EndsWith("%"))
                    {
                        t = t.Substring(0, t.Length - 1);
                        p += 1;
                    }
                    var v = Convert.ToDouble(t);
                    if (p > 0) v /= Math.Pow(100D, p);
                    return v;
                    // if (TextVerifier.IsNumber(text)) return Convert.ToDouble(text);
                }
                catch { }
            }
            return 0D;
        }

        /// <summary>获取 Decimal 对象。</summary>
        public static decimal GetDecimal(string text)
        {
            if (!string.IsNullOrEmpty(text))
            {
                try
                {
                    var t = text.Trim();
                    t = t.Replace(" ", "").Replace(",", "").Replace(",", "");
                    t = t.Replace("。", ".");

                    var p = 0;
                    while (t.Length > 0 && t.EndsWith("%"))
                    {
                        t = t.Substring(0, t.Length - 1);
                        p += 1;
                    }
                    var v = Convert.ToDecimal(t);
                    if (p > 0) v /= Convert.ToDecimal(Math.Pow(100D, p));
                    return v;
                }
                catch
                {
                    try
                    {
                        var t = text.Trim();
                        t = t.Replace(" ", "").Replace(",", "").Replace(",", "");
                        t = t.Replace("。", ".");

                        var p = 0;
                        while (t.Length > 0 && t.EndsWith("%"))
                        {
                            t = t.Substring(0, t.Length - 1);
                            p += 1;
                        }
                        var v = decimal.Parse(t, System.Globalization.NumberStyles.Float);
                        if (p > 0) v /= Convert.ToDecimal(Math.Pow(100D, p));
                        return v;
                    }
                    catch { }
                }
            }
            return 0M;
        }

        /// <summary>获取 Byte 对象。</summary>
        public static Byte GetByte(string argValue)
        {
            if (!string.IsNullOrEmpty(argValue))
            {
                try
                {
                    if (TextVerifier.IsInteger(argValue))
                    {
                        return Convert.ToByte(argValue);
                    }
                }
                catch { }
            }
            return 0;
        }

        /// <summary>获取 SByte 对象。</summary>
        public static SByte GetSByte(string argValue)
        {
            if (!string.IsNullOrEmpty(argValue))
            {
                try
                {
                    if (TextVerifier.IsInteger(argValue))
                    {
                        return Convert.ToSByte(argValue);
                    }
                }
                catch { }
            }
            return 0;
        }

        /// <summary>获取 Int16 对象。</summary>
        public static Int16 GetInt16(string argValue)
        {
            if (!string.IsNullOrEmpty(argValue))
            {
                try
                {
                    if (TextVerifier.IsInteger(argValue))
                    {
                        return Convert.ToInt16(argValue);
                    }
                }
                catch { }
            }
            return 0;
        }

        /// <summary>获取 UInt16 对象。</summary>
        public static UInt16 GetUInt16(string argValue)
        {
            if (!string.IsNullOrEmpty(argValue))
            {
                try
                {
                    if (TextVerifier.IsInteger(argValue))
                    {
                        return Convert.ToUInt16(argValue);
                    }
                }
                catch { }
            }
            return 0;
        }

        /// <summary>获取 Int32 对象。</summary>
        public static Int32 GetInt32(string argValue)
        {
            if (!string.IsNullOrEmpty(argValue))
            {
                try
                {
                    if (TextVerifier.IsInteger(argValue))
                    {
                        return Convert.ToInt32(argValue);
                    }
                }
                catch { }
            }
            return 0;
        }

        /// <summary>获取 UInt32 对象。</summary>
        public static UInt32 GetUInt32(string argValue)
        {
            if (!string.IsNullOrEmpty(argValue))
            {
                try
                {
                    if (TextVerifier.IsInteger(argValue))
                    {
                        return Convert.ToUInt32(argValue);
                    }
                }
                catch { }
            }
            return 0;
        }

        /// <summary>获取 Int64 对象。</summary>
        public static Int64 GetInt64(string argValue)
        {
            if (!string.IsNullOrEmpty(argValue))
            {
                try
                {
                    if (TextVerifier.IsInteger(argValue))
                    {
                        return Convert.ToInt64(argValue);
                    }
                }
                catch { }
            }
            return 0;
        }

        /// <summary>获取 UInt64 对象。</summary>
        public static UInt64 GetUInt64(string argValue)
        {
            if (!string.IsNullOrEmpty(argValue))
            {
                try
                {
                    if (TextVerifier.IsInteger(argValue))
                    {
                        return Convert.ToUInt64(argValue);
                    }
                }
                catch { }
            }
            return 0;
        }

    }

}