import java.util.Scanner;


public class SortTest {

	/**
	 * Udava rozsah generovanych cisel od 1 do ...RANDOM_SIZE
	 */	
	public static final int RANDOM_SIZE = 100;
	
	/**
	 * Udava velikost pole generovaneho nahodne pomoci metody
	 */
	public static final int RANDOM_LENGHT = 10;

	
	/**
	 * Metoda cte int z klavesnice a vraci ho.
	 * @return
	 */
	public static int readInt(){
	    Scanner sc = new Scanner(System.in);
		int integer = sc.nextInt();
		return integer;
	}

	/**
	 * Metoda necha uzivatele zadat delku pole intu a jeho prvky
	 * @return
	 */
	public static int[] keyboardToArray() {
		int arrayLenght;
		System.out.println("Zadej pocet prvku pole: ");
		arrayLenght = readInt();
		int[] array;
		array = new int[arrayLenght] ;
		System.out.println("Zadej " + array.length + " celych cisel: "); 
		for (int i=0; i < array.length; i++){
			array[i] = readInt(); 
		}
	return	array;
	}	
	
	
	/**
	 * Metoda generujici nahodne pole intu o velikosti size.
	 * @param size
	 * @return
	 */
	public static final int[] generateRandomArray(int size) {
		int[] result = new int[size];
		for (int i = 0; i < result.length; i++) {
			result[i] = (int)((Math.random() * RANDOM_SIZE)+1);
		}
		return result;
	}
	
	/** 
	 * Metoda ktera prevede pole intu na string oddeleny carkami.
	 * Je to udelane kvuli vypisu na obrazovku.
	 * @param array
	 * @return
	 */
	public static final String arrayToString(int[] array) {
		String result = "[ ";
		for (int i = 0; i < array.length; i++) {
			result += Integer.toString(array[i]);
			if (i < array.length - 1) {
				result += ", ";
			}
		}
		return result + " ]";
	}

	
	
	
	/**
	 * Zavola druh trideni na zadane pole intu.
	 * @param sort
	 * @param array
	 */
	public static final void testSort(Sort sort,int[] array) {
		sort.setData(array);
		sort.sort(true);
		System.out.println("Od nejmensiho: " + arrayToString(array) + " SC = " + sort.getSwapCount() + ", CC = " + sort.getCompareCount());
		sort.sort(true);
		System.out.println("Jeste jednou : " + arrayToString(array) + " SC = " + sort.getSwapCount() + ", CC = " + sort.getCompareCount());
		sort.sort(false);
		System.out.println("Od nejvetsiho: " + arrayToString(array) + " SC = " + sort.getSwapCount() + ", CC = " + sort.getCompareCount());
	}

	/**
	 * Spusti na zadanou posloupnost zvoleny druh razeni a vrati pocet 
	 * vymen ktere byli behem razeni posloupnosti provedeny
	 * @param sort
	 * @param array
	 * @return
	 */
	public static final int test2Sort(Sort sort,int[] array) {
		sort.setData(array);
		sort.sort(true);
		return sort.getSwapCount();
	}

	/**
	 * Vypise tabulku zavislosti poctu vymen prvku na poctu prvku
	 * pro nahodne generovana pole velikosti 10 - 100 pri kroku 10.
	 * Zaroven zobrazi jednoduchy graf zavislosti v novem grafickem okne.
	 */
	public static void tableAndGraph() {
		final int MAX=10;
		// Inicializuje tabulku zavislosti poctu prvku na poctu porovnavani
		int[] input,output;
		input = new int[MAX];  
		output = new int[MAX];  

		
		// Naplni tabulku na pozici 0 poctem prvku a na pozici 2 poctem porovnani
		for (int i=0; i<MAX; i++) {
			int[] array = generateRandomArray((i+1)*10);		
			input[i] = array.length;
			output[i] = test2Sort(new BubbleSort(),array);
		}
		
		// Vytiskne tabulku
		for (int j=0; j<MAX; j++) {
			System.out.println("Pocet prvku: " + input[j]);
			System.out.println("Pocet vymen: " + output[j]);
			System.out.println("------------------------");
		}	

		// Zobrazi graph
		System.out.println("Generuji graf ...");
		KresleniHistogram.doGraph(output);	
	}
		
	/**
	 * Pole ktere chci vypsat do souboru zkopiruje do noveho pole
	 * o jeden prvek delsi nez puvodni a na zacatek (prvi prvek)
	 * da delku vypisovaneho pole. 
	 * @param array
	 */
	public static void arrayToFile(int[] array) {
		int[] toFile;
		toFile = new int[array.length+1];
		toFile[0] = array.length;
		System.arraycopy(array,0,toFile,1,array.length);
		SouborIO.vystupInt(toFile);
	}

	/**
	 * Pole ktere chci nacist ze standardniho souboru 
	 * @return
	 */
	public static int[] fileToArray() {
		int[] array;
		array = SouborIO.vstupInt();		
		return array;
	}
	/**
	 * Hlavni metoda volajici postupne vsechny implementovane druhy trideni.
	 * na stejne nahodne vygenerovane pole.
	 * Je mozno ji podstrcit i jedno predpripravene polosetridene pole.
	 * @param args
	 */
	public static void main(String[] args) {

		// *** Vygeneruje tabulku zavislosti poctu prvku na poctu vymen pri BubbleSortu
		tableAndGraph();	
		
		
		
		// *** Ruzne zusoby zadani pole intu
//		int[] array = fileToArray();
//		int[] array = keyboardToArray();
//		int[] array = generateRandomArray(RANDOM_LENGHT);
        
		// *** Pripravi nova pole aby se mohla tridit stejna data
//		int[] array1 = new int[array.length];
//		System.arraycopy(array,0, array1,0,array.length);
//		int[] array2 = new int[array.length];
//		System.arraycopy(array,0, array2,0,array.length);
//		int[] array3 = new int[array.length];
//		System.arraycopy(array,0, array3,0,array.length);

		
		// *** Tady se pusti vlastni trideni 
//		System.out.println("Tridena data : " + arrayToString(array));
//		System.out.println("\nOtestuj narocnost BUBBLE sortu");
//		testSort(new BubbleSort(),array1);	
//		System.out.println("\nOtestuj narocnost SELECT sortu");
//		testSort(new SelectSort(),array2);	
//		System.out.println("\nOtestuj narocnost INSERT sortu");
//		testSort(new InsertSort(),array3);	

//		arrayToFile(array1)
//		arrayToFile(array);
		
	}

}
