/*! 
	\file un.c
	\author GOIGOUX Lucie & JEUDI--LEMOINE Alix
	\date 22/12/22
	\brief Partie 1 de la SAE 1.02

	Application de gestion des candidature dans les IUT de France
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h> // sleep
#include <strings.h> // strcasecmp : insensitive case
#include "un.h"
#include "../II/deux.c"

void identificationCandidat(int* id, ListeCandidats* listePointer, int* nbCandidats) {
	Candidat* candidat;
	char connexion, poubelle;
	int verif;
	
	printf("\nÊtes-vous déjà enregistré (O/N) ? : ");
	scanf("%*c%c", &connexion);

	char nom[LEN_MAX];

	if(connexion == 'O' || connexion == 'o') {
		printf("\nTrès bien, merci de saisir votre ID : ");
		
		if(scanf("%d", id) == 0) {
			*id = 0;
			fprintf(stderr, "\e[0;91mErreur : cet ID n'existe pas !\n\n\e[0m");
			return;
		}

		if(*id > *nbCandidats) {
			*id = 0;
			fprintf(stderr, "\e[0;91mErreur : cet ID n'existe pas !\n\n\e[0m");
			return;
		}

		printf("Merci de confirmer votre nom de famille : ");
		scanf("%s", nom);

		if(strcasecmp(nom, (*listePointer)[*id-1]->nom) != 0) {
			*id = 0;
			fprintf(stderr, "\n\e[0;91mErreur : le nom de famille ne correspond pas !\n\n\e[0m");
			return;
		} else {
			printf("\n\e[1;92mBienvenue %s %s !\n\e[1;91m"
				   "N'oubliez pas de revenir au menu principal pour vous déconnecter à la fin de votre session !\n\n\e[0m",
				   (*listePointer)[*id-1]->prenom, (*listePointer)[*id-1]->nom);
		}
	} else {
		if(connexion == 'n' || connexion == 'N') {
			printf("\nTrès bien, nous allons donc précéder à votre enregistrement.\n\n");

			candidat = creerCandidat(); // malloc

			printf("Nom de famille : ");
			scanf("%*c%[^\n]", candidat->nom);

			printf("Prénom : ");
			scanf("%*c%[^\n]", candidat->prenom);

			printf("Moyenne de mathématiques : ");
			verif = scanf("%f", &candidat->moyenneMath);
			while((candidat->moyenneMath) < 0 || (candidat->moyenneMath) > 20 || verif == 0) {
				fprintf(stderr, "\e[0;91mLa moyenne entrée est incorrecte\n\e[0mEntrez votre moyenne de mathématiques de l'année de terminale : ");
				verif = scanf("%*c%f", &candidat->moyenneMath);
			}

			printf("Moyenne de français : ");
			verif = scanf("%f", &candidat->moyenneFrancais);
			while((candidat->moyenneFrancais) < 0 || (candidat->moyenneFrancais) > 20 || verif == 0) {
				fprintf(stderr, "\e[0;91mLa moyenne entrée est incorrecte\n\e[0mEntrez votre moyenne de français de l'année de terminale : ");
				verif = scanf("%*c%f", &candidat->moyenneFrancais);
			}
		
			printf("Moyenne de anglais : ");
			verif = scanf("%f", &candidat->moyenneAnglais);
			while((candidat->moyenneAnglais) < 0 || (candidat->moyenneAnglais) > 20 || verif == 0) {
				fprintf(stderr, "\e[0;91mLa moyenne entrée est incorrecte\n\e[0mEntrez votre moyenne de anglais de l'année de terminale : ");
				verif = scanf("%*c%f", &candidat->moyenneAnglais);
			}

			printf("Moyenne de spécialité : ");
			verif = scanf("%f", &candidat->moyenneSpecialite);
			while((candidat->moyenneSpecialite) < 0 || (candidat->moyenneSpecialite) > 20 || verif == 0) {
				fprintf(stderr, "\e[0;91mLa moyenne entrée est incorrecte\n\e[0mEntrez votre moyenne de spécialité de l'année de terminale : ");
				verif = scanf("%*c%f", &candidat->moyenneSpecialite);
			}

			ajouterCandidat(listePointer, nbCandidats, candidat); // realloc
			*id = candidat->id;

			printf("\n\n\e[1mParfait ! Votre ID est \e[1;32m%d\e[0m\e[1m, ne le perdez pas, "
				"il vous suivera tout le long de vos candidatures !\n\e[1;91m"
				"N'oubliez pas de revenir au menu principal pour vous déconnecter à la fin de votre session !\n\n\e[0m", candidat->id);
		} else {
			while ((poubelle = getchar()) != '\n' && poubelle != EOF);
			fprintf(stderr, "\n\e[0;91mLa valeur entrée est incorrecte. Merci de réessayer plus tard.\e[0m\n");
		}
	}
}

void titreMenuPrincipal(void) {
	system("clear");
	printf("\e[1;35m██████╗ ███████╗ ██████╗██████╗ ██╗   ██╗████████╗███████╗███╗   ███╗███████╗███╗   ██╗████████╗    ██╗██╗   ██╗████████╗\n");
	printf("██╔══██╗██╔════╝██╔════╝██╔══██╗██║   ██║╚══██╔══╝██╔════╝████╗ ████║██╔════╝████╗  ██║╚══██╔══╝    ██║██║   ██║╚══██╔══╝\n");
	printf("██████╔╝█████╗  ██║     ██████╔╝██║   ██║   ██║   █████╗  ██╔████╔██║█████╗  ██╔██╗ ██║   ██║       ██║██║   ██║   ██║   \n");
	printf("██╔══██╗██╔══╝  ██║     ██╔══██╗██║   ██║   ██║   ██╔══╝  ██║╚██╔╝██║██╔══╝  ██║╚██╗██║   ██║       ██║██║   ██║   ██║   \n");
	printf("██║  ██║███████╗╚██████╗██║  ██║╚██████╔╝   ██║   ███████╗██║ ╚═╝ ██║███████╗██║ ╚████║   ██║       ██║╚██████╔╝   ██║   \n");
	printf("╚═╝  ╚═╝╚══════╝ ╚═════╝╚═╝  ╚═╝ ╚═════╝    ╚═╝   ╚══════╝╚═╝     ╚═╝╚══════╝╚═╝  ╚═══╝   ╚═╝       ╚═╝ ╚═════╝    ╚═╝   \e[0m\n\n");
}

void menuCandidat(VilleIUT** tiut, ListeCandidats* listePointer, int nbVilles, int* nbCandidats) {
	// poubelle: Permet de stocker les caractères aspirés en trop sur stdin lors du choix dans le menu
	char poubelle, searchIUT[LEN_MAX], searchDept[LEN_MAX];
	Candidat* candidat;

	// choix: Contient le choix de l'utilisateur dans le menu / id: contient id user si login / status: candidatures ouvertes ou fermées
	int choix, id = 0, status = readStatus();
	char connexion;

	printf("\n\nSouhaitez-vous vous connecter/enregistrer maintenant ou entrer en mode invité (O/N) ? : ");
	scanf("%*c%c", &connexion);

	if(connexion == 'O' || connexion == 'o')
		identificationCandidat(&id, listePointer, nbCandidats);
	else
		if(connexion != 'n' && connexion != 'N') 
			while ((poubelle = getchar()) != '\n' && poubelle != EOF);
		
	if(id != 0) {
		candidat = (*listePointer)[id-1];
		printf("\e[1;94mCandidat: %s %s, ID: %d\e[0m\n", candidat->prenom, candidat->nom, id);
	} else
		printf("\n\e[1;94mInvité\e[0m\n");
	printf("-----------------------------------------------------------------------\n");
	printf("\t1 - Consulter les ville possédant un IUT\n\n");
	printf("\t2 - Voir les disponibilités des départements dans un IUT\n\n");
	printf("\t3 - Rechercher un département\n\n");
	if(id != 0) {
		if(status == 1)
			printf("\t4 - Candidater\n\n");
		printf("\t5 - Suivre sa candidature\n\n");	
	} else {
		printf("\t4 - S'identifier\n\n");
	}
	printf("\t9 - Quitter\n");
	printf("-----------------------------------------------------------------------\n");


	if(scanf("%d", &choix) == 0)
		choix=0;

	printf("-----------------------------------------------------------------------\n");
	
	while(choix != 9){
		switch (choix) {
			case 1:
				//system("clear");
				printf("Consulter les ville possédant un IUT...\n\n");
                afficherListeVilles(tiut, nbVilles);
                break;
			case 2:
                printf("Voir les disponibilités des départements dans un IUT...\n\n");
				printf("Saisissez le nom de la ville recherchée (tapez q pour annuler) : ");
				
				scanf("\n%[^\n]", searchIUT);

				if(strcasecmp(searchIUT, "q") == 0)
					break;

				afficherListeDepartement(tiut, nbVilles, searchIUT);
				break;
			case 3:
				printf("Rechercher un département...\n\n");
				printf("Saisissez le nom du département recherché (tapez q pour annuler) : ");

				scanf("\n%[^\n]", searchDept);
				
				if(strcasecmp(searchDept, "q") == 0)
					break;

				afficherDepartement(tiut, nbVilles, searchDept);
				break;
			case 4:
				if(id != 0) {
					printf("Candidater...\n\n");
					if(status == 1)
						menuCandidat_candidater(tiut, nbVilles, candidat);
					else
						fprintf(stderr, "\e[0;91mErreur : la phase de candidature est arrêtée.\n\e[0m");
				} else {
					printf("S'identifier...\n\n");
					identificationCandidat(&id, listePointer, nbCandidats);
					if(id != 0)
						candidat = (*listePointer)[id-1];
				}
					
				break;
			case 5:
				printf("Suivre sa candidature...\n\n");
				
				if(id == 0)
					fprintf(stderr, "\e[0;91mErreur : vous devez d'abord vous authentifier, merci de réessayer plus tard.\n\e[0m");
				else
					menuCandidat_suivreCandidature(*listePointer, *nbCandidats, candidat);

				break;
			default:
				// Permet d'aspirer les caractères en trop sur stdin (évite de répéter le message d'erreur X fois)
				while ((poubelle = getchar()) != '\n' && poubelle != EOF);
				fprintf(stderr, "\e[0;91mErreur : la valeur entrée est invalide, merci de réessayer.\n\e[0m");
				break;
		}

		if(id != 0)
			printf("\n\e[1;94mCandidat: %s %s, ID: %d\e[0m\n", candidat->prenom, candidat->nom, id);
		else
			printf("\n\e[1;94mInvité\e[0m\n");
		printf("-----------------------------------------------------------------------\n");
		printf("\t1 - Consulter les ville possédant un IUT\n\n");
		printf("\t2 - Voir les disponibilités des départements dans un IUT\n\n");
		printf("\t3 - Rechercher un département\n\n");
		if(id != 0) {
			if(status == 1)
				printf("\t4 - Candidater\n\n");
			printf("\t5 - Suivre sa candidature\n\n");	
		} else {
			printf("\t4 - S'identifier\n\n");
		}
		printf("\t9 - Quitter\n");
		printf("-----------------------------------------------------------------------\n");
		
		if(scanf("%d", &choix) == 0)
			choix=0;
	}

	printf("\nRetour au menu principal...\n");
}

void menuResponsable(VilleIUT** tiut, ListeCandidats liste, int nbVilles, int nbCandidats) {
	FileAttente* file;
	// poubelle: permet de stocker les caractères aspirés en trop sur stdin lors du choix dans le menu
	// pass: contient la valeur entrée par l'utilisateur lors de la saisie du mot de passe
	char poubelle, pass[LEN_MAX];
	int choix;

	printf("Merci d'entrer le mot de passe responsable : ");
	system("stty -echo");
	scanf("\n%[^\n]", pass);
	system("stty echo");

	if(strcmp(pass, "resp2023") != 0) {
		fprintf(stderr, "\n\e[1;91mErreur: mot de passe incorrect !\n\n\e[0m");
		sleep(2);
		return;
	} else
		printf("\n\n\e[1;32mMot de passe correct !\e[0m\n\n");

	/* RESET LA NOTE MINI DE TOUT DEPT
	ListeDept ldept;
	for(int caca=0; caca<*nbVilles; caca++) {
		ldept = (*tiutPointer)[caca]->ldept;

		while(ldept != NULL) {
			(*tiutPointer)[caca]->ldept->noteMinimale = -1;
			ldept = ldept->suiv;
		}
			
	}
	*/

	// Met dans le pointeur FileAttente l'adresse de la file d'attente concernant
	// le département Informatique de Clermont-Ferrand
	file = lireCandidatsAttente("Informatique", "Clermont-Ferrand");

	printf("\e[1;34mResponsable: M. BOUHOURS, IUT: Clermont-Ferrand, Département: Informatique\e[0m\n");
	printf("--------------------------------------------------------------------------\n");
	printf("\t1 - Lister les candidatures\n\n");
	printf("\t2 - Traiter les candidatures\n\n");
	printf("\t3 - Voir les candidats admis\n\n");
	printf("\t4 - Voir les candidats en file d'attente\n\n");
	printf("\t9 - Quitter\n");
	printf("--------------------------------------------------------------------------\n");

	if(scanf("%d", &choix) == 0)
		choix=0;

	printf("--------------------------------------------------------------------------\n");
	
	while(choix != 9){
		switch (choix) {
			case 1:
                printf("Lister les candidatures...\n");

				calculerNoteGlobale(liste, nbCandidats); // Calcul des notes globales avant affichage

				printf("\n\e[1;32mAffichage des candidatures triées par ordre alphabétique pour le département 'Informatique' de l'IUT 'Clermont-Ferrand'\n\n\e[0m");
				afficherCandidaturesByDept(liste, nbCandidats, "Clermont-Ferrand", "Informatique");
				break;
			case 2:
				printf("Traiter les candidatures...\n");
				
				menuResponsable_traiterCandidatures(tiut, nbVilles, liste, nbCandidats);
				file = lireCandidatsAttente("Informatique", "Clermont-Ferrand");
				break;
			case 3:
				printf("Voir les candidats admis...\n");

				printf("\n\e[1;32mAffichage des candidats admis triés par ordre alphabétique pour le département 'Informatique' de l'IUT 'Clermont-Ferrand'\n\n\e[0m");
				afficherCandidatsAdmis("Informatique", "Clermont-Ferrand");
				break;
			case 4:
				printf("Voir les candidats en liste d'attente...\n");

				printf("\n\e[1;32mAffichage des candidats en file d'attente pour le département 'Informatique' de l'IUT 'Clermont-Ferrand'\n\n\e[0m");
				afficherCandidatsAttente(file);
				break;
			default:
				// Permet d'aspirer les caractères en trop sur stdin (évite de répéter le message d'erreur X fois)
				while ((poubelle = getchar()) != '\n' && poubelle != EOF);
				fprintf(stderr, "\e[0;91mErreur : la valeur entrée est invalide, merci de réessayer.\n\n\e[0m");
				break;
		}

		printf("\e[1;34mResponsable: M. BOUHOURS, IUT: Clermont-Ferrand, Département: Informatique\e[0m\n");
		printf("--------------------------------------------------------------------------\n");
		printf("\t1 - Lister les candidatures\n\n");
		printf("\t2 - Traiter les candidatures\n\n");
		printf("\t3 - Voir les candidats admis\n\n");
		printf("\t4 - Voir les candidats en file d'attente\n\n");
		printf("\t9 - Quitter\n");
		printf("--------------------------------------------------------------------------\n");
		
		if(scanf("%d", &choix) == 0)
			choix=0;
	}

	ecrireCandidatsAttente("Informatique", "Clermont-Ferrand", file);
	printf("\nRetour au menu principal...\n");
}

