//DLLGrader.java

import java.io.*;

/**
 * A series of tests to check an implementation of DLList.
 *
 * @author Zach Tomaszewski
 * @version 04 Oct 2004
 */
public class DLLGrader {

  /**
   * Runs a series of tests, printing expectations and actual results to
   * the screen.
   */
  public static void main(String[] args) {
    try{
      BufferedReader stdin = new BufferedReader(
                                new InputStreamReader(System.in));
      pln("");
      pln("DLLGrader will run a number of tests to check your DLList.");
      pln("Tests display the expected outcome in [brackets].");
      pln("The formatting of your displayed results may be different,");
      pln("but the values need to match the expected outcome.");
      pln("If your DLList is correctly implemented, DLLGrader will ");
      pln("run through all tests correctly and end with a 'DONE' message.");
      pln("");
      pln("Good luck!");

      pln("");
      pln("-- Hit Enter to continue --");
      stdin.readLine();
    
      pln("Creating a new DLList named 'list'.");
      java.util.List list = new DLList();
      p("Printing empty list []: ");
      pln(list.toString());
      
      p("Size of an empty list [0]: ");
      pln("" + list.size());
      p("list isEmpty? [true]: ");
      pln("" + list.isEmpty());
      p("list contains 'one' [false]: ");
      pln("" + list.contains("one"));
      
      pln("");
      p("Adding 'two' to the list with add(Object) [true]: ");
      pln("" + list.add("two"));
      p("Adding 'three' to the list with add(Object) [true]: ");
      pln("" + list.add("three"));
      pln("Printing list: [two three]");
      pln(list.toString());

      p("Size of list [2]: ");
      pln("" + list.size());
      p("list isEmpty? [false]: ");
      pln("" + list.isEmpty());
      p("list contains 'two' [true]: ");
      pln("" + list.contains("two"));
      p("list contains 'one' [false]: ");
      pln("" + list.contains("one"));

      pln("");
      DLList list23 = new DLList();
      list23.add("two");
      list23.add("three");
      DLList list234 = new DLList();
      list234.add("two");
      list234.add("three");
      list234.add("four");
      
      p("list equals DLList{two three} [true]: ");
      pln("" + list.equals(list23));
      p("list equals DLList{two three four} [false]: ");
      pln("" + list.equals(list234));
      p("DLList{two three four} equals list [false]: "); 
      pln("" + list234.equals(list));
      p("a new DLList equals a new DLList [true]: "); 
      pln("" + (new DLList()).equals(new DLList()));
    
      pln("");
      pln("-- Hit Enter to continue --");
      stdin.readLine();

      p("Size of list is still [2]: "); 
      pln("" + list.size());
      pln("Adding 'one' to list, pos 0. "); //start
      list.add(0, "one");
      pln("Adding 'two' to list, pos 2. "); //middle
      list.add(2, "two");
      pln("Adding 'five' to list, pos 4. "); //end
      list.add(4, "five");
      pln("Printing list [one, two, two, three, five]: ");
      pln(list.toString());    
      
      pln("");
      p("indexOf 'one' in list [0]: ");
      pln("" + list.indexOf("one"));
      p("indexOf 'two' in list [1]: ");
      pln("" + list.indexOf("two"));
      p("last indexOf 'two' in list [2]: ");
      pln("" + list.lastIndexOf("two"));
      p("indexOf 'none' in list [-1]: ");
      pln("" + list.indexOf("none"));
      p("last indexOf 'none' in list [-1]: ");
      pln("" + list.lastIndexOf("none"));

      pln("");    
      p("getting position 0 [one]: ");
      pln("" + list.get(0));
      p("getting position 3 [three]: ");
      pln("" + list.get(3));

      pln("");
      pln("-- Hit Enter to continue --");
      stdin.readLine();

      p("setting position 4 to 'end' [five]: "); 
      pln(list.set(4, "end").toString());
      pln("Printing list [one, two, two, three, end]: ");
      pln(list.toString());
      
      pln("");
      p("removing pos 0 of list [one]: ");
      pln("" + list.remove(0));
      p("removing pos 2 of list [three]: ");
      pln("" + list.remove(2));
      p("removing pos 2 of list [end]: ");
      pln("" + list.remove(2));
      pln("Printing list [two, two]: ");
      pln(list.toString());
      
      pln("");
      pln("adding (1, 'midtwo'). ");
      list.add(1, "midtwo");
      p("adding to end 'seven', 'newend' [true/true]: ");
      p(list.add("seven") + "/");
      pln(list.add("newend") + "");

      pln("");
      pln("-- Hit Enter to continue --");
      stdin.readLine();
      
      pln("Printing list [two, midtwo, two, seven, newend]: ");
      pln(list.toString());
      p("Size is [5]: ");
      pln("" + list.size());
      
      pln("");
      p("removing 'two' [true]: ");
      pln("" + list.remove("two"));
      p("removing 'newend' [true]: ");
      pln("" + list.remove("newend"));
      p("removing 'two' [true]: ");
      pln("" + list.remove("two"));
      p("removing 'none' [false]: ");
      pln("" + list.remove("none"));
      pln("Printing list [midtwo, seven]: ");
      pln(list.toString());
      
      pln("");
      p("toArray the list \n[SIZE 2: midtwo seven]: ");
      Object[] objArr = list.toArray();
      p("[SIZE " + objArr.length + ":");
      for (int i = 0; i < objArr.length; i++){
        p(" " + objArr[i]);
      }
      pln("]");
      
      p("toArray (new Object[3]) \n[SIZE 3: midtwo seven null]: ");
      objArr = list.toArray(new Object[3]);
      p("[SIZE " + objArr.length + ":");
      for (int i = 0; i < objArr.length; i++){
        p(" " + objArr[i]);
      }
      pln("]");

      p("toArray (new String[1]) \n[SIZE 2: midtwo seven]: ");
      objArr = list.toArray(new String[1]);
      p("[SIZE " + objArr.length + ":");
      for (int i = 0; i < objArr.length; i++){
        p(" " + objArr[i]);
      }
      pln("]");

      pln("toArray (new String[3]) -- returned 'in the specified array'");
      p("[SIZE 3: midtwo seven null]: ");
      objArr = new String[3]; 
      list.toArray(objArr);
      p("[SIZE " + objArr.length + ":");
      for (int i = 0; i < objArr.length; i++){
        p(" " + objArr[i]);
      }
      pln("]");

      pln("");
      pln("-- Hit Enter to continue --");
      stdin.readLine();

      pln("Clearing the list.");
      list.clear();
      p("Size is [0]: ");
      pln("" + list.size());
      p("Adding an Integer(3) [true]: ");
      pln("" + list.add(new Integer(3)));
      pln("");
      
      pln("Now checking for exception circumstances.");
      try {
        p("Adding out of bounds [catch IOOBE]: ");
        list.add(3, new Integer(5));
        pln("FAILED");
      }catch (IndexOutOfBoundsException ioobe) {
        pln("Caught IOOBE.");
      }
      try {
        p("Setting out of bounds [catch IOOBE]: ");
        list.get(5);
        pln("FAILED");
      }catch (IndexOutOfBoundsException ioobe) {
        pln("Caught IOOBE.");
      }
      try {
        p("Removing out of bounds [catch IOOBE]: ");
        list.remove(6);
        pln("FAILED");
      }catch (IndexOutOfBoundsException ioobe) {
        pln("Caught IOOBE.");
      }
      
      pln("\n");
      pln("DLLGrader is DONE.");
      pln("");

    }catch (IOException ioe) {
      pln("Encountered problems reading from keyboard.  Exiting...");
    }
  }
  
  
  
  /**
   * Shortcut for printing.
   */
  private static void p (String text){
    System.out.print(text);
  }

  /**
   * Shortcut for printing.
   */
  private static void pln (String text){
    System.out.println(text);
  }
    
}
