/*
	Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
	и других спецификаций для функционирования компактных приложений на языке
	Java (мидлетов) в среде программного обеспечения Малик Эмулятор.

	Copyright © 2016, 2019 Малик Разработчик

	Это свободная программа: вы можете перераспространять ее и/или изменять
	ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
	в каком она была опубликована Фондом свободного программного обеспечения;
	либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

	Эта программа распространяется в надежде, что она будет полезной,
	но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
	или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
	общественной лицензии GNU.

	Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
	вместе с этой программой. Если это не так, см.
	<https://www.gnu.org/licenses/>.
*/


package java.util;

public abstract class Queue extends Object
{
	protected int capacity;
	protected int head;
	protected int tail;

	protected Queue()
	{
	}

	protected Queue(int capacity)
	{
		this.capacity = capacity;
	}

	public abstract void removeTailElement();

	public void clear()
	{
		tail = head;
	}

	public boolean isEmpty()
	{
		return head == tail;
	}

	public int capacity()
	{
		return capacity - 1;
	}

	public int length()
	{
		int t;
		int h;
		return (h = head) >= (t = tail) ? h - t : h - t + capacity;
	}

	protected void reset(int newCapacity)
	{
		int t;
		int h;
		head = (h = head) >= (t = tail) ? h - t : h - t + capacity;
		tail = 0;
		capacity = newCapacity;
	}

	protected void advanceHead()
	{
		head = (head + 1) % capacity;
	}

	protected void advanceHead(int elements)
	{
		head = (head + elements) % capacity;
	}

	protected void advanceTail()
	{
		tail = (tail + 1) % capacity;
	}

	protected void advanceTail(int elements)
	{
		tail = (tail + elements) % capacity;
	}

	protected int getFreeElements()
	{
		int t;
		int h;
		return ((h = head) >= (t = tail) ? capacity - (h - t) : t - h) - 1;
	}

	protected long[] expand(long[] queue, int newCapacity)
	{
		int t;
		int h;
		int len;
		int tmp;
		long[] result;
		if(queue == null)
		{
			throw new NullPointerException("Queue.expand: " +
					"параметр queue равен нулевой ссылке.");
		}
		if(queue.length != (len = capacity))
		{
			throw new IllegalArgumentException("Queue.expand: " +
					"длина очереди не соответствует её ёмкости.");
		}
		if(newCapacity <= len)
		{
			throw new IllegalArgumentException("Queue.expand: " +
					"новая ёмкость может быть только больше прежней.");
		}
		result = new long[newCapacity];
		if((h = head) < (t = tail))
		{
			Array.copy(queue, t, result, 0, tmp = len - t);
			Array.copy(queue, 0, result, tmp, h);
		} else
		{
			Array.copy(queue, t, result, 0, h - t);
		}
		return result;
	}

	protected Object[] expand(Object[] queue, int newCapacity)
	{
		int t;
		int h;
		int len;
		int tmp;
		Object[] result;
		if(queue == null)
		{
			throw new NullPointerException("Queue.expand: " +
					"параметр queue равен нулевой ссылке.");
		}
		if(queue.length != (len = capacity))
		{
			throw new IllegalArgumentException("Queue.expand: " +
					"длина очереди не соответствует её ёмкости.");
		}
		if(newCapacity <= len)
		{
			throw new IllegalArgumentException("Queue.expand: " +
					"новая ёмкость может быть только больше прежней.");
		}
		result = (Object[]) Array.create(newCapacity, queue.getClass());
		if((h = head) < (t = tail))
		{
			Array.copy(queue, t, result, 0, tmp = len - t);
			Array.copy(queue, 0, result, tmp, h);
		} else
		{
			Array.copy(queue, t, result, 0, h - t);
		}
		return result;
	}
}