void menuAdmin(VilleIUT*** tiutPointer, ListeCandidats liste, int* nbVilles, int nbCandidats) {
	// poubelle: Permet de stocker les caractères aspirés en trop sur stdin lors du choix dans le menu
	// pass: contient la valeur entrée par l'utilisateur lors de la saisie du mot de passe
	char poubelle, pass[LEN_MAX];
	// choix: Contient le choix de l'utilisateur dans le menu, status: contient le status actuel des recrutements
	int choix, status = readStatus();

	printf("Merci d'entrer le mot de passe administrateur : ");
	system("stty -echo");
	scanf("\n%[^\n]", pass);
	system("stty echo");

	if(strcmp(pass, "admin2023") != 0) {
		fprintf(stderr, "\n\e[1;91mErreur: mot de passe incorrect !\n\n\e[0m");
		sleep(2);
		return;
	} else
		printf("\n\n\e[1;32mMot de passe correct !\e[0m\n\n");

	printf("--------------------------------------------------------------------\n");
	printf("\t1 - Modifier le nombre de place d'une formation\n\n");
	printf("\t2 - Créer un nouvel IUT\n\n");
	printf("\t3 - Créer un nouveau département\n\n");
	printf("\t4 - Supprimer un département\n\n");
	if(status == 1)
		printf("\t5 - Arrêter la phase de candidature\n\n");
	else
		printf("\t5 - Lancer la phase de candidature\n\n");
	printf("\t6 - Modifier le nom du responsable d'un département\n\n");
	printf("\t7 - Liste des candidats\n\n");
	printf("\t9 - Quitter\n");
	printf("---------------------------------------------------------------------\n");

	if(scanf("%d", &choix) == 0)
		choix=0;

	printf("---------------------------------------------------------------------\n");
	
	while(choix != 9){
		switch (choix) {
			case 1:
				printf("Modifier le nombre de place d'une formation...\n\n");
				menuAdmin_modifierPlaces(*tiutPointer, *nbVilles);
                break;
			case 2:
				printf("Créer un nouvel IUT...\n\n");
				menuAdmin_creerIUT(tiutPointer, nbVilles);
				break;
			case 3:
                printf("Créer un nouveau département...\n\n");
				menuAdmin_creerDepartement(*tiutPointer, *nbVilles);
				break;
			case 4:
				printf("Supprimer un département...\n\n");
				menuAdmin_supprimerDepartement(*tiutPointer, *nbVilles);
				break;
			case 5:
				if(status == 1)
					printf("Arrêter la phase de candidature...\n\n");
				else
					printf("Lancer la phase de candidature...\n\n");
				
				saveStatus(status ? 0 : 1);
				status = (status ? 0 : 1);

				printf("\n\e[1;32mLa phase de candidature à bien été %s !\e[0m\n\n", (status ? "lancée" : "arrêtée"));
				break;
			case 6:
				printf("Modifier le nom du responsable d'un département...\n\n");
				menuAdmin_modifierResponsable(*tiutPointer, *nbVilles);
				break;
			case 7:
				printf("Liste des candidats...\n");
				printf("\n\e[4;37mListe des candidats (triés par ordre alphabétique) :\e[0m\n\n");
                afficherListeCandidats(liste, nbCandidats);
				break;
			default:
				// Permet d'aspirer les caractères en trop sur stdin (évite de répéter le message d'erreur X fois)
				while ((poubelle = getchar()) != '\n' && poubelle != EOF);
				fprintf(stderr, "\e[0;91mErreur : la valeur entrée est invalide, merci de réessayer.\n\e[0m");
				break;
		}

		printf("\n--------------------------------------------------------------------\n");
		printf("\t1 - Modifier le nombre de place d'une formation\n\n");
		printf("\t2 - Créer un nouvel IUT\n\n");
		printf("\t3 - Créer un nouveau département\n\n");
		printf("\t4 - Supprimer un département\n\n");
		if(status == 1)
			printf("\t5 - Arrêter la phase de candidature\n\n");
		else
			printf("\t5 - Lancer la phase de candidature\n\n");
		printf("\t6 - Modifier le nom du responsable d'un département\n\n");
		printf("\t7 - Liste des candidats\n\n");
		printf("\t9 - Quitter\n");
		printf("---------------------------------------------------------------------\n");
		
		if(scanf("%d", &choix) == 0)
			choix=0;
	}

	printf("\nRetour au menu principal...\n");
}

