using System;
using System.Diagnostics;

namespace System.Collections.Generic
{
	[DebuggerDisplay("Count = {_size}")]
	internal sealed class Deque<T>
	{
		public int Count
		{
			get
			{
				return this._size;
			}
		}

		public bool IsEmpty
		{
			get
			{
				return this._size == 0;
			}
		}

		public void EnqueueTail(T item)
		{
			if (this._size == this._array.Length)
			{
				this.Grow();
			}
			this._array[this._tail] = item;
			int num = this._tail + 1;
			this._tail = num;
			if (num == this._array.Length)
			{
				this._tail = 0;
			}
			this._size++;
		}

		public T DequeueHead()
		{
			T t = this._array[this._head];
			this._array[this._head] = default(T);
			int num = this._head + 1;
			this._head = num;
			if (num == this._array.Length)
			{
				this._head = 0;
			}
			this._size--;
			return t;
		}

		public T PeekHead()
		{
			return this._array[this._head];
		}

		public T DequeueTail()
		{
			int num = this._tail - 1;
			this._tail = num;
			if (num == -1)
			{
				this._tail = this._array.Length - 1;
			}
			T t = this._array[this._tail];
			this._array[this._tail] = default(T);
			this._size--;
			return t;
		}

		public IEnumerator<T> GetEnumerator()
		{
			Deque<T>.<GetEnumerator>d__12 <GetEnumerator>d__ = new Deque<T>.<GetEnumerator>d__12(0);
			<GetEnumerator>d__.<>4__this = this;
			return <GetEnumerator>d__;
		}

		private void Grow()
		{
			int num = (int)((long)this._array.Length * 2L);
			if (num < this._array.Length + 4)
			{
				num = this._array.Length + 4;
			}
			T[] array = new T[num];
			if (this._head == 0)
			{
				Array.Copy(this._array, array, this._size);
			}
			else
			{
				Array.Copy(this._array, this._head, array, 0, this._array.Length - this._head);
				Array.Copy(this._array, 0, array, this._array.Length - this._head, this._tail);
			}
			this._array = array;
			this._head = 0;
			this._tail = this._size;
		}

		private T[] _array = Array.Empty<T>();

		private int _head;

		private int _tail;

		private int _size;
	}
}
