import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;

/* StringSortApp.java
** Java application that is for the purpose of testing objects from
** any of a few classes whose instances have methods that can sort
** an array of Strings.
*/
public class StringSortApp {

   /* Populates an array with tokens read from the input file using a
   ** Scanner, prints the array's contents, calls a method (on an object
   ** having such a method) to sort the array, and prints its contents 
   ** again.
   ** The name of the input file is provided by the first command line
   ** argument.  The first token of the file is assumed to be a nonnegative
   ** integer indicating how many subsequent strings are to be read from 
   ** the file.
   */
   public static void main(String[] args) throws FileNotFoundException {

      String line = "---------------------------------";

      // Establish a scanner that can read from the file whose name is
      // the first command line argument.
      Scanner input = new Scanner(new File(args[0]));

      // First token of input indicates how many tokens are to be read.
      final int N = input.nextInt();

      String[] strAry = new String[N];   // create the array
      for (int i = 0; i != N; i++) {     // populate the array
         strAry[i] = input.next();
      }

      // Use an instance of StringSorterLexico to sort the array into
      // lexicographic order.
      StringSorter sorter = new StringSorterLexico();
      testSorter(sorter, strAry);
      System.out.println(line + line + '\n');

      // Use an instance of StringSorterLenLexico to sort the array into
      // length-lexicographic order.
      sorter = new StringSorterLenLexico();
      testSorter(sorter, strAry);
      System.out.println(line + line + '\n');

      // Use an instance of StringSorterLexicoReverse to sort the array into
      // reverse-lexicographic order (i.e., descending order).
      sorter = new StringSorterLexicoReverse();
      testSorter(sorter, strAry);
      System.out.println(line + line + '\n');

      // Use an instance of StringSorterLexicoCaseInsensitive to sort the 
      // array into lexicographic order, but ignoring the case of letters
      // appearing in the strings.
      sorter = new StringSorterLexicoCaseInsensitive();
      testSorter(sorter, strAry);
   }

   /* Given an instance of (some proper descendant class of) StringSorter
   ** and an array of Strings, displays the array, sorts it, and displays
   ** it again.
   */
   private static void testSorter(StringSorter sorter, String[] ary) {
      Class c = sorter.getClass();
      System.out.println("About to sort using an instance of " + c.toString());
      System.out.println("Original array:");       // Display the contents
      System.out.println(Arrays.toString(ary));    // of the array (before)
      sorter.sort(ary);
      System.out.println("\nAfter sorting:");      // Display the contents
      System.out.println(Arrays.toString(ary));    // of the array (after)
   }

}