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

namespace Cryville.Crtr {
	public class CastedList<T> : IList<T>, IList, IReadOnlyList<T> {
		readonly IList _list;
		public CastedList(IList list) {
			_list = list;
		}

		public T this[int index] {
			get { return (T)_list[index]; }
			set { _list[index] = value; }
		}

		object IList.this[int index] {
			get { return _list[index]; }
			set { _list[index] = value; }
		}

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

		public bool IsReadOnly { get { return _list.IsReadOnly; } }

		public bool IsFixedSize { get { return _list.IsFixedSize; } }

		public bool IsSynchronized { get { return _list.IsSynchronized; } }

		public object SyncRoot { get { return _list.SyncRoot; } }

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

		public int Add(object value) { return _list.Add(value); }

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

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

		public bool Contains(object value) { return _list.Contains(value); }

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

		public void CopyTo(Array array, int index) { _list.CopyTo(array, index); }

		public IEnumerator<T> GetEnumerator() { return new Enumerator(this); }
		class Enumerator : IEnumerator<T> {
			readonly CastedList<T> _list;
			int _index;

			public T Current { get; private set; }

			object IEnumerator.Current { get { return Current; } }

			public Enumerator(CastedList<T> list) {
				_list = list;
			}

			public void Dispose() { }

			public bool MoveNext() {
				if (_index >= _list.Count) return false;
				Current = _list[_index];
				_index++;
				return true;
			}

			public void Reset() { _index = 0; }
		}

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

		public int IndexOf(object value) { return _list.IndexOf(value); }

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

		public void Insert(int index, object value) { _list.Insert(index, value); }

		public bool Remove(T item) {
			if (!_list.Contains(item)) return false;
			_list.Remove(item);
			return true;
		}

		public void Remove(object value) { _list.Remove(value); }

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

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