// In this implementation of a queue, the empty
// queue is always positionned to the left of
// the array.

public class CircularQueue implements Queue {

    private int capacity = 1000;

    private Object[] q;
    private int front, rear;

    public CircularQueue () {
        q = new Object[capacity];
        rear  = -1; // represents the empty queue
        front =  0; // represents the empty queue
    }

    public CircularQueue (int capacity) {
	this.capacity = capacity;
        q = new Object[capacity];
        rear  = -1; // represents the empty queue
        front =  0; // represents the empty queue
    }

    public boolean isEmpty () {
        return (rear == -1) ;
    }

    public boolean isFull () {
        return (rear != -1) && ((rear+1) % capacity) == front ;
    }
    
    public void enqueue (Object o) {
	    if (isFull())
	        throw new IllegalStateException("queue is full");

        rear = (rear+1)%capacity;
        q[rear] = o;
    }

    public Object peek () {
        return q[front];
    }

    public Object dequeue () {
        Object returnValue = q[front];
        if (front == rear) { // following this operation
	    rear  = -1;      // the queue will be empty
	    front =  0;
        } else {
	    front = (front+1)%capacity;
        }
        return returnValue;
    }

    public String toString () {
        String answer ;
        if (isEmpty ()) {
	    answer = "<<";
        } else {
	    answer = "<";
	    int i = front;
	    while (i != rear) {
		answer = answer+" "+q[i];
		i = (i+1)%capacity;
	    }
	    answer = answer + " " + q[rear] + "<";
        }
        return answer;
    }

}
