import java.util.Collections;
import java.util.ArrayList;
import java.util.List;

public class GenericMethodsExercises{

    /* Generic Methods
       2. Convert the following method to be a generic method:
    */

    /**
     * Swap the elements at two indices
     * <p>Note: Does not check if the indices are valid</p>
     * @param array The array
     * @param index1 The index of one of the elements to swap
     * @param index2 The index of other element to swap
     */
    public static void swap2Original( Integer[] array, Integer index1, Integer index2 ){
        Integer temp = array[index1];
        array[ index1 ] = array[ index2 ];
        array[ index2 ] = temp;
    }
    /**
     * Swap the elements at two indices
     * <p>Note: Does not check if the indices are valid</p>
     * @param array The array
     * @param index1 The index of one of the elements to swap
     * @param index2 The index of other element to swap
     */
    public static <T> void swap2( T[] array, int index1, int index2 ){
        T temp = array[index1];
        array[ index1 ] = array[ index2 ];
        array[ index2 ] = temp;
    }


    /* Generic Methods
       3. Does the following method compile? If not, why?
    */

    /**	    
     * Display all of the numbers (whole or real) in a list on one line
     * @param lst A list of Numbers
     */
    /* Uncomment to see if it compiles
    public <T extends Number> void printList(List<T> lst) {
        System.out.println( "printList( + "+lst+" )");
        for( Number n : lst )
            System.out.print(n + " ");
        System.out.println();
    }
    */

    /* Generic Methods
       4. Write a generic method to match the following Javadoc. Additionally,
       add code to main() to call the method twice (each with a different type).
    */

    /**
     * Finds the minimum value in a list between two indices
     * <p>Note: Does not check if the indices are valid</p>
     * @param lst The list object
     * @param startIndex The index to start looking at
     * @param endIndex The last index to consider
     * @return The smallest value in lst between startIndex and endIndex (inclusive) 
     */
    public static <T extends Comparable<T>> T findMin(List<T> lst, int startIndex, int endIndex){
        T temp = lst.get(startIndex); // current minimum value
        for( int i = startIndex + 1; i <= endIndex; ++i){
            if(lst.get(i).compareTo( temp ) < 0){
                temp = lst.get(i);
            }
        }
        return temp;
    }


    public static void main( String[] args ){

        /* Vector
           2. Declare a Vector object that stores the vowels in the English
           alphabet ('a', 'e', 'i', 'o', 'u' and 'y'). Display each of it's
           elements on a separate line.
        */




        /* Generic Methods
           2. Convert the following method to be a generic method:
        */
        Integer[] nums = {1, 2, 3};
        Character[] hello = {'h', 'e', 'l', 'l', 'o'};

        for( int i : nums ){
            System.out.print( i );
        }
        System.out.println("\n");

        swap2( nums, 1, 2 );
        for( int i : nums ){
            System.out.print( i );
        }
        System.out.println("\n");

        for( Character c : hello ){
            System.out.print( c );
        }
        System.out.println("\n");

        swap2( hello, 4, 3 );
        for( Character c : hello ){
            System.out.print( c );
        }
        System.out.println("\n");


        /* Generic Methods
           4. Additionally, add code to main() to call the method twice (each with a different type).
         */
        ArrayList<Integer> primes = new ArrayList<Integer>();
        primes.add(2);
        primes.add(3);
        primes.add(5);
        primes.add(7);
        primes.add(11);
        primes.add(13);
        primes.add(17);
        primes.add(19);
        primes.add(23);
        Collections.shuffle( primes );
        Integer min = findMin( primes, 4, primes.size() - 1);
        System.out.println("Min value in " + primes + " between indices " + 4 + " and " + (primes.size() - 1) + " is " + min);
    }
}