using System;
using System.Data;
using System.Data.Common;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Collections;
using System.Collections.Specialized;
using Winson.Framework.DBProviders;
using Winson.Framework.LogProviders;

namespace Winson.ModelOP
{
    public class ModelOP
    {
        ModelCollection<TestDS> TestList;
        TestDS testDS;
        string sql;
        private string _tableName;
        private string _primekey;

        public ModelOP(string tableName)
        {
            _tableName = tableName;
            sql = "select * from " + _tableName;
            _primekey = GetPrimeKey();
        }

        public IList Get(NameValueCollection conditionValue)
        {
            try
            {
                TestList = new ModelCollection<TestDS>();
                //将数据填充到实体集合
                DbDataReader dr = null;
                dr = DBManage.ExecuteReader(DBManage.Conn, sql, conditionValue);
                while (dr.Read())
                {
                    testDS = new TestDS();
                    FillDS(testDS, dr);
                    TestList.Add(testDS);
                }
                return TestList;
            }
            catch (Exception e)
            {
                LogManage.OutputErrLog(e, new Object[] { conditionValue });
                return null;
            }
            finally
            {
                DBManage.Conn.Close();
            }
        }

        public TestDS GetModel(NameValueCollection conditionValue)
        {
            DbDataReader dr = null;
            try
            {
                //将数据填充到实体集合                
                dr = DBManage.ExecuteReader(DBManage.Conn, sql, conditionValue);
                if (dr.Read())
                {
                    testDS = new TestDS();
                    FillDS(testDS, dr);
                    return testDS;
                }
                else
                    return null;
            }
            catch (Exception e)
            {
                LogManage.OutputErrLog(e, new Object[] { conditionValue });
                return null;
            }
            finally
            {
                dr.Close();
                DBManage.Conn.Close();
            }
        }

        public TestDS GetModel(IList modelList, int fieldID)
        {
            try
            {
                foreach (TestDS Test_DS in modelList)
                {
                    if (Test_DS.Id == fieldID)
                        return Test_DS;
                }
                return null;
            }
            catch (Exception e)
            {
                LogManage.OutputErrLog(e, new Object[] { modelList, fieldID });
                return null;
            }
        }

        public int Add(TestDS ds)
        {
            ArrayList fieldName = new ArrayList();
            ArrayList fieldValue = new ArrayList();
            int maxID = GetMaxID();
            for (int i = 0; i < ds.Count; i++)
            {
                if (ds[i, 1, maxID] != null)
                {
                    fieldName.Add(ds[i, 1, maxID]);
                    fieldValue.Add(ds[i, 0, maxID]);
                }
            }
            return DBManage.ExecuteNonQuery(DBAction.Insert, _tableName, fieldName, fieldValue);
        }

        public int Update(TestDS ds, NameValueCollection conditionValue)
        {
            ArrayList fieldName = new ArrayList();
            ArrayList fieldValue = new ArrayList();
            for (int i = 0; i < ds.Count; i++)
            {
                if (ds[i, 1, 0] != null)
                {
                    fieldName.Add(ds[i, 1, 0]);
                    fieldValue.Add(ds[i, 0, 0]);
                }
            }
            return DBManage.ExecuteNonQuery(DBAction.Update, _tableName, fieldName, fieldValue, conditionValue);
        }

        public int GetMaxID()
        {
            object max = null;
            int maxID = 1;
            string sql = "select max(" + _primekey + ") from " + _tableName;
            max = DBManage.ExecuteScalar(sql);
            if (max != null && max.ToString().Length > 0)
                maxID = (int)max + 1;
            return maxID;
        }

        #region 批量数据操作
        /// <summary>
        /// 批量添加实体记录
        /// </summary>
        /// <param name="modelList">实体集合</param>
        /// <returns>成功为True 否则为False</returns>
        public bool BatchAdd(IList modelList)
        {
            DataTable dt = new DataTable();
            DataColumn dc = null;
            DataRow dr = null;

            int maxID = GetMaxID();

            PropertyInfo[] properties = modelList[0].GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);

