using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using C1.Silverlight.DataGrid;

namespace C1DataGrid_Demo2010
{
    public partial class UltraPerformance : System.Windows.Controls.UserControl
    {
        public UltraPerformance()
        {
            InitializeComponent();

            // initialize viewport size combo
            cmbViewPortSize.Items.Add("Small Viewport");
            cmbViewPortSize.Items.Add("Full Viewport");
            cmbViewPortSize.SelectionChanged += new System.Windows.Controls.SelectionChangedEventHandler(cmbViewPortSize_SelectionChanged);
            cmbViewPortSize.SelectedIndex = 1;
        }

        const int columns = 1000;
        const int rows = 100000;
        BackgroundWorker worker = new BackgroundWorker();           

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            info.Visibility = Visibility.Visible;
            grid.Opacity = 100;
            btn.Visibility = Visibility.Collapsed;

            for (int i = 0; i < columns; i++)
            {                
                grid.Columns.Add(new DataGridNumericColumn()
                {                    
                    Header = new System.Windows.Controls.TextBlock()
                    {
                        Text = "Column" + (i + 1).ToString(),
                        TextAlignment = TextAlignment.Right,
                        VerticalAlignment = VerticalAlignment.Center,
                        Margin = new Thickness(0, 0, 5, 0),
                    },
                    Binding = new System.Windows.Data.Binding() 
                    { 
                        Path = new PropertyPath("[" + i + "]"),
                        Mode =System.Windows.Data.BindingMode.OneTime,                        
                    },
                    CanUserSort = false,
                    CanUserFilter = false,
                });
            }

            progress.Minimum = 0;
            progress.Maximum = rows;

            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.WorkerReportsProgress = true;
            worker.RunWorkerAsync();
        }

        #region Background worker

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            Random rnd = new Random();

            var list = new List<short[]>(rows);
            try
            {
                for (int i = 0; i < rows; i++)
                {
                    worker.ReportProgress(0, i);
                    var values = new short[columns];

                    for (int j = 0; j < columns; j++)
                    {
                        values[j] = (short)rnd.Next(short.MaxValue);
                    }

                    list.Add(values);
                }
            }
            catch (OutOfMemoryException)
            {
                list.Clear();
                // system has no enough memory to create the data source 
            }
            e.Result = list;
        }

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var items = (IList)e.Result;
            if (items.Count == 0)
            {
                MessageBox.Show("Sorry, we ran out of memory. This performance test creates a huge data set in the client computer, to then bind it to the C1DataGrid.\n\nYou can try with a smaller quantity of items if you download the sample and run it locally.");
            }

            grid.ItemsSource = items;
            info.Visibility = Visibility.Collapsed;
            grid.Visibility = Visibility.Visible;
        }

        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progress.Value = (int)e.UserState;
            txt.Text = string.Format("{0} / {1} rows", 
                        ((int)e.UserState).ToString("n0", CultureInfo.CurrentCulture),
                        rows.ToString("n0", CultureInfo.CurrentCulture));
        }

        #endregion


        void cmbViewPortSize_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            if (cmbViewPortSize.SelectedItem.ToString() == "Small Viewport")
            {
                grid.Width = 500;
                grid.Height = 300;
            }
            else 
            {
                grid.Width = double.NaN;
                grid.Height = double.NaN;
            }

            ResetRecyclingState();

        }

        private void ResetRecyclingState()
        {
            /*
             *  The C1DataGrid is not removing the recycling elements in size changes
             *  This might impact the performance in the small scenario, as more elements
             *  are being kept in the panels for future usage.
             */

            // save default template
            var tmp = grid.Template;

            grid.Template = new System.Windows.Controls.ControlTemplate();
            grid.ApplyTemplate();

            grid.Template = tmp;
            grid.ApplyTemplate();
        }
    }

}