void menuPrincipal(/* TODO: prise en compte des status actuels du recrutement */) {
	char poubelle; // Permet de stocker les caractères aspirés en trop sur stdin lors du choix dans le menu
    // choix: Contient le choix de l'utilisateur dans le menu, status: contient la valeur de l'état d'ouverture des recrutements
	int choix, status = readStatus();

	// PARTIE 1
	int nbVilles = 0;
	VilleIUT** tiut = readVilles(&nbVilles);

	// PARTIE 2
	int nbCandidats = 0;
	ListeCandidats liste = readCandidats(&nbCandidats);

	titreMenuPrincipal();
	printf("--------------------------------------------\n");
	printf("Vous êtes : \n");
	printf("--------------------------------------------\n");
    printf("\t1 - Candidat\n\n");
    printf("\t2 - Administrateur\n\n");
	if(status == 0)
		printf("\t3 - Responsable\n\n");
	printf("\t9 - Quitter l'application\n");
    printf("--------------------------------------------\n");

	if(scanf("%d", &choix) == 0)
		choix=0;

	printf("-------------------------------------------------\n");
	
	while(choix != 9){
		switch (choix) {
			case 1:
				system("clear");
				printf("\e[1;34m ██████╗ █████╗ ███╗   ██╗██████╗ ██╗██████╗  █████╗ ████████╗\n");
				printf("██╔════╝██╔══██╗████╗  ██║██╔══██╗██║██╔══██╗██╔══██╗╚══██╔══╝\n");
				printf("██║     ███████║██╔██╗ ██║██║  ██║██║██║  ██║███████║   ██║   \n");
				printf("██║     ██╔══██║██║╚██╗██║██║  ██║██║██║  ██║██╔══██║   ██║   \n");
				printf("╚██████╗██║  ██║██║ ╚████║██████╔╝██║██████╔╝██║  ██║   ██║   \n");
				printf(" ╚═════╝╚═╝  ╚═╝╚═╝  ╚═══╝╚═════╝ ╚═╝╚═════╝ ╚═╝  ╚═╝   ╚═╝   \e[0m\n\n");

                menuCandidat(tiut, &liste, nbVilles, &nbCandidats);
				titreMenuPrincipal();
                break;
			case 2:
				system("clear");
				printf("\e[1;34m █████╗ ██████╗ ███╗   ███╗██╗███╗   ██╗██╗███████╗████████╗██████╗  █████╗ ████████╗███████╗██╗   ██╗██████╗ \n");
				printf("██╔══██╗██╔══██╗████╗ ████║██║████╗  ██║██║██╔════╝╚══██╔══╝██╔══██╗██╔══██╗╚══██╔══╝██╔════╝██║   ██║██╔══██╗\n");
				printf("███████║██║  ██║██╔████╔██║██║██╔██╗ ██║██║███████╗   ██║   ██████╔╝███████║   ██║   █████╗  ██║   ██║██████╔╝\n");
				printf("██╔══██║██║  ██║██║╚██╔╝██║██║██║╚██╗██║██║╚════██║   ██║   ██╔══██╗██╔══██║   ██║   ██╔══╝  ██║   ██║██╔══██╗\n");
				printf("██║  ██║██████╔╝██║ ╚═╝ ██║██║██║ ╚████║██║███████║   ██║   ██║  ██║██║  ██║   ██║   ███████╗╚██████╔╝██║  ██║\n");
				printf("╚═╝  ╚═╝╚═════╝ ╚═╝     ╚═╝╚═╝╚═╝  ╚═══╝╚═╝╚══════╝   ╚═╝   ╚═╝  ╚═╝╚═╝  ╚═╝   ╚═╝   ╚══════╝ ╚═════╝ ╚═╝  ╚═╝\e[0m\n\n");

				menuAdmin(&tiut, liste, &nbVilles, nbCandidats);
				status=readStatus();
				titreMenuPrincipal();
				break;
			case 3:
				if(status == 0) { 
					system("clear");
					printf("\e[1;34m██████╗ ███████╗███████╗██████╗  ██████╗ ███╗   ██╗███████╗ █████╗ ██████╗ ██╗     ███████╗\n");
					printf("██╔══██╗██╔════╝██╔════╝██╔══██╗██╔═══██╗████╗  ██║██╔════╝██╔══██╗██╔══██╗██║     ██╔════╝\n");
					printf("██████╔╝█████╗  ███████╗██████╔╝██║   ██║██╔██╗ ██║███████╗███████║██████╔╝██║     █████╗  \n");
					printf("██╔══██╗██╔══╝  ╚════██║██╔═══╝ ██║   ██║██║╚██╗██║╚════██║██╔══██║██╔══██╗██║     ██╔══╝  \n");
					printf("██║  ██║███████╗███████║██║     ╚██████╔╝██║ ╚████║███████║██║  ██║██████╔╝███████╗███████╗\n");
					printf("╚═╝  ╚═╝╚══════╝╚══════╝╚═╝      ╚═════╝ ╚═╝  ╚═══╝╚══════╝╚═╝  ╚═╝╚═════╝ ╚══════╝╚══════╝\e[0m\n\n");

					menuResponsable(tiut, liste, nbVilles, nbCandidats);
					titreMenuPrincipal();
				} else
					fprintf(stderr, "\e[0;91mErreur : les recrutements sont en cours, impossible d'accéder au menu responsable. Merci de réessayer plus tard.\n\n\e[0m");
				break;
			default:
				// Permet d'aspirer les caractères en trop sur stdin (évite de répéter le message d'erreur X fois)
				while ((poubelle = getchar()) != '\n' && poubelle != EOF);
				fprintf(stderr, "\e[0;91mErreur : la valeur entrée est invalide, merci de réessayer.\n\n\e[0m");
				break;
		}

		printf("--------------------------------------------\n");
		printf("Vous êtes : \n");
		printf("--------------------------------------------\n");
		printf("\t1 - Candidat\n\n");
		printf("\t2 - Administrateur\n\n");
		if(status == 0)
			printf("\t3 - Responsable\n\n");
		printf("\t9 - Quitter l'application\n");
		printf("--------------------------------------------\n");
		
		if(scanf("%d", &choix) == 0)
			choix=0;
	}

	printf("\nSauvegarde des IUT...\n");
	saveVilles(tiut, nbVilles);
	printf("Sauvegarde des Candidats...\n");
	saveCandidats(liste, nbCandidats);
    printf("\nFermeture de l'application...\n");

	free(tiut);
	free(liste);
}



