// ToggleButtonRibbonUICommand.cs
// Copyright (c) 2016 Bentley Systems, Incorporated. All Rights Reserved.

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;

namespace Haestad.Framework.UI.Integration
{
    /// <summary>
    /// Class represents a command that when added to a RibbonCommandUICollection with other ToggleButtonRibbonUICommand instances, 
    /// will manage syncing toggle buttons for those different commands in order to mimic a radio button style behavior.
    /// *ownerCollection* must not be null, else the ctor will throw.
    /// </summary>
    public class ToggleButtonRibbonUICommand : RibbonUICommand
    {
        #region Constructors

        /// <summary>
        /// Instantiates a new ToggleButtonRibbonUICommand.
        /// </summary>
        /// <param name="ownerCollection">The IRibbonUICommandCollection implementation instance that owns this command (i.e., the group it is in).</param>
        /// <param name="command">The associated ICommand.</param>
        /// <param name="name">The *unique* name of the ribbon UI command.</param>
        /// <param name="labelKey">The resource key used to look up the ribbon UI command label from TextManager.</param>
        /// <param name="toolTipTitleKey">The resource key used to look up the ribbon UI command label from TextManager.</param>
        /// <param name="toolTipDescriptionKey">The resource key used to look up the ribbon UI command label from TextManager.</param>
        /// <param name="graphicResourceKey">The graphic resource key for the regular (small) image size.</param>
        public ToggleButtonRibbonUICommand(IRibbonUICommandCollection ownerCollection, ICommand command, string name, string labelKey, string toolTipTitleKey, string toolTipDescriptionKey,
            string graphicResourceKey)
            : base(command, name, labelKey, toolTipTitleKey, toolTipDescriptionKey, graphicResourceKey, String.Empty)
        {
            OwnerCollection = ownerCollection;
            OwnerCollection.RelatedCommands.Add(this);
        }

        /// <summary>
        /// Instantiates a new ToggleButtonRibbonUICommand.
        /// </summary>
        /// <param name="ownerCollection">The IRibbonUICommandCollection implementation instance that owns this command (i.e., the group it is in).</param>
        /// <param name="command">The associated ICommand.</param>
        /// <param name="name">The *unique* name of the ribbon UI command.</param>
        /// <param name="labelKey">The resource key used to look up the ribbon UI command label from TextManager.</param>
        /// <param name="toolTipTitleKey">The resource key used to look up the ribbon UI command label from TextManager.</param>
        /// <param name="toolTipDescriptionKey">The resource key used to look up the ribbon UI command label from TextManager.</param>
        /// <param name="graphicResourceKey">The graphic resource key for the regular (small) image size.</param>
        /// <param name="largeGraphicResourceKey">The graphic resource key for the large image size.</param>
        public ToggleButtonRibbonUICommand(IRibbonUICommandCollection ownerCollection, ICommand command, string name, string labelKey, string toolTipTitleKey, string toolTipDescriptionKey,
            string graphicResourceKey, string largeGraphicResourceKey)
            : base(command, name, labelKey, toolTipTitleKey, toolTipDescriptionKey, graphicResourceKey, largeGraphicResourceKey, RibbonHotKey.None)
        {
            OwnerCollection = ownerCollection;
            OwnerCollection.RelatedCommands.Add(this);
        }

        /// <summary>
        /// Instantiates a new ToggleButtonRibbonUICommand.
        /// </summary>
        /// <param name="ownerCollection">The IRibbonUICommandCollection implementation instance that owns this command (i.e., the group it is in).</param>
        /// <param name="command">The associated ICommand.</param>
        /// <param name="name">The *unique* name of the ribbon UI command.</param>
        /// <param name="labelKey">The resource key used to look up the ribbon UI command label from TextManager.</param>
        /// <param name="toolTipTitleKey">The resource key used to look up the ribbon UI command label from TextManager.</param>
        /// <param name="toolTipDescriptionKey">The resource key used to look up the ribbon UI command label from TextManager.</param>
        /// <param name="graphicResourceKey">The graphic resource key for the regular (small) image size.</param>
        /// <param name="largeGraphicResourceKey">The graphic resource key for the large image size.</param>
        /// <param name="hotKey">The ribbon hot key to use for the command.</param>
        public ToggleButtonRibbonUICommand(IRibbonUICommandCollection ownerCollection, ICommand command, string name, string labelKey, string toolTipTitleKey, string toolTipDescriptionKey,
            string graphicResourceKey, string largeGraphicResourceKey, RibbonHotKey hotKey) : 
            base(command, name, labelKey, toolTipTitleKey, toolTipDescriptionKey, graphicResourceKey, largeGraphicResourceKey, hotKey)
        {
            OwnerCollection = ownerCollection;
            OwnerCollection.RelatedCommands.Add(this);
        }
        #endregion

        #region Protected Override Methods
        protected override bool BeforeExecute()
        {
            if (!GetShouldExecuteCommand())
                return false;

            return true;
        }

        protected override void AfterExecute()
        {
            SetToggleButtonsIsChecked(true);
            SetRelatedCommandsToggleButtonsIsCheckedToFalse();
        }
        #endregion

        #region Internal Methods
        internal void SetToggleButtonsIsChecked(bool isChecked)
        {
            IList<FrameworkElement> toggleButtons = GetLinkedElements(RibbonUICommandLinkedElementTypes.ToggleButtons);
            foreach (RadRibbonToggleButtonEx toggleButton in toggleButtons)
                toggleButton.IsChecked = isChecked;
        }

        internal bool GetIsAtLeastOneOtherToggleButtonInToggleButtonGroup()
        {
            foreach (IRibbonUICommand ribbonUICommand in OwnerCollection.RelatedCommands)
            {
                if (ribbonUICommand is ToggleButtonRibbonUICommand && (!ribbonUICommand.Equals(this)))
                {
                    if (((ToggleButtonRibbonUICommand)ribbonUICommand).GetToggleButtonCount() > 0)
                        return true;
                }
            }
            return false;
        }

        internal int GetToggleButtonCount()
        {
            return GetLinkedElements(RibbonUICommandLinkedElementTypes.ToggleButtons).Count;
        }
        #endregion

        #region Private Methods
        private void SetRelatedCommandsToggleButtonsIsCheckedToFalse()
        {
            foreach (IRibbonUICommand ribbonUICommand in OwnerCollection.RelatedCommands)
            {
                if (ribbonUICommand is ToggleButtonRibbonUICommand && (!ribbonUICommand.Equals(this)))
                    ((ToggleButtonRibbonUICommand)ribbonUICommand).SetToggleButtonsIsChecked(false);
            }
        }

        private bool GetShouldExecuteCommand()
        {
            if (GetHasNoToggleButtons())
                return true;

            return !GetIsChecked();
        }

        private bool GetHasNoToggleButtons()
        {
            IList<FrameworkElement> toggleButtons = GetLinkedElements(RibbonUICommandLinkedElementTypes.ToggleButtons);
            if (toggleButtons.Count == 0)
                return true;

            return false;
        }

        private bool GetIsChecked()
        {
            IList<FrameworkElement> toggleButtons = GetLinkedElements(RibbonUICommandLinkedElementTypes.ToggleButtons);
            bool? isChecked = ((RadRibbonToggleButtonEx)toggleButtons[0]).IsChecked;
            return isChecked.HasValue ? (bool)isChecked : false;
        }
        #endregion

        #region Private Properties
        private IRibbonUICommandCollection OwnerCollection
        {
            get;
            set;
        }
        #endregion
    }
}
