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

namespace KoloryWPF
{
    public class ZamknięcieOknaPoNaciśnieciuKlawisza : Behavior<Window>
    {
        public Key Klawisz { get; set; }

        protected override void OnAttached()
        {
            Window window = this.AssociatedObject;
            if (window != null) window.PreviewKeyDown += Window_PreviewKeyDown;
        }

        private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            Window window = (Window)sender;
            if (e.Key == Klawisz) window.Close();
        }
    }

    public class PrzyciskZamykającyOkno : Behavior<Window>
    {
        public static readonly DependencyProperty PrzyciskProperty =
            DependencyProperty.Register(
                "Przycisk",
                typeof(Button),
                typeof(PrzyciskZamykającyOkno),
                new PropertyMetadata(null, PrzyciskZmieniony)
            );

        public Button Przycisk
        {
            get { return (Button)GetValue(PrzyciskProperty); }
            set { SetValue(PrzyciskProperty, value); }
        }

        private static void PrzyciskZmieniony(DependencyObject d,
                                              DependencyPropertyChangedEventArgs e)
        {
            Window window = (d as PrzyciskZamykającyOkno).AssociatedObject;
            RoutedEventHandler button_Click =
                (object sender, RoutedEventArgs _e) => { window.Close(); };
            if (e.OldValue != null) ((Button)e.OldValue).Click -= button_Click;
            if (e.NewValue != null) ((Button)e.NewValue).Click += button_Click;
        }
    }

    public class PrzyciskZamykającyOknoZPoleceniem : Behavior<Window>
    {
        public static readonly DependencyProperty PrzyciskProperty =
            DependencyProperty.Register(
                "Przycisk",
                typeof(Button),
                typeof(PrzyciskZamykającyOknoZPoleceniem),
                new PropertyMetadata(null, PrzyciskZmieniony)
            );

        public Button Przycisk
        {
            get { return (Button)GetValue(PrzyciskProperty); }
            set { SetValue(PrzyciskProperty, value); }
        }

        public static readonly DependencyProperty PolecenieProperty =
            DependencyProperty.Register(
                "Polecenie",
                typeof(ICommand),
                typeof(PrzyciskZamykającyOknoZPoleceniem));

        public ICommand Polecenie
        {
            get { return (ICommand)GetValue(PolecenieProperty); }
            set { SetValue(PolecenieProperty, value); }
        }

        public static readonly DependencyProperty ParametrPoleceniaProperty =
            DependencyProperty.Register(
                "ParametrPolecenia",
                typeof(object),
                typeof(PrzyciskZamykającyOknoZPoleceniem));

        public object ParametrPolecenia
        {
            get { return (object)GetValue(ParametrPoleceniaProperty); }
            set { SetValue(ParametrPoleceniaProperty, value); }
        }

        private static void PrzyciskZmieniony(DependencyObject d,
                                              DependencyPropertyChangedEventArgs e)
        {
            Window window = (d as PrzyciskZamykającyOknoZPoleceniem).AssociatedObject;
            RoutedEventHandler button_Click =
                (object sender, RoutedEventArgs _e) =>
                {
                    ICommand polecenie = (d as PrzyciskZamykającyOknoZPoleceniem).Polecenie;
                    object parametrPolecenia =
                        (d as PrzyciskZamykającyOknoZPoleceniem).ParametrPolecenia;
                    if (polecenie != null) polecenie.Execute(parametrPolecenia);
                    window.Close();
                };
            if (e.OldValue != null) ((Button)e.OldValue).Click -= button_Click;
            if (e.NewValue != null) ((Button)e.NewValue).Click += button_Click;
        }
    }

    public static class KlawiszWyłączBehavior
    {
        public static Key GetKlawisz(DependencyObject d)
        {
            return (Key)d.GetValue(KlawiszProperty);
        }

        public static void SetKlawisz(DependencyObject d, Key value)
        {
            d.SetValue(KlawiszProperty, value);
        }

        public static readonly DependencyProperty KlawiszProperty =
            DependencyProperty.RegisterAttached(
                "Klawisz",
                typeof(Key),
                typeof(KlawiszWyłączBehavior),
                new PropertyMetadata(Key.None, KlawiszZmieniony));

        private static void KlawiszZmieniony(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Key klawisz = (Key)e.NewValue;
            if (d is Window)
            {
                (d as Window).PreviewKeyDown +=
                    (object sender, KeyEventArgs _e) =>
                    {
                        if (_e.Key == klawisz)
                            (sender as Window).Close();
                    };
            }
            else
            {
                (d as UIElement).PreviewKeyDown +=
                    (object sender, KeyEventArgs _e) =>
                    {
                        if (_e.Key == klawisz)
                            (sender as UIElement).IsEnabled = false;
                    };
            }
        }
    }
}