// FONCTIONS MENU ADMIN

void menuAdmin_modifierPlaces(VilleIUT** tiut, int nbVilles) {
	int nbPlaces, code;
	char searchIUT[LEN_MAX], searchDept[LEN_MAX];
	printf("Entrez une ville (tapez q pour annuler) : ");
	scanf("\n%[^\n]", searchIUT);

	if(strcasecmp(searchIUT, "q") == 0)
		return;

	code = afficherListeDepartement(tiut, nbVilles, searchIUT);

	if(code != -1) {
		printf("Quel département souhaitez-vous modifier ? : ");
		scanf("\n%[^\n]", searchDept);
		printf("Entrez le nouveau nombre de places pour le département '%s' : ", searchDept);
		scanf("%d", &nbPlaces);

		modifierNbPlaces(tiut, nbVilles, searchIUT, searchDept, nbPlaces);
	}
}

void menuAdmin_creerIUT(VilleIUT*** tiutPointer, int* nbVilles) {
	VilleIUT* ville;
	char nameIUT[LEN_MAX];
	printf("Entrez le nom de la ville (tapez q pour annuler) : ");
	scanf("\n%[^\n]", nameIUT);

	if(strcasecmp(nameIUT, "q") == 0)
		return;

	ville = creerVille();
	strcpy(ville->ville, nameIUT);

	ajouterVille(tiutPointer, ville, nbVilles);

	printf("\n\e[1;32mL'IUT '%s' a bien été créé !\e[0m\n\n", nameIUT);
}

