using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.DragDrop;
#if SILVERLIGHT
using EventManager = Telerik.Windows.EventManager;
#endif

namespace TreeView.AutoScroll
{
	public class AutoScrollBehavior : Behavior<RadTreeView>
	{
		protected override void OnAttached()
		{
			base.OnAttached();

			EventManager.RegisterClassHandler(typeof(ScrollViewer), RadDragAndDropManager.DropQueryEvent, new EventHandler<DragDropQueryEventArgs>(OnTreeViewScrollViewerDropQuery), true);
		}

		private static void OnTreeViewScrollViewerDropQuery(object sender, DragDropQueryEventArgs e)
		{
			var scrollViewer = sender as ScrollViewer;

			if (scrollViewer != null)
			{

				var currentDragPoint = e.Options.CurrentDragPoint;
#if SILVERLIGHT
				var generalTransform = scrollViewer.TransformToVisual(Application.Current.RootVisual);
#else
				var generalTransform = scrollViewer.TransformToVisual(Window.GetWindow(scrollViewer));
#endif
				var topLeft = generalTransform.Transform(new Point(0, 0));
				var relative = new Point(currentDragPoint.X - topLeft.X, currentDragPoint.Y - topLeft.Y);

				if (relative.Y > 0 && relative.Y < 40)
				{
					scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - (20 * ((40 - relative.Y) / 40)));
				}

				if (relative.Y > scrollViewer.ActualHeight - 40 && relative.Y < scrollViewer.ActualHeight)
				{
					scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + (20 * ((40 - (scrollViewer.ActualHeight - relative.Y)) / 40)));
				}

				if (relative.X > 0 && relative.X < 40)
				{
					scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset - (20 * ((40 - relative.X) / 40)));
				}

				if (relative.X > scrollViewer.ActualWidth - 40 && relative.X < scrollViewer.ActualWidth)
				{
					scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + (20 * ((40 - (scrollViewer.ActualWidth - relative.X)) / 40)));
				}
			}
		}
	}
}
