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

namespace Quadarax.Foundation.Core.Collections
{

    public class LockedList<TElement> : IList<TElement>
    {

        #region *** Private Fields ***
        private readonly List<TElement> _list;
        #endregion

        #region *** Public Properties ***

        public int Count
        {
            get
            {
                lock (_list)
                {
                    return _list.Count;
                }
            }
        }

        public bool IsReadOnly
        {
            get
            {
                lock (_list)
                {
                    return ((IList<TElement>)_list).IsReadOnly;
                }
            }
        }

        #endregion

        #region *** Indexers ***
        public TElement this[int index]
        {
            get
            {
                lock (_list)
                {
                    return _list[index];
                }
            }
            set
            {
                lock (_list)
                {
                    _list[index] = value;
                }
            }
        }
        #endregion

        #region *** Constructors ***
        public LockedList()
        {
            _list = new List<TElement>();
        }
        public LockedList(IEnumerable<TElement> initialItems)
        {
            _list = new List<TElement>(initialItems);
        }
        public LockedList(int capacity)
        {
            _list = new List<TElement>(capacity);
        }
        #endregion

        #region *** Public Methods ***
        public IEnumerator<TElement> GetEnumerator()
        {
            lock (_list)
            {
                return _list.GetEnumerator();
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public void Add(TElement item)
        {
            lock (_list)
            {
                _list.Add(item);
            }
        }

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

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

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

        public bool Remove(TElement item)
        {
            lock (_list)
            {
                return _list.Remove(item);
            }
        }

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

        public void Insert(int index, TElement item)
        {
            lock (_list)
            {
                _list.Insert(index, item);
            }
        }

        public void RemoveAt(int index)
        {
            lock (_list)
            {
                _list.RemoveAt(index);
            }
        }

        #endregion
    }
}
