using System;
using System.Reflection;
using System.Collections.Generic;
using Common.TextUtil;
using Common.Exceptions;

namespace NSC
{
    /// <summary>
    /// 功能:公共参数结构
    /// 作者:王昊昇
    /// 时间:2012.11.8
    /// </summary>
    public class ParameterStruct
    {
        /// <summary>
        /// 创建ParameterStruct类的新实例
        /// </summary>
        public ParameterStruct()
        {

        }

        /// <summary>
        /// 使用给定的属性创建ParameterStruct类的新实例
        /// </summary>
        /// <param name="data">数据,支持格式:string、所有值类型数据、属性全部是值类型的实体及List列表、DataTable、byte[]、string[]</param>
        public ParameterStruct(object data)
        {
            this.Data = data;
        }

        /// <summary>
        /// 数据格式
        /// </summary>
        internal string DataFormat { get; set; }

        /// <summary>
        /// 数据,支持格式:string、所有值类型数据、属性全部是值类型的实体及List列表、DataTable、byte[]、string[]
        /// </summary>
        internal object Data { get; set; }

        /// <summary>
        /// 参数链接
        /// </summary>
        internal string Link { get; set; }

        /// <summary>
        /// 获取List类型的数据
        /// </summary>
        /// <typeparam name="T">转换的目标类型</typeparam>
        /// <returns>返回实体列表数据</returns>
        public List<T> GetList<T>() where T : new()
        {
            if (Data is List<T>)
            {
                return Data as List<T>;
            }
            else
            {
                List<T> list = null;
                Type t = typeof(T);
                if (t.IsValueType || t == typeof(string))
                {
                    list = GetValueTypeInstanceList<T>();
                }
                else
                {
                    list = GetReferenceInstanceList<T>();
                }

                Data = list;

                return list;
            }
        }

        /// <summary>
        /// 获取引用类型泛型列表
        /// </summary>
        /// <typeparam name="T">引用型实体的类型</typeparam>
        /// <returns>返回引用型泛型数据</returns>
        private List<T> GetReferenceInstanceList<T>() where T : new()
        {
            System.Xml.XmlNode itmHead = ((System.Xml.XmlNode)Data).SelectSingleNode("Items");
            System.Xml.XmlNodeList itmList = itmHead.SelectNodes("Item");

            List<T> list = new List<T>();
            foreach (System.Xml.XmlNode n in itmList)
            {
                T t = new T();
                PropertyInfo[] publicProperties = t.GetType().GetProperties();

                for (int i = 0; i < publicProperties.Length; i++)
                {
                    publicProperties[i].SetValue(t, Common.AssemblyUtil.TypeFactory.ConvertValueTypeObjectToOriginalType(n.Attributes[publicProperties[i].Name].Value, publicProperties[i].PropertyType), null);
                }

                list.Add(t);
            }
            return list;
        }

        /// <summary>
        /// 获取值类型泛型列表
        /// </summary>
        /// <typeparam name="T">值类型实体的类型</typeparam>
        /// <returns>返回值类型泛型数据</returns>
        private List<T> GetValueTypeInstanceList<T>() where T : new()
        {
            System.Xml.XmlNode itmHead = ((System.Xml.XmlNode)Data).SelectSingleNode("Items");
            System.Xml.XmlNodeList itmList = itmHead.SelectNodes("Item");

            List<T> list = new List<T>();
            Type t = typeof(T);

            //此代码可替换下面代码,性能略逊
            //foreach (System.Xml.XmlNode n in itmList)
            //{
            //    list.Add((T)Common.AssemblyUtil.TypeFactory.ConvertValueTypeObjectToOriginalType(n.Attributes["Value"].Value, t));
            //}

            if (t.IsEnum)
            {
                foreach (System.Xml.XmlNode n in itmList)
                {
                    list.Add((T)Common.AssemblyUtil.TypeFactory.ConvertToEnum(n.Attributes["Value"].Value, t));
                }
            }
            else if (t == typeof(string))
            {
                foreach (System.Xml.XmlNode n in itmList)
                {
                    list.Add((T)Common.AssemblyUtil.TypeFactory.ConvertToString(n.Attributes["Value"].Value));
                }
            }
            else if (t == typeof(int))
            {
                foreach (System.Xml.XmlNode n in itmList)
                {
                    list.Add((T)Common.AssemblyUtil.TypeFactory.ConvertToInt32(n.Attributes["Value"].Value));
                }
            }
            else if (t == typeof(short))
            {
                foreach (System.Xml.XmlNode n in itmList)
                {
                    list.Add((T)Common.AssemblyUtil.TypeFactory.ConvertToInt16(n.Attributes["Value"].Value));
                }
            }
            else if (t == typeof(long))
            {
                foreach (System.Xml.XmlNode n in itmList)
                {
                    list.Add((T)Common.AssemblyUtil.TypeFactory.ConvertToInt64(n.Attributes["Value"].Value));
                }
            }
            else if (t == typeof(decimal))
            {
                foreach (System.Xml.XmlNode n in itmList)
                {
                    list.Add((T)Common.AssemblyUtil.TypeFactory.ConvertToDecimal(n.Attributes["Value"].Value));
                }
            }
            else if (t == typeof(Single))
            {
                foreach (System.Xml.XmlNode n in itmList)
                {
                    list.Add((T)Common.AssemblyUtil.TypeFactory.ConvertToSingle(n.Attributes["Value"].Value));
                }
            }
            else if (t == typeof(double))
            {
                foreach (System.Xml.XmlNode n in itmList)
                {
                    list.Add((T)Common.AssemblyUtil.TypeFactory.ConvertToDouble(n.Attributes["Value"].Value));
                }
            }
            else if (t == typeof(bool))
            {
                foreach (System.Xml.XmlNode n in itmList)
                {
                    list.Add((T)Common.AssemblyUtil.TypeFactory.ConvertToBoolean(n.Attributes["Value"].Value));
                }
            }
            else
            {
                throw new Common.Exceptions.NotSupportedFormatException(t);
            }

            return list;
        }

