// package weiss.nonstandard;

// ListQueue class
//
// CONSTRUCTION: with no initializer
//
// ******************PUBLIC OPERATIONS*********************
// void enqueue( x )      --> Insert x
// AnyType getFront( )    --> Return least recently inserted item
// AnyType dequeue( )     --> Return and remove least recent item
// boolean isEmpty( )     --> Return true if empty; else false
// void makeEmpty( )      --> Remove all items
// ******************ERRORS********************************
// getFront or dequeue on empty queue

/**
 * List-based implementation of the queue.
 * @author Mark Allen Weiss
 */
public class ListQueue<AnyType> implements Queue<AnyType>
{
  // In class exercise showing how queue changes
  public static void main(String args[]){
    ListQueue<String> bsg = new ListQueue<String>();
    bsg.enqueue("Adama");        // Add to back
    bsg.enqueue("Tye");
    bsg.enqueue("Starbuck");
    bsg.dequeue();               // Remove from front
    String col = bsg.getFront(); // Who's in front
    bsg.dequeue();
    bsg.enqueue("Apollo");    
    bsg.enqueue("Baltar");
    bsg.dequeue();
    bsg.enqueue("Number 6");
    bsg.dequeue();
    System.out.println("Everybody's a Cyclon");
  }

  /**
   * Construct the queue.
   */
  public ListQueue( )
    {
      front = back = null;
    }

  /**
   * Test if the queue is logically empty.
   * @return true if empty, false otherwise.
   */
  public boolean isEmpty( )
  {
    return front == null;
  }

  /**
   * Insert a new item into the queue.
   * @param x the item to insert.
   */
  public void enqueue( AnyType x )
  {
    if( isEmpty( ) )    // Make queue of one element
      back = front = new ListNode<AnyType>( x );
    else                // Regular case
      back = back.next = new ListNode<AnyType>( x );
  }

  /**
   * Return and remove the least recently inserted item
   * from the queue.
   * @return the least recently inserted item in the queue.
   * @throws UnderflowException if the queue is empty.
   */
  public AnyType dequeue( )
  {
    if( isEmpty( ) )
      throw new UnderflowException( "ListQueue dequeue" );

    AnyType returnValue = front.element;
    front = front.next;
    return returnValue;
  }

  /**
   * Get the least recently inserted item in the queue.
   * Does not alter the queue.
   * @return the least recently inserted item in the queue.
   * @throws UnderflowException if the queue is empty.
   */
  public AnyType getFront( ) 
  {
    if( isEmpty( ) )
      throw new UnderflowException( "ListQueue getFront" );
    return front.element;
  }

  /**
   * Make the queue logically empty.
   */
  public void makeEmpty( )
  {
    front = null;
    back = null;
  }

  private ListNode<AnyType> front;
  private ListNode<AnyType> back;


}
