using System;
using System.Collections.ObjectModel;
using System.ServiceModel;
using System.Windows;
using System.Windows.Input;
using C1.Silverlight;
using C1.Silverlight.DataGrid;
using C1DataGrid_Demo2010.DataService;

namespace C1DataGrid_Demo2010
{
    public partial class StealthPaging 
        : System.Windows.Controls.UserControl
    {
        int _startRow = 0;
        int _pageSize = 20;
        ObservableCollection<C1DataGrid_Demo2010.DataService.Person> _people = new ObservableCollection<C1DataGrid_Demo2010.DataService.Person>();
        bool _loading;

        public StealthPaging()
        {
            InitializeComponent();

            peopleDataGrid.LoadedRowHeaderPresenter += new EventHandler<DataGridRowEventArgs>(peopleDataGrid_LoadedRowHeaderPresenter);
            peopleDataGrid.LoadedRowPresenter += new EventHandler<DataGridRowEventArgs>(peopleDataGrid_LoadedRowPresenter);

            DataContext = _people;
            GetData(_startRow, _pageSize);
        }

        // extra feature: set row header number
        void peopleDataGrid_LoadedRowHeaderPresenter(object sender, DataGridRowEventArgs e)
        {
            e.Row.HeaderPresenter.Content = new System.Windows.Controls.TextBlock() 
            { 
                Text = (e.Row.Index + 1).ToString(),
                VerticalAlignment = System.Windows.VerticalAlignment.Center,
                HorizontalAlignment = System.Windows.HorizontalAlignment.Center
            };
        }


        // *** Here is where the magic happens *** 
        // It request more data automatically if we are close to the end
        void peopleDataGrid_LoadedRowPresenter(object sender, DataGridRowEventArgs e)
        {
            if (_loading || _people.Count < _pageSize)
            {
                return;
            }
            if (_people.Count - 5 < e.Row.Index)
            {
                GetData(_startRow, _startRow + _pageSize);
            }
        }

        #region retrieve data from the server

        private void GetData(int startRow, int endRow)
        {
            UpdateState(true, startRow, endRow);

            // call web service
            var proxy = new DataWebServiceSoapClient(new BasicHttpBinding(), new EndpointAddress(Extensions.GetAbsoluteUri("DataWebService.asmx")));
            proxy.GetDataCompleted += new EventHandler<GetDataCompletedEventArgs>(proxy_GetDataCompleted);
            proxy.GetDataAsync(startRow, endRow);
        }

        void proxy_GetDataCompleted(object sender, GetDataCompletedEventArgs e)
        {
            if (null != e.Error)
            {
                MessageBox.Show(e.Error.Message, "Error Getting Data", MessageBoxButton.OK);
                return;
            }

            // data retrieved OK, add to observable collection
            _startRow += _pageSize;
            foreach (C1DataGrid_Demo2010.DataService.Person person in e.Result)
            {
                _people.Add(person);
            }

            UpdateState(false, 0, 0);
        }


        // Sets loading status
        // We could usa a VisualState here too
        private void UpdateState(bool loading, int startRow, int endRow)
        {
            if (loading)
            {
                txtStatus.Text = string.Format("Retrieving rows {0} to {1}...", startRow, endRow);
                Cursor = Cursors.Wait;
                _loading = true;
            }
            else
            {
                _loading = false;
                txtStatus.Text = "Ready";
                Cursor = Cursors.Arrow;
            }
        }


        #endregion


    }
}
