namespace Caliburn.Micro {
    using System;
    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Interactivity;
    /// 
    /// Represents a parameter of an .
    /// 
    public class Parameter : Freezable, IAttachedObject {
        /// 
        /// A dependency property representing the parameter's value.
        /// 
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register(
                "Value",
                typeof(object),
                typeof(Parameter),
                new PropertyMetadata(OnValueChanged)
                );
        DependencyObject associatedObject;
        WeakReference owner;
        /// 
        /// Gets or sets the value of the parameter.
        /// 
        /// The value.
        [Category("Common Properties")]
        public object Value {
            get { return GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }
        DependencyObject IAttachedObject.AssociatedObject {
            get
            {
                ReadPreamble();
                return associatedObject;
            }
        }
        /// 
        /// Gets or sets the owner.
        /// 
        protected ActionMessage Owner {
            get { return owner == null ? null : owner.Target as ActionMessage; }
            set { owner = new WeakReference(value); }
        }
        void IAttachedObject.Attach(DependencyObject dependencyObject) {
            WritePreamble();
            associatedObject = dependencyObject;
            WritePostscript();
        }
        void IAttachedObject.Detach() {
            WritePreamble();
            associatedObject = null;
            WritePostscript();
        }
        /// 
        /// When implemented in a derived class, creates a new instance of the  derived class.
        /// 
        /// The new instance.
        protected override Freezable CreateInstanceCore() {
            return new Parameter();
        }
        /// 
        /// Makes the parameter aware of the  that it's attached to.
        /// 
        /// The action message.
        internal void MakeAwareOf(ActionMessage owner) {
            Owner = owner;
        }
        static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
            var parameter = (Parameter)d;
            var owner = parameter.Owner;
            if (owner != null) {
                owner.UpdateAvailability();
            }
        }
    }
}