// SortingDemoMessages.java
// Demonstrates selectionSort and isSorted methods,
// and facilitates testing of various things that 
// can go wrong, without any built-in error-checking.
//
// In this version, the selectionSort and isSorted
// methods print error messages if the subarray length
// is out-of-range, and the selectionSort method
// also prints an error message if it is unsuccessful
// for any other reason.
//
// See comments in main method for testing options.

/**
 * Test program for selectionSort and isSorted
 * methods defined within this class.  Main
 * method contains commented-out options to
 * facilitate testing of parameter values
 * including inappropriate and boundary cases.
 *
 * @author Dorothy L. Nixon
 */
public class SortingDemoMessages
{
   /**
    * Main method.
    *
    * @param args command-line arguments.  None needed;
    */
   public static void main(String[] args)
   {
      short[] numbers = new short[] {5, -1, 9, 4, 8, 2, -3, 10, 3};
      int lengthFilled = 6;

      // To test various alternative values of numbers,
      // both appropriate and inappropriate, uncomment one
      // of the following lines at a time:
      //
      // numbers = new short[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
      // numbers = new short[] {9, 8, 7, 6, 5, 4, 3, 2, 1};
      // numbers = new short[] {2, 1};
      // numbers = new short[] {1};         // trivial array (okay)
      // numbers = new short[] {};          // empty array (okay)
      // numbers = null;                    // no array (not okay)

      // To test various alternative values of lengthFilled,
      // both appropriate and inappropriate, uncomment one
      // of the following lines at a time:
      //
      // lengthFilled = 0;                    // appropriate
      // lengthFilled = numbers.length;       // appropriate
      // lengthFilled = -1;                   // inappropriate
      // lengthFilled = numbers.length + 1;   // inappropriate

      // Sort numbers in ascending order.  Test selectionSort:
      selectionSort(numbers, lengthFilled);

      // Below is a test of the isSorted method, which
      // determines whether a subarray is sorted.  To test
      // isSorted for unsorted arrays, comment out the above
      // call to selectionSort.
      System.out.println(
                  "According to the isSorted method, the array "
                  + ((isSorted(numbers, lengthFilled))?"IS":"is NOT")
                  + " sorted.");

      // Display the numbers:
      System.out.print("End test.  Array contains: ");
      for ( int i = 0; i < lengthFilled; i++ )
         System.out.print(" " + numbers[i]);
      System.out.println();
   }  // method main

   /**
    * Sorts a partially-filled array of short
    * integers using selection sort.
    *
    * If the specified subarray length is out of
    * range, an error message is printed to the
    * console and the program exits with error
    * code 1.
    *
    * If sorting is unsuccessful for any other
    * reason, an error message is printed to the
    * console and the program exits with error
    * code 2.
    *
    * @param array the array to be sorted.
    * @param length length of filled portion of array
    *               Must be between 0 and the length
    *               of <code>array</code>, inclusive.
    */
   private static void selectionSort(short[] array,
                                     int length)
   {
      if ( length < 0 || length > array.length )
      {
         System.err.println("selectionSort parameter length = "
                            + length + ", should be in range "
                            + "[0, " + array.length + "]");
         System.exit(1);
      }  // if

      for ( int i = 0; i < length - 1; i++ )
      {
         // Find the lowest-valued element in
         // the subarray from index i up to
         // index length - 1
         int indexLowest = i;
         for ( int j = i + 1; j < length; j++ )
            if ( array[j] < array[indexLowest] )
               indexLowest = j;

         // Put the lowest-valued element at
         // index i, swapping if necessary:
         if ( array[indexLowest] < array[i] )
         {
            short temp = array[indexLowest];
            array[indexLowest] = array[i];
            array[i] = temp;
         }
      }  // for i

      if ( ! isSorted(array, length) )
      {
         System.err.println("selectionSort failed.");
         System.exit(2);
      }  // if
   }  // method selectionSort

   /**
    * Detects whether the specified subarray is sorted
    * in ascending order.
    *
    * If the specified subarray length is out of
    * range, an error message is printed to the
    * console and the program exits with error
    * code 1.
    *
    * @param array an array containing the subarray to be checked.
    *            Assume that the subarray starts at index 0.
    * @param length length of the subarray.
    *               Must be between 0 and the length
    *               of <code>array</code>, inclusive.
    */
   private static boolean isSorted(short[] array,
                                   int length)
   {
      if ( length < 0 || length > array.length )
      {
         System.err.println("selectionSort parameter length = "
                            + length + ", should be in range "
                            + "[0, " + array.length + "]");
         System.exit(1);
      }  // if

      for ( int i = 1; i < length; i++ )
         if ( array[i] < array[i-1] )
            return false;
      return true;
   }  // method isSorted
}  // class SortingDemoMessages