/* ListIterDriver.java */

import java.util.*;

/**
 * Runs a number of tests on a KWListIter, 
 * which implements java.util.ListIterator.
 *
 * @author Zach Tomaszewski
 * @version 19 Sept 2006
 */
public class ListIterDriver {

  /**
   * Tests each ListIterator method, printing expected 
   * and actual results to the screen.
   */
  public static void main(String[] args) {

    pln("");
    pln("Creating a iterator of an empty list.");
    KWLinkedList<String> list = new KWLinkedList<String>();
    ListIterator<String> iter = list.listIterator(0);
    
    p("hasNext [false]: ");
    pln("" + iter.hasNext());
    p("hasPrevious [false]: ");
    pln("" + iter.hasPrevious());
    p("nextIndex [0]: ");
    pln("" + iter.nextIndex());
    p("nextPrevious [-1]: ");
    pln("" + iter.previousIndex());
    try {
      p("next [NSEException]: ");
      pln(iter.next());
    }catch (NoSuchElementException nsee) {
      pln("NoSuchElementException");
    } 
    try {
      p("previous [NSEException]: ");
      pln(iter.previous());
    }catch (NoSuchElementException nsee) {
      pln("NoSuchElementException");
    } 
    
    pln("");
    pln("Add \"item\" to iterator.");
    iter.add("item");
    p("nextIndex [1]: ");
    pln("" + iter.nextIndex());
    p("hasNext [false]: ");
    pln("" + iter.hasNext());
    p("hasPrevious [true]: ");
    pln("" + iter.hasPrevious());
    p("previous [item]: ");
    pln("" + iter.previous());
    p("hasPrevious [false]: ");
    pln("" + iter.hasPrevious());
    pln("Removing last returned item. (Only item in the list; same as \"next\")");
    iter.remove();
    p("hasNext [false]: ");
    pln("" + iter.hasNext());
    p("hasPrevious [false]: ");
    pln("" + iter.hasPrevious());
    p("nextIndex [0]: ");
    pln("" + iter.nextIndex());
    
    pln("");

    p("Adding [two, three, six, last]: ");
    iter.add("two");
    iter.add("three");
    iter.add("six");
    iter.add("last");
    pln(list);
    
    pln("Attempting a series of actions with a new iterator on list.");
    try {
      iter = list.listIterator(0);
      
      iter.next();
      iter.remove(); //remove first item in list.
      p("After removing first item [three, six, last]: ");
      pln(list);
      
      pln("Adding \"one, two\" to the beginning of the list.");
      iter.add("one");
      iter.add("two");
      try {
        iter.remove();
        pln("OOPS: Removed when you shouldn't have (after an add).");
      }catch (IllegalStateException ise) {
        pln("GOOD: Won't remove immediately after add.");
      }      
      
      pln("");
      p("List at this point [one, two, three, six, last]: ");
      pln(list);
      iter.next(); //returns three, now on six
      pln("nextIndex before removing \"three\" [3]: " + iter.nextIndex());
      iter.remove(); //three gone; tests a remove in the middle of a list
      pln("nextIndex after remove [2]: " + iter.nextIndex());
      pln("Previous item after remove [two]: " + iter.previous());
      //now on two

      p("Removing last item. List now [one, two, six]: ");
      iter.next(); //on three 
      iter.next(); //on six
      iter.next(); //on last
      iter.remove();  //remove last item      
      pln(list);
      try {
        iter.remove();
        pln("OOPS: Removed when you shouldn't have (after a remove).");
      }catch (IllegalStateException ise) {
        pln("GOOD: Won't remove twice in a row.");
      }      

      pln("Adding \"end\" to tail of list.");
      iter.add("end");

    
    }catch (IllegalStateException ise) {
       pln("State management too uptight -- threw ISE when not needed.");
    }
    p("Finished list [one, two, six, end]: ");
    pln(list);
    pln("DONE!");
  }


  /* quick and dirty print helpers */
  private static void pln(Object str) {
    System.out.println(str);
  }

  private static void p(Object str) {
    System.out.print(str);
  }

  private static void pln(KWLinkedList list){    
    ListIterator iter = list.listIterator(0);
    while (iter.hasNext()) {
      p(iter.next() + " ");
    }
    pln("");
  }
  
}//end class

