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

namespace System.Collections.Generic
{
	public class SimpleListNode<T>
	{
		public T Value { get; set; }
		public SimpleListNode<T> Next { get; set; }

		public SimpleListNode(T value)
		{
			Value = value;
			Next = null;
		}
		public SimpleListNode(T value, SimpleListNode<T> next)
		{
			Value = value;
			Next = next;
		}
	}

	public class SimpleList<T> : IEnumerable<T>
	{
		public class SimpleListIenumerator : IEnumerator<T>
		{
			private SimpleListNode<T> first = null;
			private SimpleListNode<T> curr = null;
			private bool started = false;

			public SimpleListIenumerator(SimpleListNode<T> first)
			{
				this.first = first;
			}

			#region IEnumerator<T> Members
			
			public T Current
			{
				get { return curr.Value; }
			}

			#endregion

			#region IDisposable Members

			public void Dispose()
			{
			}

			#endregion

			#region IEnumerator Members

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

			public bool MoveNext()
			{
				if (!started) { curr = first; started = true; }
				else if (curr != null) curr = curr.Next;

				return curr != null;
			}

			public void Reset()
			{
				curr = null;
				started = false;
			}

			#endregion
		}

		public SimpleListNode<T> First { get; private set; }
		public SimpleListNode<T> Last { get; private set; }

		public SimpleList()
		{
			First = Last = null;
		}

		public void AddFirst(T value) 
		{
			SimpleListNode<T> node = new SimpleListNode<T>(value, this.First);
			this.First = node;
			if (this.Last == null)
				this.Last = node;
		}
		public void AddLast(T value)
		{
			SimpleListNode<T> node = new SimpleListNode<T>(value, null);
			if (this.Last != null)
			{
				this.Last.Next = node;
				this.Last = node;
			}
			else
			{
				this.First = this.Last = node;
			}
		}
		public void ChainWith(SimpleList<T> other) 
		{
			if (this.Last == null)
			{
				this.First = other.First;
			}
			else
			{
				this.Last.Next = other.First;
			}
			this.Last = other.Last;
		}
		public bool IsEmpty()
		{
			return First == null;
		}


		#region IEnumerable<T> Members

		public IEnumerator<T> GetEnumerator()
		{
			return new SimpleListIenumerator(First);
		}

		#endregion

		#region IEnumerable Members

		IEnumerator IEnumerable.GetEnumerator()
		{
			return new SimpleListIenumerator(First);
		}

		#endregion
	}
}