void menuAdmin_creerDepartement(VilleIUT** tiut, int nbVilles) {
	int i, nbP;
	char searchIUT[LEN_MAX], addDept[LEN_MAX], responsable[LEN_MAX];

	VilleIUT* ville;
	ListeDept ldept;
	MaillonDept* dept;

	printf("Entrez la ville dans laquelle vous souhaitez ajouter un département (tapez q pour annuler) : ");
	scanf("\n%[^\n]", searchIUT);

	if(strcasecmp(searchIUT, "q") == 0)
		return;

	i = rechercherVille(tiut, nbVilles, searchIUT);

	if(i == -1)
		fprintf(stderr, "\n\e[1;91mErreur: la ville '%s' n'est pas dans la liste des IUT.\e[0m\n\n", searchIUT);
	else {
		ville = tiut[i];

		printf("Entrez le nom du nouveau département : ");
		scanf("%*c%[^\n]", addDept);

		ldept = ville->ldept;

		if(ldept != NULL) {
			if(strcasecmp(ldept->departement, addDept) == 0) {
				fprintf(stderr, "\n\e[1;91mErreur: le département '%s' existe déjà dans l'IUT '%s'.\e[0m\n\n", addDept, searchIUT);	
				return;
			}

			while(ldept->suiv != NULL) {
				if(strcasecmp(ldept->suiv->departement, addDept) == 0) return;
				ldept = ldept->suiv;
			}

			if(ldept->suiv != NULL && strcasecmp(ldept->suiv->departement, addDept) == 0) {
				fprintf(stderr, "\n\e[1;91mErreur: le département '%s' existe déjà dans l'IUT '%s'.\e[0m\n\n", addDept, searchIUT);	
				return;
			}
		}
		

		printf("Entrez le nombre de place disponibles en 1ère année : ");
		scanf("%d", &nbP);
		printf("Entrez le nom du responsable de ce département : ");
		scanf("%*c%[^\n]", responsable);

		dept = creerDepartement(addDept, nbP, responsable);
		ville->ldept = ajouterDepartement(ville->ldept, dept);

		printf("\n\e[1;32mLe département '%s' a bien été ajouté à l'IUT '%s' !\e[0m\n\n", addDept, searchIUT);
	}
}

