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

namespace ImageSort.WPF.SettingsManagement.ShortCutManagement;

/// <summary>
///     Interaction logic for HotkeyEditorControl.xaml
/// </summary>
public partial class HotkeyEditorControl : UserControl
{
    public HotkeyEditorControl()
    {
        InitializeComponent();
        DataContext = this;
    }

    public static readonly DependencyProperty HotkeyProperty =
        DependencyProperty.Register(nameof(Hotkey), typeof(Hotkey),
            typeof(HotkeyEditorControl),
            new FrameworkPropertyMetadata(default(Hotkey),
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                OnHotkeyChanged));

    public Hotkey Hotkey
    {
        get => (Hotkey)GetValue(HotkeyProperty);
        set => SetValue(HotkeyProperty, value);
    }

    private static void OnHotkeyChanged(DependencyObject @object, DependencyPropertyChangedEventArgs args)
    {
        if (@object is HotkeyEditorControl hotkeyEditorControl)
            hotkeyEditorControl.HotkeyChanged?.Invoke(hotkeyEditorControl, new EventArgs());
    }

    public event EventHandler HotkeyChanged;

    private void HotkeyTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        // Don't let the event pass further
        // because we don't want standard textbox shortcuts working
        e.Handled = true;

        // Get modifiers and key data
        var modifiers = Keyboard.Modifiers;
        var key = e.Key;

        // When Alt is pressed, SystemKey is used instead
        if (key == Key.System) key = e.SystemKey;

        // Pressing delete, backspace or escape without modifiers clears the current value
        if (modifiers == ModifierKeys.None &&
            (key == Key.Delete || key == Key.Back || key == Key.Escape))
        {
            Hotkey = null;
            return;
        }

        // If no actual key was pressed - return
        if (GetIfNotAnActualKey(key))
            return;

        // Update the value
        Hotkey = new Hotkey(key, modifiers);
    }

    private static bool GetIfNotAnActualKey(Key key)
    {
        return key == Key.LeftCtrl ||
               key == Key.RightCtrl ||
               key == Key.LeftAlt ||
               key == Key.RightAlt ||
               key == Key.LeftShift ||
               key == Key.RightShift ||
               key == Key.LWin ||
               key == Key.RWin ||
               key == Key.Clear ||
               key == Key.OemClear ||
               key == Key.Apps;
    }
}