namespace Fluent.Localization
{
    using System;
    using System.ComponentModel;
    using System.Reflection;
    using Fluent.Localization.Languages;

    /// <summary>
    /// Base class for localizations.
    /// </summary>
    public abstract class RibbonLocalizationBase : INotifyPropertyChanged, IEquatable<RibbonLocalizationBase>
    {
        /// <summary>
        /// Creates a new instance and initializes <see cref="CultureName"/> and <see cref="DisplayName"/> from <see cref="RibbonLocalizationAttribute"/>.
        /// </summary>
        protected RibbonLocalizationBase()
        {
            this.CultureName = this.GetType().GetCustomAttribute<RibbonLocalizationAttribute>()?.CultureName;
            this.DisplayName = this.GetType().GetCustomAttribute<RibbonLocalizationAttribute>()?.DisplayName;
        }

        /// <summary>
        /// Creates a new instance.
        /// </summary>
        protected RibbonLocalizationBase(string cultureName, string displayName)
        {
            this.CultureName = cultureName;
            this.DisplayName = displayName;
        }

        /// <summary>
        /// Gets or sets the culture name.
        /// </summary>
        public string CultureName { get; }

        /// <summary>
        /// Gets or sets the display name.
        /// </summary>
        public string DisplayName { get; }

        /// <summary>
        /// Fallback instance of <see cref="English"/> for localization.
        /// </summary>
        public static readonly RibbonLocalizationBase FallbackLocalization = new English();

        /// <summary>
        /// Gets text for representing "Automatic"
        /// </summary>
        public abstract string Automatic { get; }

        /// <summary>
        /// Gets KeyTip of backstage button
        /// </summary>
        public abstract string BackstageButtonKeyTip { get; }

        /// <summary>
        /// Gets text of backstage button
        /// </summary>
        public abstract string BackstageButtonText { get; }

        /// <summary>
        /// Gets customize Status Bar
        /// </summary>
        public abstract string CustomizeStatusBar { get; }

        /// <summary>
        /// Expand Button ScreenTip Text
        /// </summary>
        public abstract string ExpandButtonScreenTipText { get; }

        /// <summary>
        /// Expand Button ScreenTip Title
        /// </summary>
        public abstract string ExpandButtonScreenTipTitle { get; }

        /// <summary>
        /// Minimize Button ScreenTip Text
        /// </summary>
        public abstract string MinimizeButtonScreenTipText { get; }

        /// <summary>
        /// Minimize Button ScreenTip Title
        /// </summary>
        public abstract string MinimizeButtonScreenTipTitle { get; }

        /// <summary>
        /// Gets text for representing "More colors..."
        /// </summary>
        public abstract string MoreColors { get; }

        /// <summary>
        /// Gets text for representing "No color"
        /// </summary>
        public abstract string NoColor { get; }

        /// <summary>
        /// Quick Access ToolBar DropDown Button ToolTip
        /// </summary>
        public abstract string QuickAccessToolBarDropDownButtonTooltip { get; }

        /// <summary>
        /// Quick Access ToolBar  Menu Header
        /// </summary>
        public abstract string QuickAccessToolBarMenuHeader { get; }

        /// <summary>
        /// Quick Access ToolBar Menu Minimize Quick Access Toolbar
        /// </summary>
        public abstract string QuickAccessToolBarMenuShowAbove { get; }

        /// <summary>
        /// Quick Access ToolBar Minimize Quick Access Toolbar
        /// </summary>
        public abstract string QuickAccessToolBarMenuShowBelow { get; }

        /// <summary>
        /// Quick Access ToolBar MoreControls Button ToolTip
        /// </summary>
        public abstract string QuickAccessToolBarMoreControlsButtonTooltip { get; }

        /// <summary>
        /// Quick Access ToolBar Menu Add Gallery
        /// </summary>
        public abstract string RibbonContextMenuAddGallery { get; }

        /// <summary>
        /// Quick Access ToolBar Menu Add Group
        /// </summary>
        public abstract string RibbonContextMenuAddGroup { get; }

        /// <summary>
        /// Quick Access ToolBar Menu Add Item
        /// </summary>
        public abstract string RibbonContextMenuAddItem { get; }

        /// <summary>
        /// Quick Access ToolBar Menu Add Menu
        /// </summary>
        public abstract string RibbonContextMenuAddMenu { get; }

        /// <summary>
        /// Ribbon Context Menu Customize Quick Access Toolbar
        /// </summary>
        public abstract string RibbonContextMenuCustomizeQuickAccessToolBar { get; }

        /// <summary>
        /// Ribbon Context Menu Customize Quick Access Toolbar
        /// </summary>
        public abstract string RibbonContextMenuCustomizeRibbon { get; }

        /// <summary>
        /// Ribbon Context Menu Minimize Quick Access Toolbar
        /// </summary>
        public abstract string RibbonContextMenuMinimizeRibbon { get; }

        /// <summary>
        /// Quick Access ToolBar Menu Remove Item
        /// </summary>
        public abstract string RibbonContextMenuRemoveItem { get; }

        /// <summary>
        /// Ribbon Context Menu Minimize Quick Access Toolbar
        /// </summary>
        public abstract string RibbonContextMenuShowAbove { get; }

        /// <summary>
        /// Ribbon Context Menu Minimize Quick Access Toolbar
        /// </summary>
        public abstract string RibbonContextMenuShowBelow { get; }

        /// <summary>
        /// Gets ScreenTip's disable reason header
        /// </summary>
        public abstract string ScreenTipDisableReasonHeader { get; }

        /// <summary>
        /// Gets ScreenTip's disable reason header
        /// </summary>
        public abstract string ScreenTipF1LabelHeader { get; }

        /// <summary>
        /// Change notifications are not implemented.
        /// This class only implements <see cref="INotifyPropertyChanged"/> to prevent WPF from trying to listen to changes by using other ways than listening for this event.
        /// </summary>
#pragma warning disable 67
        public event PropertyChangedEventHandler PropertyChanged;
#pragma warning restore 67

        /// <inheritdoc />
        public bool Equals(RibbonLocalizationBase other)
        {
            if (other is null)
            {
                return false;
            }

            if (ReferenceEquals(this, other))
            {
                return true;
            }

            return this.CultureName == other.CultureName;
        }

        /// <inheritdoc />
        public override bool Equals(object obj)
        {
            if (obj is null)
            {
                return false;
            }

            if (ReferenceEquals(this, obj))
            {
                return true;
            }

            return obj is RibbonLocalizationBase localizationBase
                   && this.Equals(localizationBase);
        }

        /// <inheritdoc />
        public override int GetHashCode()
        {
            return this.CultureName != null
                ? this.CultureName.GetHashCode()
                : 0;
        }

        /// <summary>
        /// 
        /// </summary>
        public static bool operator ==(RibbonLocalizationBase left, RibbonLocalizationBase right)
        {
            return Equals(left, right);
        }

        /// <summary>
        /// 
        /// </summary>
        public static bool operator !=(RibbonLocalizationBase left, RibbonLocalizationBase right)
        {
            return !Equals(left, right);
        }
    }
}