using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace LauncherIcarus.Daemon
{
    public class SelectAllFocusBehavior
    {
        public static readonly DependencyProperty EnableProperty = DependencyProperty.RegisterAttached("Enable",
            typeof(bool), typeof(SelectAllFocusBehavior),
            (PropertyMetadata) new FrameworkPropertyMetadata((object) false,
                new PropertyChangedCallback(SelectAllFocusBehavior.OnEnableChanged)));

        public static bool GetEnable(FrameworkElement frameworkElement) =>
            (bool) frameworkElement.GetValue(SelectAllFocusBehavior.EnableProperty);

        public static void SetEnable(FrameworkElement frameworkElement, bool value) =>
            frameworkElement.SetValue(SelectAllFocusBehavior.EnableProperty, (object) value);

        private static void OnEnableChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!(d is FrameworkElement frameworkElement) || !(e.NewValue is bool))
                return;
            if ((bool) e.NewValue)
            {
                frameworkElement.GotFocus += new RoutedEventHandler(SelectAllFocusBehavior.SelectAll);
                frameworkElement.PreviewMouseDown +=
                    new MouseButtonEventHandler(SelectAllFocusBehavior.IgnoreMouseButton);
            }
            else
            {
                frameworkElement.GotFocus -= new RoutedEventHandler(SelectAllFocusBehavior.SelectAll);
                frameworkElement.PreviewMouseDown -=
                    new MouseButtonEventHandler(SelectAllFocusBehavior.IgnoreMouseButton);
            }
        }

        private static void SelectAll(object sender, RoutedEventArgs e)
        {
            FrameworkElement originalSource = e.OriginalSource as FrameworkElement;
            switch (originalSource)
            {
                case TextBox _:
                    ((TextBoxBase) originalSource).SelectAll();
                    break;
                case PasswordBox _:
                    ((PasswordBox) originalSource).SelectAll();
                    break;
            }
        }

        private static void IgnoreMouseButton(object sender, MouseButtonEventArgs e)
        {
            if (!(sender is FrameworkElement frameworkElement) || frameworkElement.IsKeyboardFocusWithin)
                return;
            e.Handled = true;
            frameworkElement.Focus();
        }
    }
}