using System.Collections.Generic;
using System.Collections.Specialized;

namespace Sicentury.Core.Collections
{
    public class ObservableQueue<T> : Queue<T>, INotifyCollectionChanged
    {
        public event NotifyCollectionChangedEventHandler CollectionChanged;

        private readonly object _syncRoot = new object();

        #region Constructors

        public ObservableQueue()
        {
            LimitSize = 0;
        }

        public ObservableQueue(int capacity) : base(capacity)
        {
            LimitSize = capacity;
        }


        #endregion

        #region Properties

        public int LimitSize { get; }

        public new virtual void Enqueue(T obj)
        {
            lock (_syncRoot)
            {
                base.Enqueue(obj);

                if (LimitSize > 0 && base.Count > LimitSize)
                    base.Dequeue();

                CollectionChanged?.Invoke(this,
                    new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, obj));
            }
        }

        public new virtual T Dequeue()
        {
            lock (_syncRoot)
            {
                var obj = base.Dequeue();
                CollectionChanged?.Invoke(this,
                    new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, obj));
                return obj;
            }
        }


        public new virtual void Clear()
        {
            lock (_syncRoot)
            {
                base.Clear();
                CollectionChanged?.Invoke(this,
                    new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));

            }
        }

        #endregion
    }
}