void menuAdmin_supprimerDepartement(VilleIUT** tiut, int nbVilles) {
	if(readStatus() == 0) {
		int i;
		char searchIUT[LEN_MAX], searchDept[LEN_MAX];

		VilleIUT* ville;

		printf("Entrez la ville dans laquelle vous souhaitez supprimer un département (tapez q pour annuler) : ");
		scanf("\n%[^\n]", searchIUT);

		if(strcasecmp(searchIUT, "q") == 0)
			return;

		i = rechercherVille(tiut, nbVilles, searchIUT);

		if(i == -1)
			fprintf(stderr, "\e[1;91mErreur: la ville '%s' n'est pas dans la liste des IUT.\e[0m\n\n", searchIUT);
		else {
			ville = tiut[i];

			afficherListeDepartement(tiut, nbVilles, searchIUT);
			
			printf("Quel département souhaitez-vous supprimer ? : ");
			scanf("%*c%[^\n]", searchDept);

			ville->ldept = supprimerDepartement(ville->ldept, searchDept);
		}
	} else {
		fprintf(stderr, "\e[1;91mErreur: vous ne pouvez pas supprimer de département pendant le recrutement/le traitement des candidatures.\e[0m\n\n");
	}
}

void menuAdmin_modifierResponsable(VilleIUT** tiut, int nbVilles) {
	int code;
	char searchIUT[LEN_MAX], searchDept[LEN_MAX], nom[LEN_MAX];
	
	printf("Dans quel IUT souhaitez-vous faire une modification ? (tapez q pour annuler) : ");
	scanf("\n%[^\n]", searchIUT);

	if(strcasecmp(searchIUT, "q") == 0)
		return;

	code = afficherListeDepartement(tiut, nbVilles, searchIUT);

	if(code != -1) {
		printf("Quel département souhaitez-vous modifier ? : ");
		scanf("\n%[^\n]", searchDept);
		
		printf("Quel est le nom du nouveau responsable : ");
		scanf("\n%[^\n]", nom);

		modifierNomResponsable(tiut, nbVilles, searchIUT, searchDept, nom);
	}
}

VilleIUT* creerVille(void) {
	VilleIUT* ville = (VilleIUT*) malloc(sizeof(VilleIUT));

	if(ville == NULL) {
		perror("malloc");
		exit(errno);
	}

	ville->ldept = creerListeDepartement();

	return ville;
}

void ajouterVille(VilleIUT*** tiutPointer, VilleIUT* ville, int* nbVilles) {
	VilleIUT** tiutNew = (VilleIUT**) realloc(*tiutPointer, (*nbVilles+1)*sizeof(VilleIUT*));

	if(tiutNew == NULL) {
        perror("realloc");
        exit(errno);
    }

	*tiutPointer = tiutNew;

	(*tiutPointer)[*nbVilles] = ville;
	*nbVilles += 1;
}

