/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.collection.arrays;

import java.util.Comparator;

public final class ArraySort {

    private ArraySort() {
        // utility class
    }
   
    /**
     * Sorts an array according to the order induced by the specified comparator
     * using quicksort.
     *
     * <p>The sorting algorithm is a tuned quicksort adapted from Jon L. Bentley
     * and M. Douglas McIlroy, &ldquo;Engineering a Sort Function&rdquo;,
     * <i>Software: Practice and Experience</i>, 23(11), pages 1249&minus;1265,
     * 1993.
     *
     * @param array the array to be sorted.
     * @param comp the comparator to determine the sorting order.
     *
     */
    public static <A, T> void quickSort(A array, Comparator<T> comp) {
        NativeArraySort.quickSort(NativeArray.wrap(array), comp);
    }
    
    /**
     * Sorts the specified range of elements according to the order induced by
     * the specified comparator using quicksort.
     *
     * <p>The sorting algorithm is a tuned quicksort adapted from Jon L. Bentley
     * and M. Douglas McIlroy, &ldquo;Engineering a Sort Function&rdquo;,
     * <i>Software: Practice and Experience</i>, 23(11), pages 1249&minus;1265,
     * 1993.
     *
     * @param array the array to be sorted.
     * @param begin the index of the first element (inclusive) to be sorted.
     * @param end the index of the last element (exclusive) to be sorted.
     * @param comp the comparator to determine the sorting order.
     *
     */
    public static <A,T> void quickSort(A array, int begin, int end, Comparator<T> comp) {
        NativeArraySort.quickSort(NativeArray.wrap(array), begin, end, comp);
    }
    
    /**
     * Sorts an array according to the natural ascending order using mergesort.
     *
     * <p>This sort is guaranteed to be <i>stable</i>: equal elements will not
     * be reordered as a result of the sort. An array as large as
     * <code>array</code> will be allocated by this method.
     *
     * @param array the array to be sorted.
     */
    public static <A> void mergeSort(A array) {
        NativeArraySort.mergeSort(NativeArray.wrap(array));
    }
        
    /**
     * Sorts the specified range of elements according to the natural ascending
     * order using mergesort.
     *
     * <p>This sort is guaranteed to be <i>stable</i>: equal elements will not
     * be reordered as a result of the sort. An array as large as
     * <code>array</code> will be allocated by this method.
     *
     * @param array the array to be sorted.
     * @param begin the index of the first element (inclusive) to be sorted.
     * @param end the index of the last element (exclusive) to be sorted.
     */
    public static <A> void mergeSort(A array, int begin, int end) {
        NativeArraySort.mergeSort(NativeArray.wrap(array));
    }
    
    /**
     * Sorts an array according to the order induced by the specified comparator
     * using mergesort.
     *
     * <p>This sort is guaranteed to be <i>stable</i>: equal elements will not
     * be reordered as a result of the sort. An array as large as
     * <code>array</code> will be allocated by this method.
     *
     * @param array the array to be sorted.
     * @param comp the comparator to determine the sorting order.
     */
    public static <A, T> void mergeSort(A array, Comparator<T> comp) {
        NativeArraySort.mergeSort(NativeArray.wrap(array), comp);
    }
    
    /**
     * Sorts the specified range of elements according to the order induced by
     * the specified comparator using mergesort.
     *
     * <p>This sort is guaranteed to be <i>stable</i>: equal elements will not
     * be reordered as a result of the sort. An array as large as
     * <code>array</code> will be allocated by this method.
     *
     * @param array the array to be sorted.
     * @param begin the index of the first element (inclusive) to be sorted.
     * @param end the index of the last element (exclusive) to be sorted.
     * @param comp the comparator to determine the sorting order.
     */
    public static <A,T> void mergeSort(A array, int begin, int end, Comparator<T> comp) {
        NativeArraySort.mergeSort(NativeArray.wrap(array), begin, end, comp);
    }

}
