using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace RowDragDrop
{
    public class DropIndicationAdorner : Adorner
    {
        private readonly UIElement child;
        private double topOffset;

        public DropIndicationAdorner(UIElement owner)
            : base(owner)
        {
        }

        public DropIndicationAdorner(UIElement owner, FrameworkElement adornElement)
            : base(owner)
        {
            if (adornElement != null)
            {
                this.child = adornElement;
            }
        }

        public double TopOffset
        {
            get
            {
                return this.topOffset;
            }
            set
            {
                this.topOffset = value;
                this.UpdatePosition();
            }
        }

        protected override int VisualChildrenCount
        {
            get
            {
                return 1;
            }
        }

        public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
        {
            var result = new GeneralTransformGroup();

            result.Children.Add(base.GetDesiredTransform(transform));
            result.Children.Add(new TranslateTransform(0, this.topOffset));

            return result;
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            this.child.Arrange(new Rect(this.child.DesiredSize));

            return finalSize;
        }

        protected override Visual GetVisualChild(int index)
        {
            return this.child;
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            this.child.Measure(availableSize);

            return this.child.DesiredSize;
        }

        private void UpdatePosition()
        {
            var adorner = (AdornerLayer)this.Parent;
            if (adorner != null)
            {
                adorner.Update(this.AdornedElement);
            }
        }
    }
}