#include <iostream>
#include <iomanip>
#include <algorithm>
#include <windows.h>

// Werkt alleen voor Windows XP. Werkt NIET voor Windows 7

using namespace std;

LONGLONG getExecutionTime() {
    FILETIME creationTime, exitTime, kernelTime, userTime;
    if (GetProcessTimes(GetCurrentProcess(), &creationTime, &exitTime, &kernelTime, &userTime) == 0) {
        LPTSTR lpMsgBuf = 0;
        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            GetLastError(),
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            lpMsgBuf,
            0,
            NULL
        );
        cerr << lpMsgBuf << endl;
        LocalFree(lpMsgBuf);
    }
    LARGE_INTEGER utime;
    utime.LowPart = userTime.dwLowDateTime;
    utime.HighPart = userTime.dwHighDateTime;
    return utime.QuadPart;
}

class StopWatch {
public:
    StopWatch();
    void start();
    void stop();
private:
    bool running;
    LONGLONG start_time;
    LONGLONG total_time;
friend ostream& operator<<(ostream& o, const StopWatch& sw);
};

StopWatch::StopWatch(): running(false), total_time(0) {
}

void StopWatch::start() {
    if (!running) {
        running = true;
        start_time = getExecutionTime();
    }
}

void StopWatch::stop() {
    if (running) {
        running = false;
        total_time = getExecutionTime() - start_time;
    }
}

ostream& operator<<(ostream& o, const StopWatch& sw) {
    LONGLONG res = sw.running ? getExecutionTime() - sw.start_time : sw.total_time;
    return o << fixed << setprecision(2) << res / 10000000.0 << " sec";
}

void bubble_sort(int* begin, int* end) {
    for (int* p = end - 1; p != begin; --p) {
        for (int* q = begin; q != p; ++q) {
            if (*q > *(q + 1)) {
                int t = *q;
                *q = *(q + 1);
                *(q + 1) = t;
            }
        }
    }
}

int main() {
    srand(static_cast<unsigned int>(time(0)));
    int n;
    do {
        cout << "Geef N (<=0 om te stoppen): ";
        cin >> n;
        if (n > 0) {
            int* array = new int[n];
            for (int i = 0; i < n; ++i) {
                array[i] = rand();
            }
            StopWatch sw;
            sw.start();
            bubble_sort(array, array + n);
            //sort(array, array + n);
            sw.stop();
            cout << "Tijdsduur: " << sw << endl;
            delete[] array;
        }
    } while (n > 0);
}
