using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Threading;
using Telerik.Windows.Data;

namespace Telerik.Windows.Controls.GridView.Scrolling
{
    public class CustomScrolling
    {
        private GridViewDataControl grid;

        public CustomScrolling(GridViewDataControl grid)
        {
            this.grid = grid;
        }

        public static readonly DependencyProperty IsEnabledProperty
           = DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(CustomScrolling),
                new PropertyMetadata(new PropertyChangedCallback(OnIsEnabledPropertyChanged)));

        public static bool GetIsEnabled(DependencyObject dependencyObject)
        {
            return (bool)dependencyObject.GetValue(IsEnabledProperty);
        }

        public static void SetIsEnabled(DependencyObject dependencyObject, bool enabled)
        {
            dependencyObject.SetValue(IsEnabledProperty, enabled);
        }

        private static void OnIsEnabledPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            RadGridView grid = dependencyObject as RadGridView;
            if (grid != null)
            {
                if ((bool)e.NewValue)
                {
                    grid.SizeChanged += SizeChanged;
                }
            }
        }

        static void SizeChanged(object sender, SizeChangedEventArgs e)
        {
            var grid = (GridViewDataControl)sender;
            var source = ((DomainDataSourceView)grid.ItemsSource);

            var sw = grid.ChildrenOfType<GridViewScrollViewer>().FirstOrDefault();
            if (sw != null)
            {
                sw.IsCustomScrollingEnabled = true;

                var vsb = sw.ChildrenOfType<ScrollBar>().Where(s => s.Orientation == Orientation.Vertical).FirstOrDefault();
                if (vsb != null)
                {
                    ScrollViewer.SetVerticalScrollBarVisibility(grid, ScrollBarVisibility.Visible);

                    vsb.ClearValue(ScrollBar.ViewportSizeProperty);
                    vsb.ClearValue(ScrollBar.ValueProperty);
                    vsb.ClearValue(ScrollBar.MaximumProperty);

                    vsb.Minimum = 0;
                    vsb.SmallChange = 1;
                    vsb.SetBinding(ScrollBar.MaximumProperty, new Binding("PageCount") { Source = source });

                    vsb.Scroll -= Scroll;
                    vsb.Scroll += Scroll;
                }

                var maximumItems = (int)Math.Round(sw.RenderSize.Height / grid.RowHeight);

                if (maximumItems > source.PageSize)
                {
                    source.PageSize = maximumItems;
                }
            }
        }

        static void Scroll(object sender, ScrollEventArgs e)
        {
            var vsb = (ScrollBar)sender;
            var grid = vsb.ParentOfType<GridViewDataControl>();
            var source = ((DomainDataSourceView)grid.ItemsSource);

            var timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(1000) };
            timer.Tick += (s, args) =>
            {
                timer.Stop();

                var pageIndex = (int)Math.Round(vsb.Value);

                if (pageIndex != source.PageIndex)
                {
                    source.MoveToPage(pageIndex);
                }

            };

            timer.Start();
        }
    }
}
