/** 
    FILE:           Sorts.java
    AUTHOR:         Cheng, Jeff
    LAST CHANGE:    3-22-02
    PURPOSE:        The sorts package provides 5 different sorting algorithms
                    for working with an array (other data structures may be
                    used, with appropriate modifications.)
                    Selection sort, insertion sort, quick sort, merge sort,
                    and heap sort.
                    BONUS:  find the kth largest element in an array, using
                            an algorithm that resembles quick sort.
    
    Note:           I could have use functions to retrieve/modify the
                    private integer array, but function calls can be expensive
                    in sorting or sorting-like (selection; find kth largest)
                    algorithms, so I've avoid such uses.
                    
    COPYRIGHT:      You may use, modify, or distribute my code for 
                    non-commerical use only; you must cite me, Jeff Cheng, 
                    as the source. 
*/

package sorts;

import javax.swing.*;

public class Sorts{
    public static void main(String args[]){
        
        boolean again = false;
        do{
            System.out.println("\n\n\t This program provides five different" +
                               " algorithms to sort an array.\n" +
                               "\t You will need to specify the following:\n" +
                               "\t array size? array presorted? & show result?" +
                               "\n\t If you choose to find the kth element," +
                               " you also need to specify k.\n" +
                               "\t If you choose insertion sort, you will need" +
                               " to decide sort by iteration\t or recursion.\n\n" +
                               "\t Choose from the following:\n" +
                               "\t 0 for find kth largest element\n" +
                               "\t 1 for selection sort\n" +
                               "\t 2 for insertion sort\n" +
                               "\t 3 for quick sort\n" +
                               "\t 4 for merge sort\n" +
                               "\t 5 for heap sort\n" +
                               "\t Note this program is intended" + 
                               " as a console application:\n" +
                               "\t printing is **not** recommended!\n" +
                               "\t All other input quits the program.\n");
                               
            String userChoice = JOptionPane.showInputDialog
                                ("\t What would you like to do?");
        
            int chosen = 0;
            
            try{
                chosen = Integer.parseInt(userChoice);                            
            }catch(NumberFormatException e){
                again = false;
            };

            boolean sizeIsNumber = true;
            boolean rankIsNumber = true;   //  the kth rank
            String kthRank = "";
            String size = "";
            String wantPresorted = "";  //  user want presorted array?
            String wantPrintArray = ""; //  user want array printed?
            String initialArrayCondition = "";
            String wantIterativeInsertion = ""; //  user want iteratively?
            int arraySize = 0;
            int theKthLargestElement = 0;
            boolean presorted = false;  //  array is presorted?
            boolean printIt = false;    //  print array after sort?
            boolean iterative = false;  //  insertion iteratively?
            int holdDecision = 0;   //  just a temp variable

            switch(chosen){
                case 0:
                //  get array size                                    
                do{
                    sizeIsNumber = true;                        
                    size = JOptionPane.showInputDialog
                             ("\t What array size would you like?" +
                              "\t Array size must be a positive number.\n");
                    try{
                        arraySize = Integer.parseInt(size);                                                  
                        }catch (NumberFormatException e){
                            sizeIsNumber = false;}
                }while ((!sizeIsNumber)||(arraySize < 1));

                //  array sorted to start with?
                wantPresorted = JOptionPane.showInputDialog
                                ("\t Would you like a presorted array?" +
                                 "\t (1 for presorted, unsorted otherwise.)\n");
                try{
                    holdDecision = Integer.parseInt(wantPresorted);                                                  
                    }catch (NumberFormatException e){}
                    
                if (holdDecision == 1){
                    presorted = true;
                    } else {
                    presorted = false;
                    }
                    
                //  show result?
                wantPrintArray = JOptionPane.showInputDialog
                                ("\t Would you like the array printed after?" +
                                 "\t (1 for yes, no otherwise.\n");
                try{
                    holdDecision = Integer.parseInt(wantPrintArray);                                                  
                    }catch (NumberFormatException e){}
                    
                if (holdDecision == 1){
                    printIt = true;
                    } else {
                    printIt = false;
                    }
                
                //  what element do you want to find?
                do{
                    rankIsNumber = true;                        
                    kthRank = JOptionPane.showInputDialog
                                ("\t Specify the kth largest element to find." +
                                 "\t K must be a non-negative number & " +
                                 "<= arraysize-1.");
                
                    try{
                        theKthLargestElement = Integer.parseInt(kthRank);                                                  
                        }catch (NumberFormatException e){
                            rankIsNumber = false;}
                    }while ((!rankIsNumber)||(theKthLargestElement <= 0)||
                            (theKthLargestElement > (arraySize-1)));
                
                //  just for information
                if (presorted){
                    initialArrayCondition = "Array presorted to start.";
                    } else {
                    initialArrayCondition = "Array unsorted to start.";    
                    }

                System.out.println("\t You chose to find the kth largest" +
                                   " element in the array.\n" +
                                   "\t " + initialArrayCondition + "\n" +
                                   "\t The array size is " + arraySize + 
                                   "\n\t You chose to find the " + +
                                   theKthLargestElement + "th element.");
                                   
                FindKthLargest.createAndFind
                    (arraySize, presorted, theKthLargestElement, printIt);
        
                again = true;
                break;
        
                case 1:
                //  get array size                                    
                do{
                    sizeIsNumber = true;                        
                    size = JOptionPane.showInputDialog
                             ("\t What array size would you like?" +
                              "\t Array size must be a positive number.\n");
                    try{
                        arraySize = Integer.parseInt(size);                                                  
                        }catch (NumberFormatException e){
                            sizeIsNumber = false;}
                }while ((!sizeIsNumber)||(arraySize < 1));

                //  array sorted to start with?
                wantPresorted = JOptionPane.showInputDialog
                                ("\t Would you like a presorted array?" +
                                 "\t (1 for presorted, unsorted otherwise.)\n");
                try{
                    holdDecision = Integer.parseInt(wantPresorted);                                                  
                    }catch (NumberFormatException e){}
                    
                if (holdDecision == 1){
                    presorted = true;
                    } else {
                    presorted = false;
                    }
                    
                //  show result?
                wantPrintArray = JOptionPane.showInputDialog
                                ("\t Would you like the array printed after?" +
                                 "\t (1 for yes, no otherwise.\n");
                try{
                    holdDecision = Integer.parseInt(wantPrintArray);                                                  
                    }catch (NumberFormatException e){}
                    
                if (holdDecision == 1){
                    printIt = true;
                    } else {
                    printIt = false;
                    }
                
                //  just for information
                if (presorted){
                    initialArrayCondition = "Array presorted to start.";
                    } else {
                    initialArrayCondition = "Array unsorted to start.";    
                    }

                System.out.println("\t You chose selection sort\n" +
                                   "\t " + initialArrayCondition + "\n" +
                                   "\t The array size is " + arraySize + 
                                   "\n");
                                   
                SelectionSort.createAndSort(arraySize, presorted, printIt);
        
                again = true;
                break;
                
                case 2:
                //  get array size                                    
                do{
                    sizeIsNumber = true;                        
                    size = JOptionPane.showInputDialog
                             ("\t What array size would you like?" +
                              "\t Array size must be a positive number.\n");
                    try{
                        arraySize = Integer.parseInt(size);                                                  
                        }catch (NumberFormatException e){
                            sizeIsNumber = false;}
                }while ((!sizeIsNumber)||(arraySize < 1));

                //  array sorted to start with?
                wantPresorted = JOptionPane.showInputDialog
                                ("\t Would you like a presorted array?" +
                                 "\t (1 for presorted, unsorted otherwise.)\n");
                try{
                    holdDecision = Integer.parseInt(wantPresorted);                                                  
                    }catch (NumberFormatException e){}
                    
                if (holdDecision == 1){
                    presorted = true;
                    } else {
                    presorted = false;
                    }
                    
                //  show result?
                wantPrintArray = JOptionPane.showInputDialog
                                ("\t Would you like the array printed after?" +
                                 "\t (1 for yes, no otherwise.\n");
                try{
                    holdDecision = Integer.parseInt(wantPrintArray);                                                  
                    }catch (NumberFormatException e){}
                    
                if (holdDecision == 1){
                    printIt = true;
                    } else {
                    printIt = false;
                    }
                
                //  iterative insertion sort?
                wantIterativeInsertion = JOptionPane.showInputDialog
                                ("\t Insertion sort iteratively?" +
                                 "\t 1 for yes, no otherwise.\n");
                                 
                try{
                    holdDecision = Integer.parseInt(wantIterativeInsertion);
                }catch (NumberFormatException e){}
                
                if (holdDecision ==1){
                    iterative = true;
                    }else {
                    iterative = false;
                        }
                        
                //  just for information
                if (presorted){
                    initialArrayCondition = "Array presorted to start.";
                    } else {
                    initialArrayCondition = "Array unsorted to start.";    
                    }

                System.out.println("\t You chose insertion sort\n" +
                                   "\t " + initialArrayCondition + "\n" +
                                   "\t The array size is " + arraySize + 
                                   "\n");
                                   
                InsertionSort.createAndSort
                    (arraySize, presorted, printIt, iterative);
        
                again = true;
                break;
                
                case 3:
                //  get array size                                    
                do{
                    sizeIsNumber = true;                        
                    size = JOptionPane.showInputDialog
                             ("\t What array size would you like?" +
                              "\t Array size must be a positive number.\n");
                    try{
                        arraySize = Integer.parseInt(size);                                                  
                        }catch (NumberFormatException e){
                            sizeIsNumber = false;}
                }while ((!sizeIsNumber)||(arraySize < 1));

                //  array sorted to start with?
                wantPresorted = JOptionPane.showInputDialog
                                ("\t Would you like a presorted array?" +
                                 "\t (1 for presorted, unsorted otherwise.)\n");
                try{
                    holdDecision = Integer.parseInt(wantPresorted);                                                  
                    }catch (NumberFormatException e){}
                    
                if (holdDecision == 1){
                    presorted = true;
                    } else {
                    presorted = false;
                    }
                    
                //  show result?
                wantPrintArray = JOptionPane.showInputDialog
                                ("\t Would you like the array printed after?" +
                                 "\t (1 for yes, no otherwise.\n");
                try{
                    holdDecision = Integer.parseInt(wantPrintArray);                                                  
                    }catch (NumberFormatException e){}
                    
                if (holdDecision == 1){
                    printIt = true;
                    } else {
                    printIt = false;
                    }
                
                //  just for information
                if (presorted){
                    initialArrayCondition = "Array presorted to start.";
                    } else {
                    initialArrayCondition = "Array unsorted to start.";    
                    }

                System.out.println("\t You chose quick sort\n" +
                                   "\t " + initialArrayCondition + "\n" +
                                   "\t The array size is " + arraySize + 
                                   "\n");
                                   
                QuickSort.createAndSort(arraySize, presorted, printIt);
        
                again = true;
                break;
                
                case 4:
                //  get array size                                    
                do{
                    sizeIsNumber = true;                        
                    size = JOptionPane.showInputDialog
                             ("\t What array size would you like?" +
                              "\t Array size must be a positive number.\n");
                    try{
                        arraySize = Integer.parseInt(size);                                                  
                        }catch (NumberFormatException e){
                            sizeIsNumber = false;}
                }while ((!sizeIsNumber)||(arraySize < 1));

                //  array sorted to start with?
                wantPresorted = JOptionPane.showInputDialog
                                ("\t Would you like a presorted array?" +
                                 "\t (1 for presorted, unsorted otherwise.)\n");
                try{
                    holdDecision = Integer.parseInt(wantPresorted);                                                  
                    }catch (NumberFormatException e){}
                    
                if (holdDecision == 1){
                    presorted = true;
                    } else {
                    presorted = false;
                    }
                    
                //  show result?
                wantPrintArray = JOptionPane.showInputDialog
                                ("\t Would you like the array printed after?" +
                                 "\t (1 for yes, no otherwise.\n");
                try{
                    holdDecision = Integer.parseInt(wantPrintArray);                                                  
                    }catch (NumberFormatException e){}
                    
                if (holdDecision == 1){
                    printIt = true;
                    } else {
                    printIt = false;
                    }
                
                //  just for information
                if (presorted){
                    initialArrayCondition = "Array presorted to start.";
                    } else {
                    initialArrayCondition = "Array unsorted to start.";    
                    }

                System.out.println("\t You chose merge sort\n" +
                                   "\t " + initialArrayCondition + "\n" +
                                   "\t The array size is " + arraySize + 
                                   "\n");
                                   
                MergeSort.createAndSort(arraySize, presorted, printIt);
        
                again = true;
                break;
                
                case 5:
                //  get array size                                    
                do{
                    sizeIsNumber = true;                        
                    size = JOptionPane.showInputDialog
                             ("\t What array size would you like?" +
                              "\t Array size must be a positive number.\n");
                    try{
                        arraySize = Integer.parseInt(size);                                                  
                        }catch (NumberFormatException e){
                            sizeIsNumber = false;}
                }while ((!sizeIsNumber)||(arraySize < 1));

                //  array sorted to start with?
                wantPresorted = JOptionPane.showInputDialog
                                ("\t Would you like a presorted array?" +
                                 "\t (1 for presorted, unsorted otherwise.)\n");
                try{
                    holdDecision = Integer.parseInt(wantPresorted);                                                  
                    }catch (NumberFormatException e){}
                    
                if (holdDecision == 1){
                    presorted = true;
                    } else {
                    presorted = false;
                    }
                    
                //  show result?
                wantPrintArray = JOptionPane.showInputDialog
                                ("\t Would you like the array printed after?" +
                                 "\t (1 for yes, no otherwise.\n");
                try{
                    holdDecision = Integer.parseInt(wantPrintArray);                                                  
                    }catch (NumberFormatException e){}
                    
                if (holdDecision == 1){
                    printIt = true;
                    } else {
                    printIt = false;
                    }
                
                //  just for information
                if (presorted){
                    initialArrayCondition = "Array presorted to start.";
                    } else {
                    initialArrayCondition = "Array unsorted to start.";    
                    }

                System.out.println("\t You chose heap sort\n" +
                                   "\t " + initialArrayCondition + "\n" +
                                   "\t The array size is " + arraySize + 
                                   "\n");
                                   
                HeapSort.createAndSort(arraySize, presorted, printIt);
        
                again = true;
                break;

                default:
                System.out.println("\t You chose to quit.  Thank you!");
                again = false;
                break;
                }   //  end of switch
            } while (again);    //  end of do-while
        
    System.exit(0);
    }
}