/*
AUTORE: Manuel Vichi
Esercizio su qsort con array di struct
*/
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <iomanip>
using namespace std;

typedef struct {
    char nome;
    char cognome;
    int annoDiNascita;
} Persona;

char letteraCasuale() {
    return 'A' + rand() % 26;
}

int annoCasuale() {
    return 1990 + rand() % 21;
}

int confrontaPerCognome(const void* a, const void* b) {
    Persona* p1 = (Persona*)a;
    Persona* p2 = (Persona*)b;
    return p1->cognome - p2->cognome;
}

int confrontaPerAnnoDiNascita(const void* a, const void* b) {
    Persona* p1 = (Persona*)a;
    Persona* p2 = (Persona*)b;
    return p2->annoDiNascita - p1->annoDiNascita;
}

int confrontaPerNomeCognome(const void* a, const void* b) {
    Persona* p1 = (Persona*)a;
    Persona* p2 = (Persona*)b;
    if (p1->nome == p2->nome) {
        return p2->cognome - p1->cognome;
    }
    return p2->nome - p1->nome;
}
void stampaPersone(Persona persone[], int size) {
	cout << "Nome " << " Cognome " << " Anno di Nascita" << endl;
    for (int i = 0; i < size; ++i) {
        cout << setw(2) << persone[i].nome << ". " << setw(6) << persone[i].cognome << ". " << setw(12) << persone[i].annoDiNascita << endl;
    }
}

int main(void) {
    srand((time(NULL)));
    int size = 10;
    Persona persone[size];
    for (int i = 0; i < size; i++) {
        persone[i].nome = letteraCasuale();
        persone[i].cognome = letteraCasuale();
        persone[i].annoDiNascita = annoCasuale();
    }
    cout << "Persone prima dell'ordinamento:" << endl;
    stampaPersone(persone, size);
    qsort(persone, size, sizeof(Persona), confrontaPerCognome);
    cout << endl << "Ordinamento per cognome crescente:" << endl;
    stampaPersone(persone, size);
    qsort(persone, size, sizeof(Persona), confrontaPerAnnoDiNascita);
    cout << endl << "Ordinamento per anno di nascita decrescente:" << endl;
    stampaPersone(persone, size);
    qsort(persone, size, sizeof(Persona), confrontaPerNomeCognome);
    cout << endl << "Ordinamento per nome decrescente ed eventualmente per cognome decrescente:" << endl;
    stampaPersone(persone, size);
    return 0;
}