/*! 
	\file deux.c
	\author GOIGOUX Lucie & JEUDI--LEMOINE Alix
	\date 23/12/22
	\brief Partie 2 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 "deux.h"
#include "../III/trois.c"


Candidat* creerCandidat(void) {
    Candidat* candidat = (Candidat*) malloc(sizeof(Candidat));

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

    return candidat;
}

Candidature* creerCandidature(void) {
    Candidature* candid = (Candidature*) malloc(sizeof(Candidature));

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

    candid->decision = 0;
    candid->validation = 0;
    return candid;
}

void ajouterCandidat(ListeCandidats* listePointer, int* nbCandidats, Candidat* candidat) {
    ListeCandidats listeNew = (ListeCandidats) realloc(*listePointer, (*nbCandidats+1)*sizeof(Candidat*));
    
    if(listeNew == NULL) {
        perror("realloc");
        exit(errno);
    }

    *listePointer = listeNew;

    *nbCandidats+=1;
    candidat->id = *nbCandidats;
    (*listePointer)[*nbCandidats-1] = candidat;
}

void ajouterCandidature(Candidat* candidat, Candidature* candidature) {
    candidat->listeCandidatures = (ListeCandidatures) realloc(candidat->listeCandidatures, (candidat->nbCandidatures+1)*sizeof(Candidature*));
    candidat->listeCandidatures[candidat->nbCandidatures] = candidature;
    candidat->nbCandidatures+=1;
}

void menuCandidat_candidater(VilleIUT** tiut, int nbVilles, Candidat* candidat) {
    int found = 0;
    ListeDept liste;
	Candidature* candid = creerCandidature();

	char searchIUT[LEN_MAX], searchDept[LEN_MAX];
	printf("Entrez la ville dans laquelle vous souhaitez candidater : ");
	scanf("%s", searchIUT);

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

	int 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);
		return;
	}

	printf("Entrez le département dans lequel vous souhaitez candidater : ");
	scanf("%*c%[^\n]", searchDept);

	liste = tiut[i]->ldept;

	if(strcmp(liste->departement, searchDept) == 0)
		found=1;

	while(liste->suiv != NULL) {
		liste = liste->suiv;
		if(strcmp(liste->departement, searchDept) == 0)
			found=1;
	}

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

	strcpy(candid->ville, searchIUT);
	strcpy(candid->departement, searchDept);

	if(checkCandidature(candidat, *candid) == -1) {
		fprintf(stderr, "\n\e[1;91mErreur: vous avez déjà candidaté pour le département '%s' dans l'IUT '%s'.\e[0m\n\n", searchDept, searchIUT);
		return;
	}

	ajouterCandidature(candidat, candid);

	printf("\n\e[1;32mVotre candidature au département '%s' à l'IUT '%s' a bien été prise en compte !\e[0m\n\n", searchDept, searchIUT);
}

int checkCandidature(Candidat* candidat, Candidature candid) {
    int i, nbCandidatures = candidat->nbCandidatures;

    for(i=0; i<nbCandidatures; i++)
        if(strcmp(candidat->listeCandidatures[i]->ville, candid.ville) == 0)
            if(strcmp(candidat->listeCandidatures[i]->departement, candid.departement) == 0)
                return -1;

    return 0;
}

void afficherListeCandidats(ListeCandidats liste, int nbCandidats) {
    Candidat* candidat;
    ListeCandidats liste2 = (ListeCandidats) malloc(nbCandidats*sizeof(Candidat*));

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

    for (int i=0; i<nbCandidats; i++) {
        memcpy(&liste2[i], &liste[i], sizeof(Candidat*));
    }
    
    qsort(liste2, nbCandidats, sizeof(Candidat*), compareCandidats);

    for(int i=0; i<nbCandidats; i++) {
        candidat = liste2[i];

        afficherCandidat(candidat);
    }

    free(liste2);
}

void afficherCandidat(Candidat* candidat) {
    printf("Candidat n°%d, '%s %s' :"
           "\n  - Moyenne en mathématiques : %.2f\n  - Moyenne en français : %.2f"
           "\n  - Moyenne en anglais : %.2f\n  - Moyenne en spécialité : %.2f"
           "\n  - Nombre de candidatures : %d\n\n",
           candidat->id, candidat->nom, candidat->prenom,
           candidat->moyenneMath, candidat->moyenneFrancais,
           candidat->moyenneAnglais, candidat->moyenneSpecialite,
           candidat->nbCandidatures);
}

void afficherCandidatures(ListeCandidatures candidatures, int nbCandidatures) {
    if(nbCandidatures == 0) return;

    char decision[LEN_MAX], validation[LEN_MAX];
    Candidature* candidature = candidatures[nbCandidatures-1];

    switch (candidature->decision) {
        case 0:
            strcpy(decision, "en cours de traitement");
            break;
        case 1:
            strcpy(decision, "admis");
            break;
        case -1:
            strcpy(decision, "refusé");
            break;
        case 2:
            strcpy(decision, "sur liste d'attente");
            break;
        default:
            break;
    }

    switch (candidature->validation) {
        case 0:
            strcpy(validation, "n'a pas encore décidé");
            break;
        case 1:
            strcpy(validation, "accepte la proposition");
            break;
        case -1:
            strcpy(validation, "refuse la proposition");
            break;
        default:
            break;
    }

    if(candidature->validation == -1)
        printf("\n\e[4;37m\e[3mCandidature pour le département '%s' à l'IUT '%s' :\n\e[0m"
            "\e[3m  - Décision du département : %s,\n  - Décision du candidat : %s\e[0m\n\n",
            candidature->departement, candidature->ville, decision, validation);
    else {
        if(candidature->validation == 1)
            printf("\n\e[4;37m\e[1mCandidature pour le département '%s' à l'IUT '%s' :\n\e[0m"
            "\e[1m  - Décision du département : %s,\n  - Décision du candidat : %s\n\n\e[0m",
            candidature->departement, candidature->ville, decision, validation);
        else
            printf("\n\e[4;37mCandidature pour le département '%s' à l'IUT '%s' :\n\e[0m"
            "  - Décision du département : %s,\n  - Décision du candidat : %s\n\n\e[0m",
            candidature->departement, candidature->ville, decision, validation);
    }

    afficherCandidatures(candidatures, nbCandidatures-1);
}

/* Fonction originale sans récursivité
void afficherCandidatures_sansRecursif(Candidat* candidat) {
    int nbCandidatures = candidat->nbCandidatures;

    for(int i=0; i<nbCandidatures; i++) {
        char decision[LEN_MAX], validation[LEN_MAX];
        Candidature* candidature = candidat->listeCandidatures[i];

        switch (candidature->decision) {
            case 0:
                strcpy(decision, "en cours de traitement");
                break;
            case 1:
                strcpy(decision, "admis");
                break;
            case -1:
                strcpy(decision, "refusé");
                break;
            case 2:
                strcpy(decision, "sur liste d'attente");
                break;
            default:
                break;
        }

        switch (candidature->validation) {
            case 0:
                strcpy(validation, "n'a pas encore décidé");
                break;
            case 1:
                strcpy(validation, "refuse la proposition");
                break;
            case -1:
                strcpy(validation, "accepte");
                break;
            default:
                break;
        }

        printf("Candidature pour le département '%s' à l'IUT '%s' : \n"
               "  - Décision du département : %s,\n  - Décision du candidat : %s\n\n",
               candidature->departement, candidature->ville, decision, validation);
    }

    if(nbCandidatures == 0)
        fprintf(stderr, "\e[0;91mErreur : vous n'avez aucune candidature en cours, merci de réessayer plus tard.\n\e[0m");
}*/

