using C1.Xaml;
using C1.Xaml.FlexGrid;
using System;
using System.Linq;
using System.Collections.Generic;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;



namespace ControlExplorer.Controls.FlexGrid
{
    public partial class SortingFiltering
        : UserControl, IExposeApplicationBarItems
    {
        AppBarButton btnFilter = new AppBarButton { Icon = new BitmapIcon { UriSource = new Uri("ms-appx:///Resources/AppBar/filter.png") } };
        AppBarButton btnFilterClear = new AppBarButton { Icon = new BitmapIcon { UriSource = new Uri("ms-appx:///Resources/AppBar/filter_clear.png") } };
        AppBarButton btnSortClear = new AppBarButton { Icon = new BitmapIcon { UriSource = new Uri("ms-appx:///Resources/AppBar/sort_clear.png") } };
        AppBarButton btnToggleMultipleSort = new AppBarButton();
        List<ColumnFilter> _filters;

        public SortingFiltering()
        {
            InitializeComponent();

            btnFilter.Label = "filter";
            btnFilter.Click += btnFilter_Click;

            btnFilterClear.Label = "clear filter";
            btnFilterClear.Click += btnFilterClear_Click;

            btnSortClear.Label = "clear sort";
            btnSortClear.Click += btnSort_Click;

            btnToggleMultipleSort.Label = "enable multiple sort";
            btnToggleMultipleSort.Click += btnToggleMultipleSort_Click;
            flexgrid.AllowSorting = false; // we'll do it ourselves

            flexgrid.ItemsSource = Person.Generate(100);
            flexgrid.Tapped += flexgrid_Tapped;

            _filters = new List<ColumnFilter>();
            foreach (Column col in flexgrid.Columns)
            {
                if (col.DataType == typeof(string))
                {
                    _filters.Add(new ColumnFilter() { Column = col, Value = string.Empty });
                }
            }

            UpdateButtons();

            Loaded += SortingFiltering_Loaded;
        }

        void SortingFiltering_Loaded(object sender, RoutedEventArgs e)
        {
            flexgrid.AutoSizeColumns(0, flexgrid.Columns.Count, 30);
        }

        private void UpdateButtons()
        {
            var collView = flexgrid.CollectionView as C1CollectionView;
            btnSortClear.IsEnabled = (collView.SortDescriptions.Count > 0);
            btnFilterClear.IsEnabled = (collView.Filter != null);
        }

        #region Sort

        bool _allowMultipleSort = false;
        void btnToggleMultipleSort_Click(object sender, RoutedEventArgs e)
        {
            _allowMultipleSort = !_allowMultipleSort;

            if (_allowMultipleSort)
            {
                btnToggleMultipleSort.Label = "disable multiple sort";
            }
            else
            {
                btnToggleMultipleSort.Label = "enable multiple sort";
            }
        }

        void flexgrid_Tapped(object sender, TappedRoutedEventArgs e)
        {
            // detect tap and sort only if a column header was tapped
            var testInfo = flexgrid.HitTest(e);
            if (testInfo.CellType == CellType.ColumnHeader)
            {
                // get current column header property name
                SortGrid(flexgrid.Columns[testInfo.Column].BoundPropertyName);
            }
        }

        void btnSort_Click(object sender, RoutedEventArgs e)
        {
            var collView = flexgrid.CollectionView as C1CollectionView;
            collView.SortDescriptions.Clear();
            UpdateButtons();
        }

        void SortGrid(string propertyName)
        {
            var collView = flexgrid.CollectionView as C1CollectionView;
            // If we have a sort description with the current property path, then we remove it from the collection and
            // add a new one with the opposite sort direction (if we tap a column header twice, the sort direction changes).
            // If we don´t have a sort description with the current property path, then we add it with ascending sort direction.
            var sortDescriptions = collView.SortDescriptions;

            using (collView.DeferRefresh())
            {
                var sortDescription = sortDescriptions.FirstOrDefault(sd => sd.PropertyName.Equals(propertyName));

                // if multiple selection is disabled, we always clear the collection
                if (!_allowMultipleSort)
                {
                    sortDescriptions.Clear();
                }

                if (sortDescription == null)
                {
                    sortDescription = new SortDescription(propertyName, ListSortDirection.Ascending);
                    sortDescriptions.Add(sortDescription);
                }
                else
                {
                    sortDescriptions.Remove(sortDescription);
                    sortDescriptions.Add(new SortDescription(propertyName, sortDescription.Direction == ListSortDirection.Ascending ? ListSortDirection.Descending : ListSortDirection.Ascending));
                }
            }

            UpdateButtons();
        }

        #endregion

        #region Filter

        void btnFilterClear_Click(object sender, RoutedEventArgs e)
        {
            foreach (var filter in _filters)
            {
                filter.Value = "";
            }
            var collView = flexgrid.CollectionView as C1CollectionView;
            collView.Filter = null;
            UpdateButtons();
        }

        private async void btnFilter_Click(object sender, RoutedEventArgs e)
        {
            var flyout = new PickerFlyout();
            flyout.ConfirmationButtonsVisible = true;
            var filter = new FlexGridFilter(_filters);
            flyout.Content = filter;
            var page = C1.Xaml.Extensions.FindParent<Page>(this);
            if (page != null)
            {
                var ok = await flyout.ShowAtAsync(sender as FrameworkElement);
                var collView = flexgrid.CollectionView as C1CollectionView;
                if (ok)
                {
                    if (_filters.Where(f => !string.IsNullOrEmpty(f.Value.Trim())).Count() > 0)
                    {
                        collView.Filter = null;
                        collView.Filter = (item) =>
                        {
                            foreach (var colFilter in _filters)
                            {
                                string filterValue = colFilter.Value.Trim().ToUpper();
                                if ((colFilter.Column.PropertyInfo != null) && !string.IsNullOrEmpty(filterValue))
                                {
                                    string value = colFilter.Column.PropertyInfo.GetValue(item, null) as string;
                                    // use String.Contains method for filter sample
                                    if (value == null || !value.ToUpper().Contains(filterValue))
                                    {
                                        return false;
                                    }
                                }
                            }
                            return true;
                        };
                    }
                    else
                    {
                        collView.Filter = null;
                    }
                    UpdateButtons();
                }
            }
        }

        #endregion

        public IEnumerable<ICommandBarElement> ApplicationBarItems
        {
            get
            {
                yield return btnSortClear;

                yield return btnFilter;
                yield return btnFilterClear;

                yield return btnToggleMultipleSort;
            }
        }
    }
}
