/*
Nome: Mario
Cognome: Montanari
Classe: 3AIN

Definire una struct livelloLinguistico che memorizzi
il livello del certificato linguistico di uno studente;
il livello è definito da una lettera e da un numero (ad
esempio: A1, B2, C2).

Creare una struct classe definita dall’anno e dalla sezione
(5F, 3C, …).

Creare una struct studente con codice numerico studente,
classe e livello linguistico.

Memorizzare 5 studenti (leggendo i dati da tastiera o casualmente)
e verificare se c’è qualche studente di una classe inferiore che ha
un livello linguistico più alto di uno studente di una classe
superiore e nel caso stamparne i dati.
*/

#include <iostream>
#include <ctime>
#include <cstdlib>

#define MIN_NUM_LIVELLO 1
#define MAX_NUM_LIVELLO 2

#define MIN_CAR_LIVELLO 65
#define MAX_CAR_LIVELLO 67

#define MIN_NUM_CLASSE 1
#define MAX_NUM_CLASSE 5

#define MIN_CAR_CLASSE 65
#define MAX_CAR_CLASSE 73

#define MIN_CODICE_STUDENTE 1000
#define MAX_CODICE_STUDENTE 9999

#define NUM_STUDENTI 5

using namespace std;

typedef struct {
	char carLivello;
	int numLivello;
} livelloLinguistico;

typedef struct {
	int numClasse;
	char carClasse;
} Classe;

typedef struct {
	int codiceStudente;
	Classe classeStudente;
	livelloLinguistico livelloStudente;
} Studente;

void riempiStruct(Studente studente[], int num_studenti);
void stampaStruct(Studente studente[], int num_studenti);
void stampaCriterio(Studente studente[], int num_studenti);

int main(void) {
	srand(time(NULL));
	Studente studente[NUM_STUDENTI];
	int num_studenti = NUM_STUDENTI;
	
	riempiStruct(studente, num_studenti);
	stampaStruct(studente, num_studenti);
	stampaCriterio(studente, num_studenti);
	
	return 0;
}

void riempiStruct(Studente studente[], int num_studenti) {
	for (int i = 0; i < num_studenti; i++) {
		studente[i].livelloStudente.carLivello = rand() % (MAX_CAR_LIVELLO - MIN_CAR_LIVELLO + 1) + MIN_CAR_LIVELLO;
		studente[i].livelloStudente.numLivello = rand() % (MAX_NUM_LIVELLO - MIN_NUM_LIVELLO + 1) + MIN_NUM_LIVELLO;
		studente[i].classeStudente.numClasse = rand() % (MAX_NUM_CLASSE - MIN_NUM_CLASSE + 1) + MIN_NUM_CLASSE;
		studente[i].classeStudente.carClasse = rand() % (MAX_CAR_CLASSE - MIN_CAR_CLASSE + 1) + MIN_CAR_CLASSE;
		studente[i].codiceStudente = rand() % (MAX_CODICE_STUDENTE - MIN_CODICE_STUDENTE + 1) + MIN_CODICE_STUDENTE;
	}
}

void stampaStruct(Studente studente[], int num_studenti) {
	for (int i = 0; i < num_studenti; i++) {
		cout << "Studente " << i + 1 << ": " << endl;
		cout << "   Codice studente: " << studente[i].codiceStudente << endl;
		cout << "   Livello linguistico: " << studente[i].livelloStudente.carLivello;
		cout << studente[i].livelloStudente.numLivello << endl;
		cout << "   Classe di studio: " << studente[i].classeStudente.numClasse;
		cout << studente[i].classeStudente.carClasse << endl << endl;
	}
}

void stampaCriterio(Studente studente[], int num_studenti) {
	cout << "Studenti di classi inferiori con livello linguistico piu' alto:" << endl;
	bool trovato = false;

	for (int i = 0; i < num_studenti; i++) {
		for (int j = 0; j < num_studenti; j++) {
			if (studente[i].classeStudente.numClasse < studente[j].classeStudente.numClasse) {
				bool livello_superiore = false;

				if (studente[i].livelloStudente.carLivello > studente[j].livelloStudente.carLivello) {
					livello_superiore = true;
				} else if (studente[i].livelloStudente.carLivello == studente[j].livelloStudente.carLivello &&
					studente[i].livelloStudente.numLivello > studente[j].livelloStudente.numLivello) {
					livello_superiore = true;
				}

				if (livello_superiore) {
					cout << "Studente " << studente[i].codiceStudente << " (" 
						<< studente[i].classeStudente.numClasse << studente[i].classeStudente.carClasse 
						<< ") con livello " << studente[i].livelloStudente.carLivello 
						<< studente[i].livelloStudente.numLivello << " supera lo studente " 
						<< studente[j].codiceStudente << " (" 
						<< studente[j].classeStudente.numClasse << studente[j].classeStudente.carClasse 
						<< ") con livello " << studente[j].livelloStudente.carLivello 
						<< studente[j].livelloStudente.numLivello << "." << endl;
						trovato = true;
				}
			}
		}
	}

	if (!trovato) {
		cout << "Nessuno studente di classe inferiore ha un livello piu' alto." << endl;
	}
}