using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PXP.Crawler.API.Utils
{
    [Serializable]
    public class ListEx<T> : List<T>
    {
        #region Declarations

        public class ListExItemEventArgs<T> : EventArgs
        {
            private T item;

            public ListExItemEventArgs(T item)
            {
                this.item = item;
            }

            public T Item
            {
                get { return item; }
            }
        }

        public delegate void ListExItemEventHandler(object sender, ListExItemEventArgs<T> e);

        #endregion

        #region Variables

        internal object tag = null;

        #endregion

        #region Events

        public event EventHandler Changed;

        internal void OnChanged()
        {
            if (Changed != null)
                Changed(this, EventArgs.Empty);
        }

        public event ListExItemEventHandler Added;

        internal void OnAdded(T item)
        {
            if (Added != null)
                Added(this, new ListExItemEventArgs<T>(item));
        }

        public event ListExItemEventHandler Removed;

        internal void OnRemoved(T item)
        {
            if (Removed != null)
                Removed(this, new ListExItemEventArgs<T>(item));
        }

        #endregion

        #region Collection

        public new void Add(T item)
        {
            base.Add(item);
            OnAdded(item);
            OnChanged();
        }

        public new void Insert(int index, T item)
        {
            base.Insert(index, item);
            OnAdded(item);
            OnChanged();
        }

        public new void Remove(T item)
        {
            base.Remove(item);
            OnRemoved(item);
            OnChanged();
        }

        public new void RemoveAt(int index)
        {
            T item = base[index];
            base.RemoveAt(index);
            OnRemoved(item);
            OnChanged();
        }

        public new void Clear()
        {
            T[] items = base.ToArray();
            base.Clear();
            foreach (T item in items)
            {
                OnRemoved(item);
            }
            OnChanged();
        }

        #endregion

        #region Properties

        public object Tag
        {
            get { return tag; }
            set { tag = value; }
        }

        #endregion

    }
}
