using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using System.Collections;

namespace ChuPiao.Common.Utils
{
    /// <summary>
    /// 集合操作枚举
    /// </summary>
    public enum NotifyCollectionChangedAction
    {
        // 摘要:
        //     向集合中添加了一个或多个项。
        Add = 0,
        //
        // 摘要:
        //     从集合中移除了一个或多个项。
        Remove = 1,
        //
        // 摘要:
        //     在集合中替换了一个或多个项。
        Replace = 2,
        //
        // 摘要:
        //     在集合中移动了一个或多个项。
        Move = 3,
        //
        // 摘要:
        //     集合的内容发生显著更改。
        Reset = 4,
    }

    public delegate void NotifyCollectionChangedEventHandler(object sender, NotifyCollectionChangedEventArgs e);

    /// <summary>
    /// 集合变化的事件参数
    /// </summary>
    public class NotifyCollectionChangedEventArgs : EventArgs
    {
        private NotifyCollectionChangedAction _action;
        public NotifyCollectionChangedAction Action
        {
            get { return _action; }
            set { _action = value; }
        }

        public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object item)
        {
            _action = action;
            _newItems.Insert(0, item);
        }
        public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action)
        {
            _action = action;
        }
        private IList _newItems = new ArrayList();
        /// <summary>
        /// 获取更改中涉及的新项的列表
        /// </summary>
        public IList NewItems
        {
            get
            {
                return _newItems;
            }
        }
    }

    public class ObservableCollection<T> : IList<T>
    {
        public ObservableCollection()
        {
            _list = new List<T>();
        }

        public event NotifyCollectionChangedEventHandler CollectionChanged;
        protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            if (null != CollectionChanged)
            {
                CollectionChanged(this, e);
            }
        }
        private List<T> _list;

        #region IList<T> 成员

        public int IndexOf(T item)
        {
            return _list.IndexOf(item);
        }

        public void Insert(int index, T item)
        {
            _list.Insert(index, item);
            if (null != CollectionChanged)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
            }
        }

        public void RemoveAt(int index)
        {
            object item = _list[index];
            _list.RemoveAt(index);
            if (null != CollectionChanged)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
            }
        }

        public T this[int index]
        {
            get
            {
                return _list[index];
            }
            set
            {
                _list[index] = value;
                if (null != CollectionChanged)
                {
                    CollectionChanged(this,new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace,index));
                }
            }
        }

        #endregion

        #region ICollection<T> 成员

        public void Add(T item)
        {
            _list.Add(item);
            if (null != CollectionChanged)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
            }
        }

        public void AddWithNoEvent(T item)
        {
            _list.Add(item);
        }

        public void Clear()
        {
            _list.Clear();
            if (null != CollectionChanged)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove));
            }
        }

        public void ClearWithNoEvent()
        {
            _list.Clear();
        }

        public bool Contains(T item)
        {
            return _list.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            _list.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return _list.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public bool Remove(T item)
        {
            _list.Remove(item);
            if (null != CollectionChanged)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
            }
            return true;
        }

        public bool RemoveWithNoEvent(T item)
        {
            return _list.Remove(item);
        }

        #endregion

        #region IEnumerable<T> 成员

        public IEnumerator<T> GetEnumerator()
        {
            return _list.GetEnumerator();
        }

        #endregion

        #region IEnumerable 成员

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _list.GetEnumerator();
        }

        #endregion

        #region IList<T> 成员

        int IList<T>.IndexOf(T item)
        {
            return _list.IndexOf(item);
        }

        void IList<T>.Insert(int index, T item)
        {
            _list.Insert(index, item);
            if (null != CollectionChanged)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
            }
        }

        void IList<T>.RemoveAt(int index)
        {
            object item = _list[index];
            _list.RemoveAt(index);
            if (null != CollectionChanged)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
            }
        }

        T IList<T>.this[int index]
        {
            get
            {
                return _list[index];
            }
            set
            {
                _list[index] = value;
                if (null != CollectionChanged)
                {
                    CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, index));
                }
            }
        }

        #endregion

        #region ICollection<T> 成员

        void ICollection<T>.Add(T item)
        {
            _list.Add(item);
            if (null != CollectionChanged)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
            }
        }

        void ICollection<T>.Clear()
        {
            _list.Clear();
            if (null != CollectionChanged)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove));
            }
        }

        bool ICollection<T>.Contains(T item)
        {
            return _list.Contains(item);
        }

        void ICollection<T>.CopyTo(T[] array, int arrayIndex)
        {
            _list.CopyTo(array, arrayIndex);
        }

        int ICollection<T>.Count
        {
            get { return _list.Count; }
        }

        bool ICollection<T>.IsReadOnly
        {
            get { return false; }
        }

        bool ICollection<T>.Remove(T item)
        {
            _list.Remove(item);
            if (null != CollectionChanged)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
            }
            return true;
        }

        #endregion

        #region IEnumerable<T> 成员

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return _list.GetEnumerator();
        }

        #endregion

        public List<T> ToList()
        {
            List<T> list = new List<T>();
            foreach (T t in _list)
            {
                list.Add(t);
            }
            return list;
        }

        public List<T> Sort(Comparison<T> sortmethod)
        {
            _list.Sort(sortmethod);
            return _list;
        }
    }
}
