namespace Caliburn.Micro.Core {
    using System;
    /// 
    /// Hosts extension methods for  classes.
    /// 
    public static class ScreenExtensions {
        /// 
        /// Activates the item if it implements , otherwise does nothing.
        /// 
        /// The potential activatable.
        public static void TryActivate(object potentialActivatable) {
            var activator = potentialActivatable as IActivate;
            if (activator != null)
                activator.Activate();
        }
        /// 
        /// Deactivates the item if it implements , otherwise does nothing.
        /// 
        /// The potential deactivatable.
        /// Indicates whether or not to close the item after deactivating it.
        public static void TryDeactivate(object potentialDeactivatable, bool close) {
            var deactivator = potentialDeactivatable as IDeactivate;
            if (deactivator != null)
                deactivator.Deactivate(close);
        }
        /// 
        /// Closes the specified item.
        /// 
        /// The conductor.
        /// The item to close.
        public static void CloseItem(this IConductor conductor, object item) {
            conductor.DeactivateItem(item, true);
        }
        /// 
        /// Closes the specified item.
        /// 
        /// The conductor.
        /// The item to close.
        public static void CloseItem(this ConductorBase conductor, T item) where T: class {
            conductor.DeactivateItem(item, true);
        }
        ///
        /// Activates a child whenever the specified parent is activated.
        ///
        ///The child to activate.
        ///The parent whose activation triggers the child's activation.
        public static void ActivateWith(this IActivate child, IActivate parent) {
            var childReference = new WeakReference(child);
            EventHandler handler = null;
            handler = (s, e) => {
                var activatable = (IActivate) childReference.Target;
                if (activatable == null)
                    ((IActivate) s).Activated -= handler;
                else
                    activatable.Activate();
            };
            parent.Activated += handler;
        }
        ///
        /// Deactivates a child whenever the specified parent is deactivated.
        ///
        ///The child to deactivate.
        ///The parent whose deactivation triggers the child's deactivation.
        public static void DeactivateWith(this IDeactivate child, IDeactivate parent) {
            var childReference = new WeakReference(child);
            EventHandler handler = null;
            handler = (s, e) => {
                var deactivatable = (IDeactivate) childReference.Target;
                if (deactivatable == null)
                    ((IDeactivate)s).Deactivated -= handler;
                else
                    deactivatable.Deactivate(e.WasClosed);
            };
            parent.Deactivated += handler;
        }
        ///
        /// Activates and Deactivates a child whenever the specified parent is Activated or Deactivated.
        ///
        ///The child to activate/deactivate.
        ///The parent whose activation/deactivation triggers the child's activation/deactivation.
        public static void ConductWith(this TChild child, TParent parent) 
            where TChild : IActivate, IDeactivate
            where TParent : IActivate, IDeactivate
        {
            child.ActivateWith(parent);
            child.DeactivateWith(parent);
        }
    }
}