/* Aufgabe 31 Prakash Punnoor */

class Aufgabe31
{
	public static void main ( String[] args )
	{
		/* ein einfacher Test */
		queue q = new queue(3);
		
		System.out.println("empty: "+q.empty());
		q.enq(new Integer(1));System.out.println("enq 1");
		System.out.println("empty: "+q.empty());
		q.enq(new Integer(2));System.out.println("enq 2");
		System.out.println("front: "+q.front());
		q.deq();System.out.println("deq");
		System.out.println("empty: "+q.empty());
		System.out.println("front: "+q.front());
		q.deq();System.out.println("deq");
		System.out.println("empty: "+q.empty());
		System.out.println("front: "+q.front());
		q.deq();System.out.println("deq");
		System.out.println("empty: "+q.empty());
		
		q.enq(new Integer(3));System.out.println("enq 3");
		System.out.println("empty: "+q.empty());
		System.out.println("front: "+q.front());
		q.deq();System.out.println("deq");
		System.out.println("empty: "+q.empty());
		
		System.out.println("Test maxfill");
		for (int i = 1; i<=3; ++i) {
			q.enq(new Integer(i));System.out.println("enq "+i);
		}
		
		for (int i = 1; i<=3; ++i) {
			System.out.println("front: "+q.front());
			q.deq();
		}
		
		System.out.println("Test overflow");
		for (int i = 1; i<=4; ++i) {
			q.enq(new Integer(i));System.out.println("enq "+i);
		}

		for (int i = 1; i<=4; ++i) {
			System.out.println("front: "+q.front());
			q.deq();
		}
		
		System.out.println("Test Ring");
		for (int i = 1; i<=2; ++i) {
			q.enq(new Integer(i));System.out.println("enq "+i);
		}
		q.deq();
		for (int i = 3; i<=4; ++i) {
			q.enq(new Integer(i));System.out.println("enq "+i);
		}
		q.deq();
		q.enq(new Integer(5));System.out.println("enq 5");

		for (int i = 1; i<=3; ++i) {
			System.out.println("front: "+q.front());
			q.deq();
		}

		
		return;
	}
}

/* Zwar hätte es auch gereicht die Aufgabe wie die Keller-
Implementation zu lösen, doch wollten einige explizit ein
interface sehen ;-) */
interface queueI
{
	public boolean empty();
	public void enq(Object datum);
	public Object front();
	public void deq();
}

class queue implements queueI
{
	private Object array[];
	private int index_start;
	private int index_end;
	private int max_size;
	
	public queue(int array_size)
	{
		/* um von der vollen Schlange zu unterscheiden -> Vorlesung */
		max_size = array_size + 1;
		array = new Object[max_size];
		index_start = 0;
		index_end = 0;
	}
	
	public boolean empty()
	{
		return index_start == index_end;
	}
	
	public void enq(Object datum)
	{
		int index_end_old = index_end;
		
		++index_end;
		index_end %= max_size;
		if (index_end == index_start) {
			/* Schlange voll, hier sollte eine Exception hin... */
			index_end = index_end_old;
			System.out.println("queue full");
			return;
		}
		array[index_end_old] = datum;
	}
	
	public Object front()
	{
		return empty() ? null : array[index_start];
	}
	
	public void deq()
	{
		if (!empty()) {
			++index_start;
			index_start %= max_size;
		}
	}
}