using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using HandyControl.Data;

namespace HandyControl.Controls
{
    public class SelectableItem : ContentControl, ISelectable
    {
        private bool _isMouseLeftButtonDown;

        protected override void OnMouseLeave(MouseEventArgs e)
        {
            base.OnMouseLeave(e);

            _isMouseLeftButtonDown = false;
        }

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);

            _isMouseLeftButtonDown = true;
        }

        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonUp(e);

            if (_isMouseLeftButtonDown)
            {
                if (SelfManage)
                {
                    if (!IsSelected)
                    {
                        IsSelected = true;
                        OnSelected(new RoutedEventArgs(SelectedEvent, this));
                    }
                    else if (CanDeselect)
                    {
                        IsSelected = false;
                        OnSelected(new RoutedEventArgs(DeselectedEvent, this));
                    }
                }
                else
                {
                    if (CanDeselect)
                    {
                        OnSelected(IsSelected
                            ? new RoutedEventArgs(DeselectedEvent, this)
                            : new RoutedEventArgs(SelectedEvent, this));
                    }
                    else
                    {
                        OnSelected(new RoutedEventArgs(SelectedEvent, this));
                    }
                }
                _isMouseLeftButtonDown = false;
            }
        }

        protected virtual void OnSelected(RoutedEventArgs e) => RaiseEvent(e);

        public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register(
            "IsSelected", typeof(bool), typeof(SelectableItem), new PropertyMetadata(ValueBoxes.FalseBox));

        public bool IsSelected
        {
            get => (bool) GetValue(IsSelectedProperty);
            set => SetValue(IsSelectedProperty, ValueBoxes.BooleanBox(value));
        }

        public static readonly DependencyProperty SelfManageProperty = DependencyProperty.Register(
            "SelfManage", typeof(bool), typeof(SelectableItem), new PropertyMetadata(ValueBoxes.FalseBox));

        public bool SelfManage
        {
            get => (bool) GetValue(SelfManageProperty);
            set => SetValue(SelfManageProperty, ValueBoxes.BooleanBox(value));
        }

        public static readonly DependencyProperty CanDeselectProperty = DependencyProperty.Register(
            "CanDeselect", typeof(bool), typeof(SelectableItem), new PropertyMetadata(ValueBoxes.FalseBox));

        public bool CanDeselect
        {
            get => (bool) GetValue(CanDeselectProperty);
            set => SetValue(CanDeselectProperty, ValueBoxes.BooleanBox(value));
        }

        public static readonly RoutedEvent SelectedEvent =
            EventManager.RegisterRoutedEvent("Selected", RoutingStrategy.Bubble,
                typeof(RoutedEventHandler), typeof(SelectableItem));

        public event RoutedEventHandler Selected
        {
            add => AddHandler(SelectedEvent, value);
            remove => RemoveHandler(SelectedEvent, value);
        }

        public static readonly RoutedEvent DeselectedEvent =
            EventManager.RegisterRoutedEvent("Deselected", RoutingStrategy.Bubble,
                typeof(RoutedEventHandler), typeof(SelectableItem));

        public event RoutedEventHandler Deselected
        {
            add => AddHandler(DeselectedEvent, value);
            remove => RemoveHandler(DeselectedEvent, value);
        }
    }
}
