import java.util.List;
import java.util.ArrayList;
import java.util.Vector;
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 String findMin(List<String> lst, int startIndex, int endIndex){
        String min = lst.get(startIndex);
        for( int i = startIndex + 1; i <= endIndex; ++i){ // +1 because we we're already using the element at startIndex
            // if( list.get(i) < min ){
            if( lst.get(i).compareTo( min ) < 0 ){
                min = lst.get(i);
            }
        }
        return min;
    }*/
    public static <T extends Comparable<T>> T findMin(List<T> lst, int startIndex, int endIndex){
        T min = lst.get(startIndex);
        for( int i = startIndex + 1; i <= endIndex; ++i){ // +1 because we we're already using the element at startIndex
            // if( list.get(i) < min ){
            if( lst.get(i).compareTo( min ) < 0 ){
                min = lst.get(i);
            }
        }
        return min;
    }

    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<Double> numbers = new ArrayList<Double>();
        numbers.add(5.0);
        numbers.add(3.141596);
        numbers.add(99.0);
        numbers.add(100.0);
        System.out.println("The minimum value of " + numbers + " is " + findMin(numbers, 0,numbers.size() - 1));

        Vector<String> colors = new Vector<String>();
        colors.add("blue");
        colors.add("red");
        colors.add("green");
        colors.add("phthalo blue");
        System.out.println("The minimum value of " + colors + " is " + findMin(colors, 1,colors.size() - 2));;
    }
}