int rechercherVille(VilleIUT** tiut, int nbVilles, char* searchIUT) {
	int i=0;
	for(i=0; i<nbVilles; i++)
		if(strcasecmp(tiut[i]->ville, searchIUT) == 0)
			return i;

	return -1;
}

void afficherListeVilles(VilleIUT** tiut, int nbVilles) {
	printf("\e[4;37mListe des villes ayant un IUT disponibles :\e[0m\n\n");

	int i;
	for(i=0; i<nbVilles; i++)
		printf("  - %s\n", tiut[i]->ville);

	printf("\n\n");
}

ListeDept creerListeDepartement(void) {
	return NULL;
}

int afficherListeDepartement(VilleIUT** tiut, int nbVilles, char* searchIUT) {
	ListeDept ldept;
	int i = rechercherVille(tiut, nbVilles, searchIUT);

	if(i == -1) {
		fprintf(stderr, "\n\e[1;91mErreur: la ville '%s' n'est pas dans la liste des IUT.\e[0m\n\n", searchIUT);
		return -1;
	}

	ldept = tiut[i]->ldept;

	if(ldept == NULL)
		fprintf(stderr, "\n\e[1;91mErreur: la ville '%s' ne contient aucun département\e[0m\n\n", tiut[i]->ville);
	else {
		printf("\n\e[4;37mDépartements disponibles dans la ville '%s' :\e[0m\n\n", tiut[i]->ville);
				
		while (ldept != NULL) {
			printf("  - %s, \e[0;32m%d places disponibles\e[0m, Reponsable : %s\n", ldept->departement, ldept->nbP, ldept->responsable);
			ldept = ldept->suiv;
		}

		printf("\n");
	}

	return 1;
}

void afficherDepartement(VilleIUT** tiut, int nbVilles, char* searchDept) {
	int i, nb=0;
	ListeDept ldept, search;

	printf("\n\e[4;37mListe des IUT contenant le département '%s':\e[0m\n\n", searchDept);

	for(i=0; i<nbVilles; i++) {
		ldept = tiut[i]->ldept;

		if(ldept != NULL) {
			if(strcasecmp(ldept->departement, searchDept) == 0) {
				printf("  - %s\n", tiut[i]->ville);
				nb++;
			} else {
				search = ldept;

				while(search->suiv != NULL) {
					search = search->suiv;
					if(strcasecmp(search->departement, searchDept) == 0) {
						printf("  - %s\n", tiut[i]->ville);
						nb++;
					}
				}
			}
		}
	}

	if(nb == 0)
		fprintf(stderr, "  \e[1;91mAucun IUT ne contient ce département !\e[0m\n");

	printf("\n");
}

MaillonDept* creerDepartement(char* departement, int nbP, char* responsable) {
	MaillonDept* newDept = (MaillonDept*) malloc(sizeof(MaillonDept));

	if(newDept == NULL) {
		perror("malloc");
		exit(errno);
	}

	strcpy(newDept->departement, departement);
	newDept->nbP = nbP;
	strcpy(newDept->responsable, responsable);
	newDept->noteMinimale = -1; // Ajout Partie III

	return newDept;
}

ListeDept ajouterDepartement(ListeDept ldept, MaillonDept* dept) {
	ListeDept search = ldept;
	
	if(ldept == NULL)
		ldept = dept;
	else {
		while(search->suiv != NULL) 
			search = search->suiv;

		search->suiv = dept;
	}

	return ldept;
}

ListeDept supprimerDepartement(ListeDept ldept, char* searchDept) {
	int foundDept=0;
	ListeDept search, tmp;

	if(strcasecmp(ldept->departement, searchDept) == 0) {
		ldept = ldept->suiv;
		foundDept = 1;
	} else {
		search = ldept;

		while(search->suiv != NULL && strcasecmp(search->departement, searchDept) != 0) {
			tmp = search;
			search = search->suiv;
		}

		if(strcasecmp(search->departement, searchDept) == 0) {
			tmp->suiv = search->suiv;
			foundDept=1;
		}
	}

	if(foundDept)
		printf("\n\e[1;32mLe département '%s' a bien été supprimé !\e[0m\n\n", searchDept);
	else
		fprintf(stderr, "\n\e[1;91mErreur: la département '%s' n'existe pas.\e[0m\n\n", searchDept);

	return ldept;
}

void modifierNbPlaces(VilleIUT** tiut, int nbVilles, char* searchIUT, char* searchDept, int nb) {
	int foundDept=0, i = rechercherVille(tiut, nbVilles, searchIUT);
	ListeDept ldept, search;
	
	if(i == -1) {
		fprintf(stderr, "\n\e[1;91mErreur: la ville '%s' n'est pas dans la liste des IUT.\e[0m\n\n", searchIUT);
		return;
	}

	ldept = tiut[i]->ldept;

	if(ldept != NULL) {
		if(strcasecmp(ldept->departement, searchDept) == 0) {
			printf("\n\e[1;32mLe nombre de places de la formation '%s' à l'IUT '%s' est passé de %d à %d\e[0m\n\n", searchDept, searchIUT, ldept->nbP, nb);
			ldept->nbP = nb;
			foundDept = 1;
		} else {
			search = ldept;

			while(search->suiv != NULL) {
				search = search->suiv;
				if(strcasecmp(search->departement, searchDept) == 0) {
					printf("\n\e[1;32mLe nombre de places de la formation '%s' à l'IUT '%s' est passé de %d à %d\e[0m\n\n", searchDept, searchIUT, search->nbP, nb);
					search->nbP = nb;
					foundDept = 1;
				}
			}
		}
	}

	if(!foundDept)
		fprintf(stderr, "\n\e[1;91mErreur: le département '%s' n'a pas été trouvé dans l'IUT '%s'\e[0m\n\n", searchDept, searchIUT);
}

