package org.academiadecodigo.bootcamp11.sortalgo;

/**
 * MIT License
 * (c) 2017 Ricardo Constantino
 */
public class SortAlgo {
    public static void main(String[] args) {
        int max_num_of_cards = 15;
        if (args.length > 0) {
            if (args[0].equals("-h") || args[0].equals("--help")) {
                printUsage(0);
            } else {
                try {
                    max_num_of_cards = Integer.parseInt(args[0]);
                } catch (NumberFormatException error) {
                    System.out.println("Error: the first argument is the number of elements in the array.");
                    printUsage(1);
                }
            }
        }

        System.out.println("First, let's grab a bunch of cards:");

        int[] sorted_cards = generateArray(max_num_of_cards);
        System.out.println(prettyPrint(sorted_cards));

        System.out.println("\nNow, let's shuffle them:");
        // shuffle them
        int[] shuffled_cards = shuffleArray(sorted_cards);
        System.out.println(prettyPrint(shuffled_cards));

        System.out.println("\nLet's grab the shuffled deck and sort it again "+
                "using bubble sort:");
        bubbleSort(shuffled_cards);
    }

    private static void bubbleSort(int[] array) {
        int[] result = copyArray(array);
        boolean anychange = true;
        while (anychange) {
            anychange = false;
            for (int i=0; i<result.length-1; i++) {
                if(result[i+1] < result[i]) {
                    swap(result, i, i+1);
                    anychange = true;
                }
            }
        }
        System.out.println(prettyPrint(result));
    }

    private static int[] generateArray(int length) {
        int[] result = new int[length];
        for (int i = 0; i < length; i++) {
            result[i] = i;
        }
        return result;
    }

    private static int[] shuffleArray(int[] array) {
        int count = array.length;
        int[] result = copyArray(array);

        for (int i = 0; i < count; i++) {
            int j = (int) ((double)(count - i) * Math.random() / 2.0);
            swap(result, i, i+j);
        }
        return result;
    }

    private static void swap(int[] array, int left, int right) {
        int temp = array[left];
        array[left] = array[right];
        array[right] = temp;
    }

    private static int[] copyArray(int[] array) {
        int[] result = new int[array.length];
        for (int i=0; i<array.length; i++) {
            result[i] = array[i];
        }
        return result;
    }

    private static String prettyPrint(int[] array) {
        String result = "[ ";
        for (int i = 0; i < array.length - 1; i++) {
            result += array[i] + ", ";
        }
        return result + array[array.length - 1] + " ]";
    }

    private static void printUsage(int ret) {
        System.out.println("Usage: java -jar Algorithms.jar [number_to_look_for word_to_check_if_palindrome]");
        System.exit(ret);
    }
}