            foreach (PropertyInfo item in properties)
            {
                if (item.CanRead && item.Name != null && item.Name.ToLower() != "item" && item.Name.ToLower() != "count")
                {
                    dc = new DataColumn(item.Name);
                    dc.DataType = item.PropertyType;
                    dt.Columns.Add(dc);
                }
            }

            for (int n = 0; n < modelList.Count; n++)
            {
                dr = dt.NewRow();
                //反射取得相关成员属性
                properties = modelList[n].GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);

                foreach (PropertyInfo item in properties)
                {
                    if (item.CanRead && item.Name.ToLower() != "item" && item.Name.ToLower() != "count")
                    {
                        if (item.Name.ToLower().Equals(_primekey))//判断如果是主键，则进行自增
                            dr[item.Name] = maxID;
                        else
                            dr[item.Name] = item.GetValue(modelList[n], null);
                    }
                }
                //构建Datatable以批量操作
                dt.Rows.Add(dr);
                maxID++;
            }
            return DBManage.ExecuteBatchInsert(_tableName, dt);
        }

        /// <summary>
        /// 批量更新实体记录
        /// </summary>
        /// <param name="modelList">实体集合</param>
        /// <returns>成功为True 否则为False</returns>
        public bool BatchUpdate(IList modelList)
        {
            DataTable dt = new DataTable();
            DataColumn dc = null;
            DataRow dr = null;


            PropertyInfo[] properties = modelList[0].GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);

            foreach (PropertyInfo item in properties)
            {
                if (item.CanRead && item.Name != null && item.Name.ToLower() != "item" && item.Name.ToLower() != "count")
                {
                    dc = new DataColumn(item.Name);
                    dc.DataType = item.PropertyType;
                    dt.Columns.Add(dc);
                }
            }

            for (int n = 0; n < modelList.Count; n++)
            {
                dr = dt.NewRow();
                //反射取得相关成员属性
                properties = modelList[n].GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);

                foreach (PropertyInfo item in properties)
                {
                    if (item.CanRead && item.Name.ToLower() != "item" && item.Name.ToLower() != "count")
                    {
                        dr[item.Name] = item.GetValue(modelList[n], null);
                    }
                }
                //构建Datatable以批量操作
                dt.Rows.Add(dr);

            }
            return DBManage.ExecuteBatchUpdate(_tableName, _primekey, dt);
        }

        #endregion

        #region 私有方法
        /// <summary>
        /// 填充实体内容
        /// </summary>
        /// <param name="targetObj">实体对象</param>
        /// <param name="dr">DbDataReader对象</param>
        private void FillDS(object targetObj, DbDataReader reader)
        {
            //实现首字母大写，规范所有属性名称
            System.Globalization.CultureInfo cult = System.Threading.Thread.CurrentThread.CurrentCulture;
            System.Globalization.TextInfo textInfo = cult.TextInfo;
            string name = string.Empty;

            for (int i = 0; i < reader.FieldCount; i++)
            {
                name = textInfo.ToTitleCase(reader.GetName(i).ToLower());
                PropertyInfo propertyInfo = targetObj.GetType().GetProperty(name);
                if (propertyInfo != null)
                {
                    if (reader.GetValue(i) != DBNull.Value && propertyInfo.CanWrite)
                    {
                        propertyInfo.SetValue(targetObj, reader.GetValue(i), null);
                    }
                }
            }
        }

        /// <summary>
        /// 获取当前操作表的主键名称
        /// </summary>
        /// <returns>主键名称</returns>
        private string GetPrimeKey()
        {
            string cSQL = "select rtrim(b.name) as colname from sysobjects a,syscolumns b " +
                          "left outer join sysproperties c on b.id = c.id and b.colid = c.smallid " +
                          "left outer join syscomments e on b.cdefault = e.id " +
                          "left outer join (select g.id,g.colid from sysindexes f,sysindexkeys g " +
                          "where f.id = g.id and f.indid = g.indid and f.indid > 0 and " +
                          "f.indid < 255 and (f.status & 2048)<>0) h on b.id = h.id " +
                          "and b.colid = h.colid where a.id = b.id and a.status>0 and h.id is not null and  a.name='" + _tableName + "'";
            return DBManage.ExecuteScalar(cSQL).ToString();
        }
        #endregion

    }
}
