using AIMSExtension;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms; 
namespace DrawGraph
{
    /// 
    /// 实例类属性改变时进行通知
    /// 
    public class EntityObjectChangeNotifier
    {
        public static event EventHandler ObjectChanged;
        private static bool isSetOk = true; //设置值是否成功
        public static bool isCreateOk = false;
        /// 
        /// 为属性幅值
        /// 
        /// 类的类型
        /// 类的属性
        /// 显示的文本
        /// 真正的值
        /// 为真时做数据库更新
        public static void SetValue(object t, string propertyName, string text, string value, bool isUpdate = false, ZedGraphControl ZedControl = null)
        {
            isSetOk = true;
            try
            {
                //给属性赋值
                object oldValue = SubObjSetValue(t, propertyName, value);
                if (oldValue == null) oldValue = "";
                if (isUpdate)
                {
                    //为真时更新数据库  
                    DocumentEntityMethod.SetOperationRecordValue(t, propertyName, value);
                }
                propertyName = propertyName.Replace(t.GetType().Name + ".", "");
                //通知组件显示文本
                ObjectChangedEventArgs args = new ObjectChangedEventArgs(t.GetType().Name + "." + propertyName, oldValue, text, value, ZedControl);
                if (ObjectChanged != null) ObjectChanged(t, args);
                args = null;
            }
            catch (Exception exp)
            {
                MessageBox.Show(propertyName + "属性设置错误:" + exp.Message);
            }
        }
        public static object SubObjSetValue(object t, string propertyName, string value)
        {
            object oldValue = null;
            List propertys = new List();
            if (propertyName.IndexOf('.') > 0)
            {
                propertys = propertyName.Split('.').ToList();
            }
            else
            {
                propertys.Add(propertyName);
            }
            for (int i = 0; i < propertys.Count; i++)
            {
                string pro = propertys[i];
                if (i == propertys.Count - 1)
                {
                    //最后一个
                    PropertyInfo p = t.GetType().GetProperties().SingleOrDefault(x => x.Name == pro);
                    if (p == default(PropertyInfo))
                    {
                        isSetOk = false;
                    }
                    else
                    {
                        Attribute[] attribs = Attribute.GetCustomAttributes(p);
                        Attribute attrib = attribs.FirstOrDefault(s => s is NoCreatControlAttributs);
                        //如果增加了NoCreatControlAttributs这个属性的属性则不生成列表
                        oldValue = p.GetValue(t, new object[] { });
                        //如果这个属性的标签是不取值的属性,则返回
                        if (attrib != null)
                        {
                            isSetOk = false;
                            return oldValue;
                        }
                        if (p.PropertyType == typeof(System.DateTime) && value == "")
                        {
                        }
                        else
                        {
                            p.SetValue(t, ChanageType(value, p.PropertyType), new object[] { });
                        }
                        return oldValue;
                    }
                }
                else
                {
                    try
                    {
                        PropertyInfo p = t.GetType().GetProperties().SingleOrDefault(x => x.Name == pro);
                        if (p == default(PropertyInfo))
                        {
                            isSetOk = false;
                        }
                        else
                        {
                            Attribute[] attribs = Attribute.GetCustomAttributes(p);
                            Attribute attrib = attribs.FirstOrDefault(s => s is NoCreatControlAttributs);
                            //如果增加了NoCreatControlAttributs这个属性的属性则不生成列表
                            object subObj = p.GetValue(t, new object[] { });
                            //如果这个属性的标签是不取值的属性,则返回
                            if (attrib != null)
                            {
                                isSetOk = false;
                                return subObj;
                            }
                            string subProName = propertyName.Replace((pro + "."), "");
                            oldValue = SubObjSetValue(subObj, subProName, value);
                            //当循环得到值后后面的就不需要循环了
                            break;
                        }
                    }
                    catch (Exception  )
                    { 
                        //throw;
                    }
                }
            }
            return oldValue;
        }
        private static object ChanageType(object value, Type convertsionType)
        {
            //判断convertsionType类型是否为泛型,因为nullable是泛型类,
            if (convertsionType.IsGenericType &&
                //判断convertsionType是否为nullable泛型类
                convertsionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                if (value == null || value.ToString().Length == 0)
                {
                    return null;
                }
                //如果convertsionType为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
                NullableConverter nullableConverter = new NullableConverter(convertsionType);
                //将convertsionType转换为nullable对的基础基元类型
                convertsionType = nullableConverter.UnderlyingType;
            }
            return Convert.ChangeType(value, convertsionType);
        }
    }
    public class ObjectChangedEventArgs : EventArgs
    {
        public string PropertyName { get; set; }
        public object OldValue { get; private set; }
        public object NewValue { get; private set; }
        public object NewText { get; private set; }
        public object ZedControl { get; private set; }
        public ObjectChangedEventArgs(string name, object oldvalue, Object newText, object newValue, ZedGraphControl zedControl = null)
        {
            PropertyName = name;
            OldValue = oldvalue;
            NewValue = newValue;
            NewText = newText;
            ZedControl = zedControl;
        }
    }
}