using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Data;
using System.IO;
namespace NFine.Web
{
    /// <summary>
    /// 打印类的公共函数
    /// </summary>
    public class PrintFunction
    {
        /// <summary>
        /// 把List类转化为XML字符串
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="DtTable"></param>
        /// <returns></returns>
        public static string ListToXml<T>(IList<T> DtTable)
        {
            StringBuilder PrintStr = new StringBuilder();
            XmlWriterSettings setting = new XmlWriterSettings();
            PropertyInfo[] TableColumns;
            Type TableType = DtTable[0].GetType();
            int ColRecn, RowRecn;
            string ColType;

            setting.Indent = true;
            setting.OmitXmlDeclaration = true;
            TableColumns = TableType.GetProperties();


            using (XmlWriter PrintXml = XmlWriter.Create(PrintStr, setting))
            {
                PrintXml.WriteStartElement("xml");
                PrintXml.WriteAttributeString("xmlns", "s", null, "u");
                PrintXml.WriteAttributeString("xmlns", "dt", null, "u");
                PrintXml.WriteAttributeString("xmlns", "rs", null, "u");
                PrintXml.WriteAttributeString("xmlns", "z", null, "#R");
                PrintXml.WriteStartElement("s", "Schema", null);
                PrintXml.WriteAttributeString("id", "RowsetSchema");
                PrintXml.WriteStartElement("s", "ElementType", null);
                PrintXml.WriteAttributeString("name", "row");
                PrintXml.WriteAttributeString("content", "eltOnly");
                PrintXml.WriteAttributeString("rs", "updatable", null, "true");

                for (ColRecn = 0; ColRecn < TableColumns.Length; ColRecn++)
                {
                    ColType = TableColumns[ColRecn].PropertyType.ToString();
                    if (ColType == "System.String" || ColType == "System.DateTime"
                        || ColType == "System.Int" || ColType == "System.Double"
                        || ColType == "System.Boolean" || ColType == "System.Int32" || ColType == "System.Int64")
                    {
                        PrintXml.WriteStartElement("s", "AttributeType", null);
                        PrintXml.WriteAttributeString("name", TableColumns[ColRecn].Name);

                        PrintXml.WriteAttributeString("rs", "number", null, (ColRecn + 1).ToString());
                        PrintXml.WriteAttributeString("rs", "nullable", null, "true");
                        PrintXml.WriteAttributeString("rs", "maydefer", null, "true");
                        PrintXml.WriteAttributeString("rs", "writeunknown", null, "true");
                        PrintXml.WriteAttributeString("rs", "basetable", null, "");
                        PrintXml.WriteAttributeString("rs", "basecolumn", null, TableColumns[ColRecn].Name);

                        if (ColType == "System.String")
                        {  //char
                            PrintXml.WriteStartElement("s", "datatype", null);
                            PrintXml.WriteAttributeString("dt", "type", null, "string");
                            PrintXml.WriteAttributeString("dt", "maxLength", null, "8000");
                            PrintXml.WriteEndElement();
                        }
                        else if (ColType == "System.DateTime")
                        {  //dateTime
                            PrintXml.WriteStartElement("s", "datatype", null);
                            PrintXml.WriteAttributeString("dt", "type", null, "dateTime");
                            PrintXml.WriteAttributeString("dt", "maxLength", null, "16");
                            PrintXml.WriteEndElement();
                        }
                        else if (ColType == "System.Double")
                        {  //Float
                            PrintXml.WriteStartElement("s", "datatype", null);
                            PrintXml.WriteAttributeString("dt", "type", null, "float");
                            PrintXml.WriteAttributeString("dt", "maxLength", null, "8");
                            PrintXml.WriteEndElement();
                        }
                        else if (ColType == "System.Int" || ColType == "System.Int32" || ColType == "System.Int64")
                        {  //int
                            PrintXml.WriteStartElement("s", "datatype", null);
                            PrintXml.WriteAttributeString("dt", "type", null, "int");
                            PrintXml.WriteAttributeString("dt", "maxLength", null, "4");
                            PrintXml.WriteEndElement();
                        }
                        else if (ColType == "System.Boolean")
                        {  //bit
                            PrintXml.WriteStartElement("s", "datatype", null);
                            PrintXml.WriteAttributeString("dt", "type", null, "boolean");
                            PrintXml.WriteAttributeString("dt", "maxLength", null, "2");
                            PrintXml.WriteEndElement();
                        }
                        PrintXml.WriteEndElement();
                    }
                }
                PrintXml.WriteEndElement();
                PrintXml.WriteEndElement();


                PrintXml.WriteStartElement("rs", "data", null);
                for (RowRecn = 0; RowRecn < DtTable.Count; RowRecn++)
                {
                    PrintXml.WriteStartElement("z", "row", null);
                    for (ColRecn = 0; ColRecn < TableColumns.Length; ColRecn++)
                    {
                        if (Convert.IsDBNull(TableColumns[ColRecn].GetValue(DtTable[RowRecn], null)) == true)
                            continue;

                        ColType = TableColumns[ColRecn].PropertyType.ToString();
                        if (ColType == "System.String" || ColType == "System.DateTime"
                            || ColType == "System.Int" || ColType == "System.Double"
                            || ColType == "System.Boolean" || ColType == "System.Int32" || ColType == "System.Int64")
                        {
                            if (ColType == "System.DateTime")
                            {
                                DateTime TmpDateTime = System.Convert.ToDateTime(TableColumns[ColRecn].GetValue(DtTable[RowRecn], null));
                                string TmpStr = TmpDateTime.ToString("yyyy-MM-dd") + "T" + TmpDateTime.ToString("HH:mm:ss");
                                PrintXml.WriteAttributeString(TableColumns[ColRecn].Name, TmpStr);
                            }
                            else
                            {
                                string strValue = TableColumns[ColRecn].GetValue(DtTable[RowRecn], null).ToString();
                                strValue = strValue.Replace("\b", " ");
                                strValue = Regex.Replace(strValue, "[\x00-\x08\x0b-\x0c\x0e-\x1f]", " ");
                                PrintXml.WriteAttributeString(TableColumns[ColRecn].Name, strValue);
                            }
                        }
                    }
                    PrintXml.WriteEndElement();
                }
                PrintXml.WriteEndElement();

                PrintXml.WriteEndElement();
            }

            return PrintStr.ToString();
        }


