using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Interactivity;
using Telerik.Windows.Controls;
using System.Collections.ObjectModel;
using Telerik.Windows.Data;
using System.Collections.Specialized;

namespace Sample
{
    public class GlobalGroupingBehavior : Behavior<RadGridView>
    {
        private static ObservableCollection<GroupDescriptor> GlobalGroupDescriptors;
        private static RadObservableCollection<SortDescriptor> GlobalSortDescriptors;
        private static object SortChangedSender;

        static GlobalGroupingBehavior()
        {
            GlobalGroupDescriptors = new ObservableCollection<GroupDescriptor>();
            GlobalSortDescriptors = new RadObservableCollection<SortDescriptor>();
        }

        protected override void OnAttached()
        {
            base.OnAttached();

            this.AssociatedObject.GroupDescriptors.CollectionChanged += this.GroupDescriptors_CollectionChanged;
            GlobalGroupDescriptors.CollectionChanged += this.GlobalGroupDescriptors_CollectionChanged;

            this.AssociatedObject.Sorted += this.AssociatedObject_Sorted;
            GlobalSortDescriptors.CollectionChanged += this.GlobalSortDescriptors_CollectionChanged;
        }

        protected override void OnDetaching()
        {
            this.AssociatedObject.GroupDescriptors.CollectionChanged -= this.GroupDescriptors_CollectionChanged;
            GlobalGroupDescriptors.CollectionChanged -= this.GlobalGroupDescriptors_CollectionChanged;

            this.AssociatedObject.Sorted -= this.AssociatedObject_Sorted;
            GlobalSortDescriptors.CollectionChanged -= this.GlobalSortDescriptors_CollectionChanged;

            base.OnDetaching();
        }

        private void GlobalGroupDescriptors_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    if (!this.AssociatedObject.GroupDescriptors.Contains(e.NewItems[0]))
                    {
                        this.AssociatedObject.GroupDescriptors.Add(e.NewItems[0] as GroupDescriptor);
                    }
                    break;
                case NotifyCollectionChangedAction.Remove:
                    if (this.AssociatedObject.GroupDescriptors.Contains(e.OldItems[0]))
                    {
                        this.AssociatedObject.GroupDescriptors.Remove(e.OldItems[0] as GroupDescriptor);
                    }
                    break;
            }
        }

        private void GroupDescriptors_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    if (!GlobalGroupDescriptors.Contains(e.NewItems[0]))
                    {
                        GlobalGroupDescriptors.Add(e.NewItems[0] as GroupDescriptor);
                    }
                    break;
                case NotifyCollectionChangedAction.Remove:
                    if (GlobalGroupDescriptors.Contains(e.OldItems[0]))
                    {
                        GlobalGroupDescriptors.Remove(e.OldItems[0] as GroupDescriptor);
                    }
                    break;
            }
        }

        private void AssociatedObject_Sorted(object sender, GridViewSortedEventArgs e)
        {
            SortChangedSender = this.AssociatedObject;

            GlobalSortDescriptors.Clear();
            GlobalSortDescriptors.AddRange(this.AssociatedObject.SortDescriptors);
        }

        private void GlobalSortDescriptors_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (this.AssociatedObject != SortChangedSender)
            {
                this.AssociatedObject.SortDescriptors.Clear();
                this.AssociatedObject.SortDescriptors.AddRange(GlobalSortDescriptors);
            }
        }
    }
}
