#if XFORMS
namespace Caliburn.Micro.Core.Xamarin.Forms
#else
namespace Caliburn.Micro
#endif
{
    using System;
    using System.Collections.Generic;
    using System.Reflection;
#if WinRT
    using Windows.UI.Xaml;
#elif XFORMS
    using global::Xamarin.Forms;
    using DependencyObject = global::Xamarin.Forms.BindableObject;
    using DependencyProperty = global::Xamarin.Forms.BindableProperty;
    using FrameworkElement = global::Xamarin.Forms.VisualElement;
#else
    using System.Windows;
#endif
    /// 
    /// The context used during the execution of an Action or its guard.
    /// 
    public class ActionExecutionContext : IDisposable {
        private WeakReference message;
        private WeakReference source;
        private WeakReference target;
        private WeakReference view;
        private Dictionary values;
        /// 
        /// Determines whether the action can execute.
        /// 
        /// Returns true if the action can execute, false otherwise.
        public Func CanExecute;
        /// 
        /// Any event arguments associated with the action's invocation.
        /// 
        public object EventArgs;
        /// 
        /// The actual method info to be invoked.
        /// 
        public MethodInfo Method;
        /// 
        /// The message being executed.
        /// 
        public ActionMessage Message {
            get { return message == null ? null : message.Target as ActionMessage; }
            set { message = new WeakReference(value); }
        }
        /// 
        /// The source from which the message originates.
        /// 
        public FrameworkElement Source {
            get { return source == null ? null : source.Target as FrameworkElement; }
            set { source = new WeakReference(value); }
        }
        /// 
        /// The instance on which the action is invoked.
        /// 
        public object Target {
            get { return target == null ? null : target.Target; }
            set { target = new WeakReference(value); }
        }
        /// 
        /// The view associated with the target.
        /// 
        public DependencyObject View {
            get { return view == null ? null : view.Target as DependencyObject; }
            set { view = new WeakReference(value); }
        }
        /// 
        /// Gets or sets additional data needed to invoke the action.
        /// 
        /// The data key.
        /// Custom data associated with the context.
        public object this[string key] {
            get {
                if (values == null)
                    values = new Dictionary();
                object result;
                values.TryGetValue(key, out result);
                return result;
            }
            set {
                if (values == null)
                    values = new Dictionary();
                values[key] = value;
            }
        }
        /// 
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// 
        public void Dispose() {
            Disposing(this, System.EventArgs.Empty);
        }
        /// 
        /// Called when the execution context is disposed
        /// 
        public event EventHandler Disposing = delegate { };
    }
}