ListeCandidats readCandidats(int* nbCandidats) {
    int i, j;
    Candidat* candidat;
    Candidature* candidature;
    ListeCandidats liste;
    ListeCandidatures listeCandidatures;

    FILE *fe = fopen("donnees/candidats.don", "r");

    if(fe == NULL) {
        fprintf(stderr, "Erreur: impossible de lire le fichier candidats.don");
        return NULL;
    }

    fscanf(fe, "%d", nbCandidats);

    liste = (ListeCandidats) malloc(*nbCandidats*sizeof(Candidat*));

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

    for(i=0; i<*nbCandidats; i++) {
        candidat = creerCandidat();
        fscanf(fe, "%d\n%[^\n]\n%[^\n]\n%f\n%f\n%f\n%f\n%d",
                   &candidat->id, candidat->nom, candidat->prenom,
                   &candidat->moyenneMath, &candidat->moyenneFrancais,
                   &candidat->moyenneAnglais, &candidat->moyenneSpecialite,
                   &candidat->nbCandidatures);

        listeCandidatures = (ListeCandidatures) malloc(candidat->nbCandidatures*sizeof(Candidature*));

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

        candidat->listeCandidatures = listeCandidatures;

        for(j=0; j<candidat->nbCandidatures; j++) {
            candidature = (Candidature*) malloc(sizeof(Candidature));

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

            fscanf(fe, "\n%[^\n]\n%[^\n]\n%d%d",
                       candidature->ville, candidature->departement,
                       &candidature->decision, &candidature->validation);
            candidat->listeCandidatures[j] = candidature;
        }

        liste[i] = candidat;
    }

    return liste;
}

