// Queue implemented using an array as a ring buffer

public class QueueAsArray implements SeqStructure {
    private int head;           // points to element for dequeue
    private int tail;           // points to empty slot for enqueue
    private Object[] a;         // array of objects
    private int size;           // current number of objects in queue
    private final int MAXSIZE;  // max number of objects

    // make Queue with array:
    public QueueAsArray(int size) {
	a = new Object[size];
	MAXSIZE = size;
	head = 0;
	tail = 0;
	this.size = 0;
    }

    // enqueue:
    public void put(Object o) {
	if (size == MAXSIZE) {
	    System.out.print("Overflow!");
	    return;
	}
	// queue isn't full, so tail must point to an empty slot:
	a[tail++] = o;                   // insert item at end of Q and move tail up
	if (tail == MAXSIZE) tail = 0;   // if tail at end, move to front
	size++;                          // increment count of items in Q
    }
    
    // dequeue:
    public Object get() {
	if (size == 0) {
	    System.out.print("Empty!");
	    return null;
	}
	// Since size is not 0, we know head must point to a valid item:
	Object temp = a[head];           // get item from head of Q (FIFO)
	a[head++] = null;                // reset that location and move head pointer
	if (head == MAXSIZE) head = 0;   // wrap-around: if head at end move to front
	size--;                          // decrease count of items in Q
	return temp;                     // return extracted item
    }
    
    // elements in queue:
    public int size() {
	return size; 
    }
    
    // is size==0?
    public boolean isEmpty() {
	return (size == 0); 
    }

    // Strigify queue:
    public String toString() {
        String s = "FIFO: [";
	// there is at least one item in queue:
	if (size!=0) {
	    int index = head;                    // start iterating from head
	    do {                                 // keep iterating until index reaches tail
		s += a[index++];                 // stringify current element and increment index
		if (index == MAXSIZE) index = 0; // wrap-around: move index to front
		if (index != tail) s+=" | ";     // add spacer to be fancy
	    } while (index != tail);             // stop iterating when index hits tail
	}
        s +="]";
        return s;
    }
}