/**
 * @author Peter A. Friend
 * @version 1.0
 */

public class Queue
{
   private class QueueNode
   {
      Object item;
      QueueNode link;
   }

   private QueueNode front;
   private QueueNode rear;
   private int itemCount;
   
   /**
    * Constructor.
    */

   public Queue()
   {
      itemCount = 0;
   }

   /**
    * Returns whether the queue is empty.
    */

   public synchronized final boolean isEmpty()
   {
      return (itemCount == 0);
   }

   /**
    * Inserts an item into the queue.
    *
    * @param newItem The new item to insert into the queue.
    */
 
   public synchronized final void insert(Object newItem)
   {
      QueueNode temp = new QueueNode();

      temp.item = newItem;
      temp.link = null;
      if(rear == null)
      {
         front = temp;
         rear = temp;
      }
      else
      {
         rear.link = temp;
         rear = temp;
      }
      itemCount++;
   }

   /**
    * Removes an item from the queue.
    *
    * @return The the item being removed from the queue or <EM>null</EM> if the queue is empty.
    */

   public synchronized final Object remove()
   {
      if(itemCount == 0)
         return null;

      Object temp = front.item;
      front = front.link;

      if(front == null)
         rear = null;

      itemCount--;
      return temp;
   }

   /**
    * Returns the queue items in an array. None are deleted.
    *
    * @return The array of items stored in the Queue.
    */

   public synchronized final Object[] toArray()
   {
      Object temp[] = new Object[itemCount];
      QueueNode node = front;

      for (int i = 0; i < itemCount; i++)
      {
         temp[i] = node.item;
         node = node.link;
      }

      return temp;
   }
}