        /// <summary>
        /// 把数据表转换为XML字符串
        /// </summary>
        /// <param name="pTable"></param>
        /// <returns></returns>
        public static string TableToXml(DataTable pTable)
        {
            StringBuilder stbPrint = new StringBuilder();
            XmlWriterSettings pXMLSet = new XmlWriterSettings();
            pXMLSet.Indent = true;
            pXMLSet.OmitXmlDeclaration = true;

            using (XmlWriter pPrintXML = XmlWriter.Create(stbPrint, pXMLSet))
            {
                pPrintXML.WriteStartElement("xml");
                pPrintXML.WriteAttributeString("xmlns", "s", null, "u");
                pPrintXML.WriteAttributeString("xmlns", "dt", null, "u");
                pPrintXML.WriteAttributeString("xmlns", "rs", null, "u");
                pPrintXML.WriteAttributeString("xmlns", "z", null, "#R");
                pPrintXML.WriteStartElement("s", "Schema", null);
                pPrintXML.WriteAttributeString("id", "RowsetSchema");
                pPrintXML.WriteStartElement("s", "ElementType", null);
                pPrintXML.WriteAttributeString("name", "row");
                pPrintXML.WriteAttributeString("content", "eltOnly");
                pPrintXML.WriteAttributeString("rs", "updatable", null, "true");

                foreach (DataColumn pColumn in pTable.Columns)
                {
                    if (pColumn.DataType.Name == "Int64" || pColumn.DataType.Name == "Boolean"
                        || pColumn.DataType.Name == "String" || pColumn.DataType.Name == "DateTime"
                        || pColumn.DataType.Name == "Decimal" || pColumn.DataType.Name == "Double"
                        || pColumn.DataType.Name == "Int32" || pColumn.DataType.Name == "Single"
                        || pColumn.DataType.Name == "Int16" || pColumn.DataType.Name == "Byte")
                    {
                        pPrintXML.WriteStartElement("s", "AttributeType", null);
                        pPrintXML.WriteAttributeString("name", pColumn.ColumnName);

                        pPrintXML.WriteAttributeString("rs", "number", null, (pColumn.Ordinal + 1).ToString());
                        pPrintXML.WriteAttributeString("rs", "nullable", null, "true");
                        pPrintXML.WriteAttributeString("rs", "maydefer", null, "true");
                        pPrintXML.WriteAttributeString("rs", "writeunknown", null, "true");
                        pPrintXML.WriteAttributeString("rs", "basetable", null, pTable.TableName);
                        pPrintXML.WriteAttributeString("rs", "basecolumn", null, pColumn.ColumnName);

                        if (pColumn.DataType.Name == "Int64")
                        {  //bigint
                            pPrintXML.WriteStartElement("s", "datatype", null);
                            pPrintXML.WriteAttributeString("dt", "type", null, "i8");
                            pPrintXML.WriteAttributeString("dt", "maxLength", null, "8");
                            pPrintXML.WriteEndElement();
                        }
                        else if (pColumn.DataType.Name == "Boolean")
                        {  //bit
                            pPrintXML.WriteStartElement("s", "datatype", null);
                            pPrintXML.WriteAttributeString("dt", "type", null, "boolean");
                            pPrintXML.WriteAttributeString("dt", "maxLength", null, "2");
                            pPrintXML.WriteEndElement();
                        }
                        else if (pColumn.DataType.Name == "String")
                        {  //char
                            pPrintXML.WriteStartElement("s", "datatype", null);
                            pPrintXML.WriteAttributeString("dt", "type", null, "string");
                            pPrintXML.WriteAttributeString("dt", "maxLength", null, pColumn.MaxLength.ToString());
                            pPrintXML.WriteEndElement();
                        }
                        else if (pColumn.DataType.Name == "DateTime")
                        {  //dateTime
                            pPrintXML.WriteStartElement("s", "datatype", null);
                            pPrintXML.WriteAttributeString("dt", "type", null, "dateTime");
                            pPrintXML.WriteAttributeString("dt", "maxLength", null, "16");
                            pPrintXML.WriteEndElement();
                        }
                        else if (pColumn.DataType.Name == "Decimal")
                        {  //Decimal
                            pPrintXML.WriteStartElement("s", "datatype", null);
                            pPrintXML.WriteAttributeString("dt", "type", null, "number");
                            pPrintXML.WriteAttributeString("dt", "maxLength", null, "19");
                            pPrintXML.WriteEndElement();
                        }
                        else if (pColumn.DataType.Name == "Double")
                        {  //Float
                            pPrintXML.WriteStartElement("s", "datatype", null);
                            pPrintXML.WriteAttributeString("dt", "type", null, "float");
                            pPrintXML.WriteAttributeString("dt", "maxLength", null, "8");
                            pPrintXML.WriteEndElement();
                        }
                        else if (pColumn.DataType.Name == "Int32")
                        {  //int
                            pPrintXML.WriteStartElement("s", "datatype", null);
                            pPrintXML.WriteAttributeString("dt", "type", null, "int");
                            pPrintXML.WriteAttributeString("dt", "maxLength", null, "4");
                            pPrintXML.WriteEndElement();
                        }
                        else if (pColumn.DataType.Name == "Single")
                        {  //Real
                            pPrintXML.WriteStartElement("s", "datatype", null);
                            pPrintXML.WriteAttributeString("dt", "type", null, "r4");
                            pPrintXML.WriteAttributeString("dt", "maxLength", null, "4");
                            pPrintXML.WriteEndElement();
                        }
                        else if (pColumn.DataType.Name == "Int16")
                        {  //smallint
                            pPrintXML.WriteStartElement("s", "datatype", null);
                            pPrintXML.WriteAttributeString("dt", "type", null, "i2");
                            pPrintXML.WriteAttributeString("dt", "maxLength", null, "2");
                            pPrintXML.WriteEndElement();
                        }
                        else if (pColumn.DataType.Name == "Byte")
                        {  //tinyint
                            pPrintXML.WriteStartElement("s", "datatype", null);
                            pPrintXML.WriteAttributeString("dt", "type", null, "ui1");
                            pPrintXML.WriteAttributeString("dt", "maxLength", null, "1");
                            pPrintXML.WriteEndElement();
                        }
                        pPrintXML.WriteEndElement();
                    }
                }
                pPrintXML.WriteEndElement();
                pPrintXML.WriteEndElement();

                pPrintXML.WriteStartElement("rs", "data", null);
                foreach (DataRow pRow in pTable.Rows)
                {
                    pPrintXML.WriteStartElement("z", "row", null);
                    foreach (DataColumn Column in pTable.Columns)
                    {
                        if (pRow.IsNull(Column) == true)
                            continue;

                        if (Column.DataType.Name == "Int64" || Column.DataType.Name == "Boolean"
                            || Column.DataType.Name == "String" || Column.DataType.Name == "DateTime"
                            || Column.DataType.Name == "Decimal" || Column.DataType.Name == "Double"
                            || Column.DataType.Name == "Int32" || Column.DataType.Name == "Single"
                            || Column.DataType.Name == "Int16" || Column.DataType.Name == "Byte")
                        {
                            if (Column.DataType.Name == "DateTime")
                            {
                                DateTime dtValue = System.Convert.ToDateTime(pRow[Column]);
                                string strValue = dtValue.ToString("yyyy-MM-dd") + "T" + dtValue.ToString("HH:mm:ss");
                                pPrintXML.WriteAttributeString(Column.ColumnName, strValue);
                            }
                            else
                            {
                                string strValue = pRow[Column].ToString();
                                strValue = strValue.Replace("\b", " ");
                                strValue = Regex.Replace(strValue, "[\x00-\x08\x0b-\x0c\x0e-\x1f]", " ");
                                pPrintXML.WriteAttributeString(Column.ColumnName, strValue);
                            }
                        }
                    }
                    pPrintXML.WriteEndElement();
                }
                pPrintXML.WriteEndElement();

                pPrintXML.WriteEndElement();
            }

            return stbPrint.ToString();
        }

