namespace Caliburn.Micro.Core {
    using System;
    /// 
    /// A base implementation of .
    /// 
    public class Screen : ViewAware, IScreen, IChild {
        static readonly ILog Log = LogManager.GetLog(typeof (Screen));
        bool isActive;
        bool isInitialized;
        object parent;
        string displayName;
        /// 
        /// Creates an instance of the screen.
        /// 
        public Screen() {
            displayName = GetType().FullName;
        }
        /// 
        /// Gets or Sets the Parent 
        /// 
        public virtual object Parent {
            get { return parent; }
            set {
                parent = value;
                NotifyOfPropertyChange("Parent");
            }
        }
        /// 
        /// Gets or Sets the Display Name
        /// 
        public virtual string DisplayName {
            get { return displayName; }
            set {
                displayName = value;
                NotifyOfPropertyChange("DisplayName");
            }
        }
        /// 
        /// Indicates whether or not this instance is currently active.
        /// Virtualized in order to help with document oriented view models.
        /// 
        public virtual bool IsActive {
            get { return isActive; }
            private set {
                isActive = value;
                NotifyOfPropertyChange("IsActive");
            }
        }
        /// 
        /// Indicates whether or not this instance is currently initialized.
        /// Virtualized in order to help with document oriented view models.
        /// 
        public virtual bool IsInitialized {
            get { return isInitialized; }
            private set {
                isInitialized = value;
                NotifyOfPropertyChange("IsInitialized");
            }
        }
        /// 
        /// Raised after activation occurs.
        /// 
        public virtual event EventHandler Activated = delegate { };
        /// 
        /// Raised before deactivation.
        /// 
        public virtual event EventHandler AttemptingDeactivation = delegate { };
        /// 
        /// Raised after deactivation.
        /// 
        public virtual event EventHandler Deactivated = delegate { };
        void IActivate.Activate() {
            if (IsActive) {
                return;
            }
            var initialized = false;
            if (!IsInitialized) {
                IsInitialized = initialized = true;
                OnInitialize();
            }
            IsActive = true;
            Log.Info("Activating {0}.", this);
            OnActivate();
            var handler = Activated;
            if (handler != null) {
                handler(this, new ActivationEventArgs
                {
                    WasInitialized = initialized
                });
            }
        }
        /// 
        /// Called when initializing.
        /// 
        protected virtual void OnInitialize() {}
        /// 
        /// Called when activating.
        /// 
        protected virtual void OnActivate() {}
        void IDeactivate.Deactivate(bool close) {
            if (IsActive || (IsInitialized && close)) {
                var attemptingDeactivationHandler = AttemptingDeactivation;
                if (attemptingDeactivationHandler != null) {
                    attemptingDeactivationHandler(this, new DeactivationEventArgs
                    {
                        WasClosed = close
                    });
                }
                IsActive = false;
                Log.Info("Deactivating {0}.", this);
                OnDeactivate(close);
                var deactivatedHandler = Deactivated;
                if (deactivatedHandler != null) {
                    deactivatedHandler(this, new DeactivationEventArgs
                    {
                        WasClosed = close
                    });
                }
                if (close) {
                    Views.Clear();
                    Log.Info("Closed {0}.", this);
                }
            }
        }
        /// 
        /// Called when deactivating.
        /// 
        /// Inidicates whether this instance will be closed.
        protected virtual void OnDeactivate(bool close) {}
        /// 
        /// Called to check whether or not this instance can close.
        /// 
        /// The implementor calls this action with the result of the close check.
        public virtual void CanClose(Action callback) {
            callback(true);
        }
        /// 
        /// Tries to close this instance by asking its Parent to initiate shutdown or by asking its corresponding view to close.
        /// Also provides an opportunity to pass a dialog result to it's corresponding view.
        /// 
        /// The dialog result.
        public virtual void TryClose(bool? dialogResult = null) {
            PlatformProvider.Current.GetViewCloseAction(this, Views.Values, dialogResult).OnUIThread();
        }
    }
}