/*
 * Queue.class
 * Part of package project
 *
 * Author: Philip Bradley
 *
 */

package project;

public class Queue {

	QueueNode head = new QueueNode();
	QueueNode tail = new QueueNode();
	int qSize;

	public Queue() {
		head = new QueueNode();
		tail = head;
		qSize = 0;
	}

        /**
        * Checks to see if the Queue is empty
        * @return	boolean indicating if Queue is empty
        */
	public boolean isEmpty() {
		return(qSize == 0);
	}

        /**
        * @return       An int indicating the number of elements in the Queue
        */
	public int getSize() {
		return(qSize);
	}

        /**
        * @return       String consisting of concatenation of all the
	*		Queue elements in String form
        */
	public String toString() {
		int index = qSize;
		String s = new String("");
		QueueNode node = head;

		while (--index >= 0) {
			s += node.data.toString() + " ";
			node = node.next;
		}
		return(s);
	}

        /**
	* Adds an Object to the Queue
        * @param        The Object to be enQueued
        */
	public void enQueue(Object o) {
		QueueNode newQueueNode = new QueueNode();
		tail.data = o;
		tail.next = newQueueNode;
		tail = tail.next;
		qSize++;
	}

        /**
        * Adds an int to the Queue
	* This method is superfluous and should be removed at some stage
        * @param        The int to be enQueued
        */
	public void enQueue(int i) {
		enQueue(new Integer(i));
	}

        /**
        * Returns the element currently at the head of the Queue or else 
	* throws an Exception if the Queue is empty.
        * @return       The element currently at the head of the Queue.
        */
	public Object serve() throws Exception {
		if (qSize > 0) {
			Object returnVal = head.data;
			head = head.next;
			qSize--;
			return(returnVal);
		} else {	
			throw(new Exception("Queue is empty."));
		}
	}

	
	public static void main(String[] args) {
	/*
	 * Some test code.
	 *
	 */
		Queue q = new Queue();
		q.enQueue("First");
		q.enQueue("Second");
		q.enQueue("Third");
		System.out.println(q.toString());
		try {
			while (!q.isEmpty()) {
				System.out.print("Size: " + q.getSize() + " ");
				System.out.println(q.serve());
			}
                        System.out.println("Size: " + q.getSize()); 
		} catch (Exception e) {
			System.out.println("Error: " + e.getMessage());
		}
	}
}

class QueueNode {

	Object data;
	QueueNode next;

	public QueueNode() {
		data = null;
		next = null;
	}
}

