import java.util.*;

public class TravellerList implements TravellerListUtils {
  DNode head;
  DNode tail;
  DNode cur;
  
  // constructor
  public TravellerList() {
  		head = null;
  		tail = null;
  		cur = null;
  }
  
  // public method to add a new passenger to the queue!
  public void addTraveller(Object o) {
  	DNode tmp = new DNode(o);
  	if ( head != null ) {
  		tmp.setNext(head);
  		head.setPrev(tmp);
  	} else {
  		tail = tmp;
  	}
  	head = tmp;	
  }
  
  public String toString() {
  	String tmp = "\n";
  	Enumeration tmpit = fifoIterator();
    while ( tmpit.hasMoreElements() == true) {
  		tmp = tmp + " " + tmpit.nextElement().toString() + "\n";
  	}
  	return tmp;
  }
  
    //
    // lifo iterator stuff
    //
    private class LocalLifoIterator implements Enumeration {
       private DNode curNode;
    
       public LocalLifoIterator() {
         curNode = head;
       }
       public boolean hasMoreElements() {
          return curNode != null;
       }
       public Object nextElement() {
         Object c = curNode;
         curNode = curNode.getNext();
         return ((DNode)c).getData();
       }
     } // end private class LocalLifoIterator

     public Enumeration lifoIterator() {
       return new LocalLifoIterator();
     }
  
     //
     // fifo iterator
     //
     private class LocalFifoIterator implements Enumeration {
        private DNode curNode;
    
        public LocalFifoIterator() {
          curNode = tail;
        }
        public boolean hasMoreElements() {
          return curNode != null;
        }
        public Object nextElement() {
          Object c = curNode;
          curNode = curNode.getPrev();
          return ((DNode)c).getData();
        }
      } // end private class LocalFifoIterator

      // return a fifo iterator
      public Enumeration fifoIterator() {
        return new LocalFifoIterator();
      }
      
      //
      // priority fifo iterator -- only return the elite passengers in fifo order
      //
      private class LocalPFifoIterator implements Enumeration {
        private DNode curNode;
    
        public LocalPFifoIterator() {
          curNode = tail;
        }
        public boolean hasMoreElements() {
          // advance the curNode to the first elite passenger if we can
          while (curNode != null && !(curNode.getData() instanceof ElitePassenger) ) {
          	   curNode = curNode.getPrev();
          } 
          return curNode != null;
       }
        
        public Object nextElement() {
          Object c = curNode;
          // advance the curNode to the next elite passenger or to null
          curNode = curNode.getPrev();
          while (curNode != null && !(curNode.getData() instanceof ElitePassenger) ) {
          	   curNode = curNode.getPrev();
          } 
          return ((DNode)c).getData();
        }
     } // end private class LocalIterator

      // return a priority fifo iterator
      public Enumeration pfifoIterator() {
        return new LocalPFifoIterator();
      } 
  
  // tester for this class
  public static void main (String [] args ) {
  	TravellerList q = new TravellerList();
  	  	
 	ElitePassenger e0 = new ElitePassenger("Sarah");
 	q.addTraveller(e0);
 	Passenger p1 = new Passenger("Peggy");
  	q.addTraveller(p1);
   	Infant i1 = new Infant("Baby", 18, e0);
   	q.addTraveller(i1);
    
  	ElitePassenger e1 = new ElitePassenger("Michael");
 	q.addTraveller(e1);
 	Passenger p2 = new Passenger("Brian");
 	q.addTraveller(p2);
  	System.out.println("printing the entire queue right after creation " + q.toString()); 
  	
  	System.out.println("");
  	System.out.println("***testing iterators***");
  	Enumeration fifoit = q.fifoIterator();
  	System.out.println("doing fifo first");
  	while (fifoit.hasMoreElements()) {
  		System.out.println(fifoit.nextElement().toString());
  	}
  	System.out.println("");
  	System.out.println("doing lifo next");
  	Enumeration lifoit = q.lifoIterator();
  	while (lifoit.hasMoreElements()) {
  		System.out.println(lifoit.nextElement().toString());
  	}

    System.out.println("");
  	System.out.println("doing priority fifo next");
	// only print out the passengerbs that are elite!
  	Enumeration pfifoit = q.pfifoIterator();
  	while (pfifoit.hasMoreElements() == true ) {
  		System.out.println(pfifoit.nextElement().toString());
  	} 
  	
  	
  } // main
}
 
