﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LLVM.ClangTidy
{
    public class DynamicPropertyDescriptor<T> : PropertyDescriptor
    {
        T Value_;
        DynamicPropertyDescriptor<T> Parent_;
        bool IsInheriting_;
        object Component_;

        public DynamicPropertyDescriptor(object Component, DynamicPropertyDescriptor<T> Parent, string Name, Attribute[] Attrs)
            : base(Name, Attrs)
        {
            foreach (DefaultValueAttribute Attr in Attrs.OfType<DefaultValueAttribute>())
            {
                Value_ = (T)Attr.Value;
            }
            Parent_ = Parent;
            IsInheriting_ = true;
            Component_ = Component;
        }

        public bool IsInheriting { get { return IsInheriting_; } set { IsInheriting_ = value; } }
        public DynamicPropertyDescriptor<T> Parent { get { return Parent_; } }

        /// <summary>
        /// Determines whether this property's value should be considered "default" (e.g.
        /// displayed in bold in the property grid).  Root properties are unmodifiable and
        /// always default.  Non-root properties are default iff they are inheriting.
        /// That is to say, if a property is explicitly set to False, the property should
        /// be serialized even if the parent is also False.  It would only not be serialized
        /// if the user had explicitly chosen to inherit it.
        /// </summary>
        /// <param name="component"></param>
        /// <returns></returns>
        public override bool ShouldSerializeValue(object component)
        {
            return (Parent_ != null) && !IsInheriting;
        }

        /// <summary>
        /// Set the value back to the default.  For root properties, this essentially does
        /// nothing as they are read-only anyway.  For non-root properties, this only means
        /// that the property is now inheriting.
        /// </summary>
        /// <param name="component"></param>
        public override void ResetValue(object component)
        {
            IsInheriting_ = true;
        }

        public override void SetValue(object component, object value)
        {
            // This is a bit of a trick.  If the user chose the inheritance option from the
            // dropdown, we will try to set the value to that string.  So look for that and
            // then just reset the value.
            if (value.Equals(MagicInheritance.Text))
                ResetValue(component);
            else
            {
                // By explicitly setting the value, this property is no longer inheriting,
                // even if the value the property is being set to is the same as that of
                // the parent.
                IsInheriting_ = false;
                Value_ = (T)value;
            }
        }

        public override TypeConverter Converter
        {
            get
            {
                // We need to return a DynamicPropertyConverter<> that can deal with our requirement
                // to inject the inherit property option into the dropdown.  But we still need to use
                // the "real" converter to do the actual work for the underlying type.  Therefore,
                // we need to look for a TypeConverter<> attribute on the property, and if it is present
                // forward an instance of that converter to the DynamicPropertyConverter<>.  Otherwise,
                // forward an instance of the default converter for type T to the DynamicPropertyConverter<>.
                TypeConverter UnderlyingConverter = null;
                var ConverterAttr = this.Attributes.OfType<TypeConverterAttribute>().LastOrDefault();
                if (ConverterAttr != null)
                {
                    Type ConverterType = Type.GetType(ConverterAttr.ConverterTypeName);
                    UnderlyingConverter = (TypeConverter)Activator.CreateInstance(ConverterType);
                }
                else
                    UnderlyingConverter = TypeDescriptor.GetConverter(typeof(T));

                return new DynamicPropertyConverter<T>(this, UnderlyingConverter);
            }
        }

        public override bool IsReadOnly
        {
            get
            {
                return (Parent_ == null);
            }
        }

        public override Type ComponentType
        {
            get
            {
                return Component_.GetType();
            }
        }

        public override object GetValue(object component)
        {
            // Return either this property's value or the parents value, depending on
            // whether or not this property is inheriting.
            if (IsInheriting_ && Parent != null)
                return Parent.GetValue(component);
            return Value_;
        }

        public override bool CanResetValue(object component)
        {
            return !IsReadOnly;
        }

        public override Type PropertyType
        {
            get
            {
                return typeof(T);
            }
        }
    }
}