        /// <summary>
        /// 把文件转换为字符串
        /// </summary>
        /// <param name="strFileName"></param>
        /// <returns></returns>
        public static string FileToString(string strFileName)
        {
            string[] aryByte = new string[256];
            for (int i = 0; i < 256; i++)
            {
                if (i == 0)
                    aryByte[i] = "00";
                else if (i < 16)
                    aryByte[i] = "0" + Convert.ToString(i, 16).ToUpper();
                else
                    aryByte[i] = Convert.ToString(i, 16).ToUpper();
            }

            if (!File.Exists(strFileName))
            {
                return "";
            }

            byte[] aryFileByte = File.ReadAllBytes(strFileName);
            StringBuilder stbFileValue = new StringBuilder();
            for (int i = 0; i < aryFileByte.Length; i++)
            {
                stbFileValue.Append(aryByte[aryFileByte[i]]);
            }
            aryFileByte = null;

            return stbFileValue.ToString();
        }

        /// <summary>
        /// 转化为base64编码
        /// </summary>
        /// <param name="strValue"></param>
        /// <returns></returns>
        public static string EnBase64(string strValue)
        {
            byte[] byteData = Encoding.Default.GetBytes(strValue);
            string strResult = Convert.ToBase64String(byteData);
            return strResult;
        }

    }
}