int compareCandidats(const void* p1, const void* p2) {
    Candidat* c1 = *(ListeCandidats) p1;
    Candidat* c2 = *(ListeCandidats) p2;

    char nomComplet1[60], nomComplet2[60];
    strcpy(nomComplet1, c1->nom);
    strcat(nomComplet1, c1->prenom);

    strcpy(nomComplet2, c2->nom);
    strcat(nomComplet2, c2->prenom);

    return strcmp(nomComplet1, nomComplet2);
}

int saveCandidats(ListeCandidats liste, int nbCandidats) {
    int i, j;
    Candidat* candidat;
    Candidature* candidature;
    ListeCandidatures listeCandidatures;

    FILE *fe = fopen("donnees/candidats.don", "w");

    if(fe == NULL) {
        fprintf(stderr, "Erreur: impossible de lire le fichier candidats.don");
        return -1;
    }

    fprintf(fe, "%d", nbCandidats);

    for(i=0; i<nbCandidats; i++) {
        candidat = liste[i];

        fprintf(fe, "\n%d\n%s\n%s\n%f\t%f\t%f\t%f\n%d",
                   candidat->id, candidat->nom, candidat->prenom,
                   candidat->moyenneMath, candidat->moyenneFrancais,
                   candidat->moyenneAnglais, candidat->moyenneSpecialite,
                   candidat->nbCandidatures);

        listeCandidatures = candidat->listeCandidatures;

        for(j=0; j<candidat->nbCandidatures; j++) {
            candidature = listeCandidatures[j];
            fprintf(fe, "\n%s\n%s\n%d\n%d",
                       candidature->ville, candidature->departement,
                       candidature->decision, candidature->validation);
        }
    }

    fclose(fe);
    
    return 0;
}

int readStatus(void) {
	int status;

	FILE *fe = fopen("donnees/status.don", "r");
	
	if(fe == NULL) {
		perror("fopen");
		exit(errno);
	}

	fscanf(fe, "%d", &status);

	fclose(fe);

	return status;
}

void saveStatus(int status) {
	FILE *fe = fopen("donnees/status.don", "w");
	
	if(fe == NULL) {
		perror("fopen");
		exit(errno);
	}

	fprintf(fe, "%d", status);

	fclose(fe);
}