using System;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows;
using System.Windows.Shapes;
using Size = System.Windows.Size;
using EGC = ExtendedGrid.Microsoft.Windows.Controls;

namespace MECF.Framework.UI.Client.DataGridTransform.DataGrid.Microsoft.Windows.Controls.Primitives
{
    public class DataGridCellDragToFillAdorner : Adorner
    {
        public event EventHandler<DragStartedEventArgs> OnDragStart;
        public event EventHandler<DragCompletedEventArgs> OnDragCompleted;
        public event EventHandler<DragDeltaEventArgs> OnDragDelta;

        private readonly VisualCollection _adornerVisuals;
        private readonly Thumb _thumb2;
        private readonly Rectangle _rec;
        private readonly Rectangle _recShadow;
        private Rect _lastBoundRect;
        private Brush _disabledStroke;

        #region Constructors

        public DataGridCellDragToFillAdorner(UIElement adornedElement, Size originCellSize) : base(adornedElement)
        {
            _lastBoundRect = new Rect(0, 0, originCellSize.Width, originCellSize.Height);
            _adornerVisuals = new VisualCollection(this);
            _disabledStroke = Brushes.DarkGray;

            _rec = new Rectangle()
            {
                StrokeThickness = 2
            };

            _recShadow = new Rectangle()
            {
                StrokeThickness = 2,
                StrokeDashArray = { 1, 1 },
                Opacity = 0.5,
                Visibility = Visibility.Hidden
            };

            _thumb2 = new Thumb();
            _thumb2.DragStarted += Thumb2OnDragStarted;
            _thumb2.DragDelta += Thumb2_DragDelta;
            _thumb2.DragCompleted += Thumb2OnDragCompleted;
            
            _adornerVisuals.Add(_rec);
            _adornerVisuals.Add(_recShadow);
            _adornerVisuals.Add(_thumb2);
        }

        #endregion

        #region Properties

        protected override int VisualChildrenCount => _adornerVisuals.Count;

        internal int StartCellIndex { get; private set; }

        internal int EndCellIndex { get; private set; }

        #endregion

        #region Dps

        public static readonly DependencyProperty ThumbStyleProperty = DependencyProperty.Register(
            nameof(ThumbStyle), typeof(Style), typeof(DataGridCellDragToFillAdorner), 
            new PropertyMetadata(default(Style)));

        public Style ThumbStyle
        {
            get => (Style)GetValue(ThumbStyleProperty);
            set => SetValue(ThumbStyleProperty, value);
        }

        public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register(
            nameof(Stroke), typeof(Brush), typeof(DataGridCellDragToFillAdorner), 
            new PropertyMetadata(default(Brush)));
    
        public Brush Stroke
        {
            get => (Brush)GetValue(StrokeProperty);
            set => SetValue(StrokeProperty, value);
        }

        #endregion

        #region Methods

        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            
            if(e.Property == IsEnabledProperty 
               || e.Property == ThumbStyleProperty 
               || e.Property == StrokeProperty)
                ApplyStyle();
                
        }

        protected override Visual GetVisualChild(int index)
        {
            return _adornerVisuals[index];
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            /*_rec.Arrange(_lastBoundRect);
            _thumb2.Arrange(new Rect(_lastBoundRect.Width - 5, _lastBoundRect.Height + _lastBoundRect.Y - 5, 10, 10));*/
            _rec.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
            //_recShadow.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
            _thumb2.Arrange(
                new Rect(finalSize.Width - _thumb2.Width / 2, 
                    finalSize.Height - _thumb2.Height / 2, 
                    _thumb2.Width, 
                    _thumb2.Height));
      
            return base.ArrangeOverride(finalSize);
        }

        private void ApplyStyle()
        {
            SetThumbStyle();
            SetStroke();
            if (IsEnabled == false)
            {
                _rec.Stroke = _disabledStroke;
                _recShadow.Stroke = _disabledStroke;
                _recShadow.Visibility = Visibility.Hidden;
                _thumb2.Background = _disabledStroke;
            }
        }

        private void SetThumbStyle()
        {
            if (ThumbStyle != null && ThumbStyle.TargetType == typeof(Thumb))
                _thumb2.Style = ThumbStyle;
            else
            {
                // Load default style
                LoadDefaultThumbStyle();
            }
        }

        private void SetStroke()
        {
            _rec.Stroke = Stroke;
            _recShadow.Stroke = Stroke;
        }

        private void LoadDefaultThumbStyle()
        {
            _thumb2.Width = 10;
            _thumb2.Height = 10;
            _thumb2.Background = Stroke;
            _thumb2.BorderThickness = new Thickness(0);
        }
        

        /// <summary>
        /// 绘制选择范围的虚线框。
        /// </summary>
        /// <param name="boundRect"></param>
        /// <param name="startCellIndex"></param>
        /// <param name="endCellIndex"></param>
        internal void ArrangeSelectionBound(Rect boundRect, int startCellIndex, int endCellIndex)
        {
            _lastBoundRect.X = boundRect.X;
            _lastBoundRect.Y = boundRect.Y;
            _lastBoundRect.Width = boundRect.Width;
            _lastBoundRect.Height = boundRect.Height;
            _recShadow.Arrange(_lastBoundRect);
            StartCellIndex = startCellIndex;
            EndCellIndex = endCellIndex;

            //Debug.WriteLine($"Adorner Bound: {_lastBoundRect}", "Adorner");
        }

        /// <summary>
        /// 获取拖动选择的范围。
        /// </summary>
        /// <returns></returns>
        internal Rect GetSelectionBound()
        {
            return _lastBoundRect;
        }

        /// <summary>
        /// 取消填充操作。
        /// </summary>
        internal void Cancel()
        {
            if (_thumb2.IsDragging)
                _thumb2.CancelDrag();
        }

        #endregion

        #region Event Handlers

        private void Thumb2OnDragStarted(object sender, DragStartedEventArgs e)
        {
            _recShadow.Visibility = Visibility.Visible;
            OnDragStart?.Invoke(this, e);
        }

        private void Thumb2OnDragCompleted(object sender, DragCompletedEventArgs e)
        {
            _recShadow.Visibility = Visibility.Hidden;

            if (!e.Canceled)
            {
                _rec.Arrange(_lastBoundRect);
                _recShadow.Arrange(_lastBoundRect);
                _thumb2.Arrange(
                    new Rect(_lastBoundRect.Width - _thumb2.Width / 2, 
                        _lastBoundRect.Height + _lastBoundRect.Y - _thumb2.Height / 2,
                        _thumb2.Width, 
                        _thumb2.Height));

                OnDragCompleted?.Invoke(this, e);
            }
        }

        private void Thumb2_DragDelta(object sender, DragDeltaEventArgs e)
        {
            OnDragDelta?.Invoke(this, e);
        }

        #endregion
    }
}
