
interface Queue {
	
	public void enqueue(Object o) throws Exception;
	
	public Object dequeue();
	
	public boolean isFull();
	
}


// Implementiert eine Schlange mit einem Array, der
// eine Art Kreis simuliert
class ArrayQueue implements Queue {
	
	Object[]	ar;
	int			start = 0;
	int			elements = 0;
	
	public ArrayQueue(int capacity) {
		
		ar = new Object[capacity];
		
	}
	
	public void enqueue(Object o) throws Exception {
		
		if (!isFull()) {
			
			ar[(start + elements) % ar.length] = o;
			elements++;
			
		}
		else throw new Exception("Queue is full.");
		
	}
	
	public Object dequeue() {
		
		if (elements > 0) {
			
			elements--;
			
			int i = start;
			start = (start+1) % ar.length;
			
			return ar[i];
			
		}
		
		// alternativ könnte man auch eine Exception werfen
		return null;
		
	}
	
	// pre: elements <= ar.length
	public boolean isFull() {
		return (elements == ar.length);
	}
	
	public static void main(String[] args) {
		
		Queue st = new ArrayQueue(3);
		
		try {
			st.enqueue(new Integer(1));
			st.enqueue(new Integer(2));
			st.enqueue(new Integer(3));
			
			// der wirft 'ne Exception
			st.enqueue(new Integer(4));
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		// dann nehmen wir den ersten wieder raus
		System.out.println((Integer) st.dequeue());

		try {
			// jetzt passe die 4 auch noch rein
			st.enqueue(new Integer(4));
		}
		catch (Exception e) {
			// won't happen
		}
		
		System.out.println((Integer) st.dequeue());
		System.out.println((Integer) st.dequeue());
		System.out.println((Integer) st.dequeue());
		
		// jetzt ist der Stack leer
		System.out.println((Integer) st.dequeue());
		
	}
}