void modifierNomResponsable(VilleIUT** tiut, int nbVilles, char* searchIUT, char* searchDept, char* nom) {
	ListeDept ldept, search;
	int foundDept=0, i = rechercherVille(tiut, nbVilles, searchIUT);

	if(i == -1) {
		fprintf(stderr, "\n\e[1;91mErreur: la ville '%s' n'est pas dans la liste des IUT.\e[0m\n\n", searchIUT);
		return;
	}

	ldept = tiut[i]->ldept;

	if(ldept != NULL) {
		if(strcasecmp(ldept->departement, searchDept) == 0) {
			strcpy(ldept->responsable, nom);
			printf("\n\e[1;32mLe responsable de la formation '%s' à l'IUT '%s' est désormais '%s'.\e[0m\n\n", searchDept, searchIUT, ldept->responsable);
			foundDept = 1;
		} else {
			search = ldept;

			while(search->suiv != NULL) {
				search = search->suiv;
				if(strcasecmp(search->departement, searchDept) == 0) {
					strcpy(search->responsable, nom);
					printf("\n\e[1;32mLe responsable de la formation '%s' à l'IUT '%s' est désormais '%s'.\e[0m\n\n", searchDept, searchIUT, search->responsable);
					foundDept = 1;
				}
			}
		}
	}

	if(foundDept == 0)
		fprintf(stderr, "\n\e[1;91mErreur: le département '%s' n'a pas été trouvé dans l'IUT '%s'.\e[0m\n\n", searchDept, searchIUT);
}

void saveVilles(VilleIUT* tiut[], int nbVilles) {
	int i, longueurNomVille, nbDepartements, lenDepartement, lenNomResponsable;
	VilleIUT ville;
	MaillonDept* maillon;

    FILE *fe = fopen("donnees/villes.bin", "wb");

    if(fe == NULL) {
        fprintf(stderr, "\e[1;91mErreur: impossible d'écrire dans le fichier villes.don\e[0m");
        return;
    }

	fwrite(&nbVilles, sizeof(int), 1, fe);

	for (i=0; i<nbVilles; i++) {
		ville = *tiut[i];

		longueurNomVille = strlen(ville.ville)+1;
		fwrite(&longueurNomVille, sizeof(int), 1, fe);
		fwrite(ville.ville, sizeof(char), longueurNomVille, fe);

		nbDepartements = 0;
		maillon = ville.ldept;
		while (maillon != NULL) {
			nbDepartements++;
			maillon = maillon->suiv;
		}
		fwrite(&nbDepartements, sizeof(int), 1, fe);

		maillon = ville.ldept;
		while (maillon != NULL) {
			lenDepartement = strlen(maillon->departement)+1;
			fwrite(&lenDepartement, sizeof(int), 1, fe);
			fwrite(maillon->departement, sizeof(char), lenDepartement, fe);

			fwrite(&maillon->nbP, sizeof(int), 1, fe);

			lenNomResponsable = strlen(maillon->responsable)+1;
			fwrite(&lenNomResponsable, sizeof(int), 1, fe);
			fwrite(maillon->responsable, sizeof(char), lenNomResponsable, fe);

			fwrite(&maillon->noteMinimale, sizeof(int), 1, fe);

			maillon = maillon->suiv;
		}
	}

    fclose(fe);
}

VilleIUT** readVilles(int* nbVilles) {
	VilleIUT** tiut;
	VilleIUT* ville;
	MaillonDept* maillon, *maillonPrecedent;
	int i, lenNomVille, nbDepartements, lenDepartement, lenNomResponsable;

	FILE *fe = fopen("donnees/villes.bin", "rb");

    if(fe == NULL) {
        fprintf(stderr, "\e[1;91mErreur: impossible de lire le fichier villes.bin\e[0m");
        exit(1);
    }

	fread(nbVilles, sizeof(int), 1, fe);

	tiut = (VilleIUT**) malloc(*nbVilles*sizeof(VilleIUT*));

	if(tiut == NULL) {
		perror("malloc");
		exit(errno);
	}

	for (i=0; i<*nbVilles; i++) {
		ville = (VilleIUT*) malloc(sizeof(VilleIUT));

		if(ville == NULL) {
			perror("malloc");
			exit(errno);
		}

		fread(&lenNomVille, sizeof(int), 1, fe);
		fread(ville->ville, sizeof(char), lenNomVille, fe);

		fread(&nbDepartements, sizeof(int), 1, fe);

		ville->ldept = creerListeDepartement();
		maillonPrecedent = NULL;

		int j;
		for (j=0; j<nbDepartements; j++) {
			maillon = (MaillonDept*) malloc(sizeof(MaillonDept));

			if(maillon == NULL) {
				perror("malloc");
				exit(errno);
			}
			
			if(maillonPrecedent != NULL)
				maillonPrecedent->suiv = maillon;

			fread(&lenDepartement, sizeof(int), 1, fe);
			fread(maillon->departement, sizeof(char), lenDepartement, fe);

			fread(&maillon->nbP, sizeof(int), 1, fe);

			fread(&lenNomResponsable, sizeof(int), 1, fe);
			fread(maillon->responsable, sizeof(char), lenNomResponsable, fe);

			fread(&maillon->noteMinimale, sizeof(int), 1, fe);
			
			if(maillonPrecedent == NULL)
				ville->ldept = maillon;

			maillonPrecedent = maillon;
		}

		tiut[i] = ville;
	}

    fclose(fe);

    return tiut;
}