        /// <summary>
        /// 获取实体类型的数据
        /// </summary>
        /// <typeparam name="T">实体的数据类型</typeparam>
        /// <returns>返回实体引用</returns>
        public T GetEntity<T>() where T : new()
        {
            if (Data.GetType() == typeof(T))
            {
                return (T)Data;
            }
            else
            {
                System.Xml.XmlNode itmHead = ((System.Xml.XmlNode)Data).SelectSingleNode("Items");
                System.Xml.XmlNode itm = itmHead.SelectSingleNode("Item");

                T t = new T();
                PropertyInfo[] publicProperties = t.GetType().GetProperties();

                for (int i = 0; i < publicProperties.Length; i++)
                {
                    // 修改: 适应实体属性也是一个类  李鹏飞 2013.05.21  ---开始
                    if (itm.Attributes[publicProperties[i].Name] != null && 
                        (t.GetType().GetProperty(publicProperties[i].Name).PropertyType.IsValueType ||
                        t.GetType().GetProperty(publicProperties[i].Name).PropertyType.FullName.Contains("String")))
                    {
                        publicProperties[i].SetValue(t, Common.AssemblyUtil.TypeFactory.ConvertValueTypeObjectToOriginalType(itm.Attributes[publicProperties[i].Name].Value, publicProperties[i].PropertyType), null);
                    }
                    // 修改: 适应实体属性也是一个类  李鹏飞 2013.05.21  ---结束
                }

                return t;
            }
        }

        /// <summary>
        /// 获取String类型的数据
        /// </summary>
        /// <returns>返回字符串</returns>
        public string GetString()
        {
            return Data.ToString();
        }

        /// <summary>
        /// 获取Short类型的数据
        /// </summary>
        /// <returns>返回16位整型数据</returns>
        public short GetShort()
        {
            return Data.ToString().ToInt16();
        }

        /// <summary>
        /// 获取Int类型的数据
        /// </summary>
        /// <returns>返回32位整形数据</returns>
        public int GetInteger()
        {
            return Data.ToString().ToInt32();
        }

        /// <summary>
        /// 获取Long类型的数据
        /// </summary>
        /// <returns>返回64位整型数据</returns>
        public long GetLong()
        {
            return Data.ToString().ToInt64();
        }

        /// <summary>
        /// 获取Single类型的数据
        /// </summary>
        /// <returns>返回单精度浮点数据</returns>
        public Single GetSingle()
        {
            return Data.ToString().ToSingle();
        }

        /// <summary>
        /// 获取Double类型的数据
        /// </summary>
        /// <returns>返回双精度浮点数据</returns>
        public Double GetDouble()
        {
            return Data.ToString().ToDouble();
        }

        /// <summary>
        /// 获取Decimal类型的数据
        /// </summary>
        /// <returns>返回高精度浮点数据</returns>
        public decimal GetDecimal()
        {
            return Data.ToString().ToDecimal();
        }

        /// <summary>
        /// 获取数据表
        /// </summary>
        /// <returns>返回数据表</returns>
        public System.Data.DataTable GetDataTable()
        {
            return Data as System.Data.DataTable;
        }

        /// <summary>
        /// 获取二进制数组
        /// </summary>
        /// <returns>返回二进制数组</returns>
        public byte[] GetBinary()
        {
            return Data as byte[];
        }

        /// <summary>
        /// 获取字符串数组
        /// </summary>
        /// <returns>返回字符串数组</returns>
        public string[] GetArray()
        {
            return Data as string[];
        }

        /// <summary>
        /// 设置数据的值
        /// </summary>
        /// <param name="data">数据,支持格式:string、所有值类型数据、属性全部是值类型或string的实体及List列表、DataTable、byte[]</param>
        public void SetData(object data)
        {
            this.Data = data;
        }
    }
}