using System;
using System.Reflection;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using System.Collections.ObjectModel;
using C1.Xaml.FlexGrid;
using C1.Xaml;
using System.Collections;

namespace FlexGridSamples
{
    public sealed partial class CollectionView : Page
    {
        C1CollectionView _c1CollectionView;

        public CollectionView()
        {
            this.InitializeComponent();

            IList<string> fieldNames = new string[] { "Line", "Color", "Price", "Weight", "Cost", "Volume", "Discontinued", "Rating" };
            List<string> groupFields = new List<string>(fieldNames);
            groupFields.Sort();
            List<string> filterFields = new List<string>(groupFields);
            //groupFields.Insert(0, "(None)");
            //groupComboBox.ItemsSource = properties;
            //groupComboBox.SelectedIndex = 1;
            filterComboBox.ItemsSource = filterFields;
            filterComboBox.SelectedIndex = 0;

            //you can use a custome C1CollectionViewConverter to define sort/group in xaml page
            //or define C1CollectionViewer as following.
            //_c1CollectionView = new C1CollectionView();
            //_c1CollectionView.SourceCollection = Product.GetProducts(100);
            //_c1CollectionView.GroupDescriptions.Add(new C1.Xaml.PropertyGroupDescription("Color"));

            c1FlexGrid1.DataContext = new ViewModel();
            c1FlexGrid1.Loaded += C1FlexGrid1_Loaded;
        }

        private void C1FlexGrid1_Loaded(object sender, RoutedEventArgs e)
        {
            _c1CollectionView = c1FlexGrid1.CollectionView as C1CollectionView;
        }

        //void UpdateGrouping()
        //{
        //    if (_c1CollectionView != null)
        //    {
        //        using (_c1CollectionView.DeferRefresh())
        //        {
        //            _c1CollectionView.GroupDescriptions.Clear();
        //            if (groupComboBox.SelectedIndex > 0)
        //            {
        //                _c1CollectionView.GroupDescriptions.Add(new PropertyGroupDescription((string)groupComboBox.SelectedItem));
        //            }
        //        }
        //    }
        //}

        void UpdateFiltering()
        {
            if (filterTextBox.Text.Length == 0)
            {
                _c1CollectionView.Filter = null;
            }
            else
            {
                if (_c1CollectionView.Filter == null)
                {
                    _c1CollectionView.Filter = FilterFunction;
                }
                else
                {
                    _c1CollectionView.Refresh();
                }
            }
        }

        bool FilterFunction(object product)
        {
            // get customer to test
            Product c = product as Product;
            if (c == null)
            {
                return false;
            }

            // get value of the property we're filtering on
            var pi = typeof(Product).GetRuntimeProperty(filterComboBox.SelectedItem.ToString());
            object propValue = pi.GetValue(c, null);
            if (propValue == null)
            {
                return false;
            }

            // check if the property contains the filter string
            var text = propValue.ToString();
            return text.IndexOf(filterTextBox.Text, StringComparison.CurrentCultureIgnoreCase) > -1;
        }

        void groupComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //UpdateGrouping();
        }
        void filterTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            UpdateFiltering();
        }
        void filterComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            filterTextBox.Text = string.Empty;
        }

        private void groupCheckbox_Checked(object sender, RoutedEventArgs e)
        {
            //if (string.IsNullOrWhiteSpace(_txtGroups.Text))
            //{
            //    _txtGroups.Text = (sender as CheckBox).Content.ToString();
            //}
            //else
            //{
            //    _txtGroups.Text += "," + (sender as CheckBox).Content.ToString();
            //}

            if (_c1CollectionView != null)
            {
                using (_c1CollectionView.DeferRefresh())
                {
                    var group = _c1CollectionView.GroupDescriptions.FirstOrDefault(p => (p as PropertyGroupDescription).PropertyName == (sender as CheckBox).Content.ToString());
                    if (group == null)
                    {
                        _c1CollectionView.GroupDescriptions.Add(new PropertyGroupDescription((sender as CheckBox).Content.ToString()));
                    }
                }
            }
        }

        private void groupCheckbox_Unchecked(object sender, RoutedEventArgs e)
        {
            //var s = _txtGroups.Text.Split(',').ToList();
            //s.Remove((sender as CheckBox).Content.ToString());

            //_txtGroups.Text = "";
            //for (int i = 0; i < s.Count; i++)
            //{
            //    _txtGroups.Text += s[i];
            //    if (s[i] != s.Last())
            //    {
            //        _txtGroups.Text += ",";
            //    }
            //}

            if (_c1CollectionView != null)
            {
                using (_c1CollectionView.DeferRefresh())
                {
                    _c1CollectionView.GroupDescriptions.Remove(_c1CollectionView.GroupDescriptions.FirstOrDefault(p => (p as PropertyGroupDescription).PropertyName == (sender as CheckBox).Content.ToString()));

                }
            }
        }
    }

    public class C1CollectionViewConverter : IValueConverter
    {

        private ObservableCollection<SortDescription> sortDescriptions = new ObservableCollection<SortDescription>();

        public ObservableCollection<SortDescription> SortDescriptions
        {
            get { return sortDescriptions; }
            set { sortDescriptions = value; }
        }


        private ObservableCollection<PropertyGroupDescription> groupDescriptions = new ObservableCollection<PropertyGroupDescription>();

        public ObservableCollection<PropertyGroupDescription> GroupDescriptions
        {
            get { return groupDescriptions; }
            set { groupDescriptions = value; }
        }
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            if (value != null && value is IEnumerable)
            {
                var collectionView = new C1CollectionView();

                collectionView.SourceCollection = (System.Collections.IEnumerable)value;
                foreach (var group in this.GroupDescriptions)
                {
                    collectionView.GroupDescriptions.Add(group);
                }
                foreach (var sort in this.SortDescriptions)
                {
                    collectionView.SortDescriptions.Add(sort);
                }

                return collectionView;
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }

    public class ViewModel
    {
        public ICollectionView Products { get; set; }

        public ViewModel()
        {
            Products = Product.GetProducts(100);
        }
    }

}
