/********************************************************************************************
ShowSort.cpp
	Jim Millard
	for CO311

    Visualize Sorting

********************************************************************************************/
#include <iostream>
#include <string>
#include <time.h>
#include <ezwin.h>
#include <rect.h>

#include "ezwsort.h"

using namespace std;

sortchoice PromptAndGet();
bool YesNo(string);
void FillWithRand(int A[], const int size);
void ParseAndPrint(int A[], const int size);

int ApiMain()
    {
    int Array[MaxElements];

    cout << "This program will graphically display the performance of a variety of" << endl
         << "sorting algorithms." << endl
         << endl;
    do {
        sortchoice whichSort = PromptAndGet();
        if (whichSort == done)
            {
            Terminate();
            return 0;
            }

        int toSort = 100;
        cout << "How many numbers to sort (up to " << MaxElements << "): ";
        cin >> toSort;
        if (toSort < 2)
            return 0;

        short delayMS;
        cout << "How long should each move take (in milliseconds): ";
        cin >> delayMS;
        if (delayMS < 0)
            delayMS = 0;

        FillWithRand(Array, toSort); //setup the array with X numbers

        if (YesNo("Do you want to see the unsorted list"))
            {
            cout << "Unsorted:" << endl;
            ParseAndPrint(Array, toSort); //show the unsorted array
            Pause();
            }

        Visualize(Array, toSort, whichSort, delayMS);

        if (YesNo("Do you want to see the sorted list"))
            {
            cout << "Sorted:" << endl;
            ParseAndPrint(Array, toSort); //show the (hopefully) sorted array
            Pause();
            }
        }
    while (YesNo("Visualize Another"));

    Terminate();
    return 0;
    }

bool YesNo(string prompt)
    {
    char input;
    do {
        cout << prompt << " (Y/N)? ";
        cin >> input;
        switch (input)
            {
            case 'Y':
            case 'y':
                return true;
            case 'N':
            case 'n':
                return false;
            }
        }
    while (1);
    }

sortchoice PromptAndGet()
    {
    int menuitem = -1;
    while ((menuitem < (int)done) || (menuitem > (int)quick))
        {
        cout << "Which sort would you like to visualize: " << endl
             << '\t' << terrible << ". Super-simple" << endl
             << '\t' << bubble << ". Bubble Sort" << endl
             << '\t' << bidibubble << ". Bi-directional Bubble Sort" << endl
             << '\t' << shell << ". Shell Sort (Modified Bubble)" << endl
             << '\t' << selection << ". Selection Sort" << endl
             << '\t' << insertion << ". Insertion Sort" << endl
             << '\t' << quick << ". QuickSort" << endl
             << endl
             << '\t' << done << ". Exit the program" << endl
             << endl
             << "Choice: ";
        cin >> menuitem;
        }
    return (sortchoice)menuitem;
    }

void FillWithRand(int A[], const int size)
    {
    time_t t;
    srand((unsigned) time(&t));

    for (int i = 0; i < size; i++)
        {
        //generate the new number
        int newNumber = rand() % 10000;

        //check for duplicates (we don't want any)
        bool found = false;
        for (int j = 0; j < size; j++)
            if (A[j] == newNumber)
                {
                found = true;
                break;
                }

        //if there were no duplicates, save the number, otherwise redo the position
        if (!found)
            A[i] = newNumber;
        else
            i--;
        }

    return;
    }

void ParseAndPrint(int A[], const int size)
    {

    for (int i = 0; i < size; i++)
        {
        if (A[i] < 1000)
            cout.width(4);
        cout << A[i] << ' ';
        }
    cout << endl << endl;

    return;
    }