/**
 * @file structuresP2.c
 * @author Antoine Perederii
 * @brief Fichier contenant les fonctions des structures de la partie 2
 */
#include "SAE.h"

/**
 * @brief Retourne une nouvelle liste vide
 *
 * @author Antoine Perederii
 * @return ListeChoix
 */
ListeChoix listenouvChoix(void)
{
    ListeChoix lc;
    lc = NULL;
    return lc;
}

/**
 * @brief Insère un choix en tête de d'une liste
 *
 * @author Antoine Perederii
 * @param lc Liste de choix dans laquelle insérer
 * @param choix Choix à insérer
 * @return ListeChoix
 */
ListeChoix insererEnTeteChoix(ListeChoix lc, Choix choix)
{
    MaillonChoix *p;
    p = (MaillonChoix *)malloc(sizeof(MaillonChoix));
    if (p == NULL)
    {
        printf("Opérations interdites !!!!\n");
        exit(1);
    }
    p->choix = choix;
    p->suiv = lc;
    return p;
}

/**
 * @brief Insère un nouveau choix dans une liste dans l'ordre alphabétique de la ville et du département
 *
 * @author Antoine Perederii
 * @param lc Liste de choix dans laquelle insérer
 * @param choix Choix à insérer
 * @return ListeChoix
 */
ListeChoix insererChoix(ListeChoix lc, Choix choix)
{
    if (videChoix(lc))
        return insererEnTeteChoix(lc, choix);
    if (strcmp(choix.ville, lc->choix.ville) < 0)
        return insererEnTeteChoix(lc, choix);
    if (strcmp(choix.ville, lc->choix.ville) == 0)
    {
        if (strcmp(choix.departement, lc->choix.departement) != 0)
            return insererEnTeteChoix(lc, choix);
        lc->choix = choix;
    }
    lc->suiv = insererChoix(lc->suiv, choix);
    return lc;
}

/**
 * @brief supprime le choix en tête d'une liste
 *
 * @author Antoine Perederii
 * @param lc Liste dans laquelle supprimer
 * @return ListeChoix
 */
ListeChoix supprimerEnTeteChoix(ListeChoix lc)
{
    MaillonChoix *aux;
    if (videChoix(lc))
    {
        printf("Opérations interdites !!!!\n");
        exit(1);
    }
    aux = lc;
    lc = lc->suiv;
    free(aux);
    return lc;
}

/**
 * @brief Supprime un choix particulier dans une liste
 *
 * @author Antoine Perederii
 * @param lc Liste dans laquelle supprimer
 * @param choix Choix à supprimer
 * @return ListeChoix
 */
ListeChoix supprimerChoix(ListeChoix lc, Choix choix)
{
    if (videChoix(lc))
        return lc;
    if (strcmp(choix.ville, lc->choix.ville) < 0)
        return lc;
    if (strcmp(choix.ville, lc->choix.ville) == 0)
    {
        if (strcmp(choix.departement, lc->choix.departement) == 0)
        {
            return supprimerEnTeteChoix(lc);
        }
    }
    return supprimerChoix(lc->suiv, choix);
}

/**
 * @brief Recherche un choix dans une liste
 *
 * @author Antoine Perederii
 * @param lc Liste de choix dans laquelle rechercher
 * @param choix Choix à rechercher
 * @return true
 * @return false
 */
bool rechercheChoix(ListeChoix lc, Choix choix)
{
    if (videChoix(lc))
        return false;
    if (strcmp(choix.ville, lc->choix.ville) < 0)
        return false;
    if (strcmp(choix.ville, lc->choix.ville) == 0)
        if (strcmp(choix.departement, lc->choix.departement) == 0)
            return true;
    return rechercheChoix(lc->suiv, lc->choix);
}

/**
 * @brief Retourne le choix en tête de liste
 *
 * @author Antoine Perederii
 * @param lc Liste de choix
 * @return Choix
 */
Choix TeteChoix(ListeChoix lc)
{
    if (videChoix(lc))
    {
        printf("Opérations interdites !!!!\n");
        exit(1);
    }
    return lc->choix;
}

/**
 * @brief Vérifie si une liste est vide
 *
 * @author Antoine Perederii
 * @param lc Liste de choix
 * @return true
 * @return false
 */
bool videChoix(ListeChoix lc)
{
    return lc == NULL;
}

/**
 * @brief Affiche tous les choix d'une liste
 *
 * @author Antoine Perederii
 * @param lc Liste de choix
 */
void afficherChoix(ListeChoix lc)
{
    while (!videChoix(lc))
    {
        afficherCandidatsChoix(TeteChoix(lc));
        lc = lc->suiv;
    }
    printf("\n");
}

/**
 * @brief Retourne la longueur d'une liste de choix
 *
 * @author Antoine Perederii
 * @param lc Liste de choix
 * @return int
 */
int longueurChoix(ListeChoix lc)
{
    int cpt = 0;
    while (!videChoix(lc))
    {
        cpt++;
        lc = lc->suiv;
    }
    return cpt;
}

/**
 * @brief Affiche un choix
 *
 * @author Antoine Perederii
 * @param choix Le choix à afficher
 */
void afficherCandidatsChoix(Choix choix)
{
    printf("Ville : %s\nDépartement : %s\nAdmission : %d\nCandidat : %d\n", choix.ville, choix.departement, choix.decisionAdmission, choix.decisionCandidat);
}

/**
 * @brief Retourne le département d'un choix
 *
 * @author Antoine Perederii
 * @param lc Liste de choix
 * @param pos Position du choix duquel on veut retourner le département
 * @return char*
 */
char *getDeptChoix(ListeChoix lc, int pos)
{
    for (int i = 0; i < pos; i++)
    {
        lc = lc->suiv;
    }
    return lc->choix.departement;
}

/**
 * @brief Retourne la ville d'un choix
 *
 * @author Antoine Perederii
 * @param lc Liste de choix
 * @param pos Position du choix duquel on veut retourner le département
 * @return char*
 */
char *getVilleChoix(ListeChoix lc, int pos)
{
    for (int i = 0; i < pos; i++)
    {
        lc = lc->suiv;
    }
    return lc->choix.ville;
}

/**
 * @brief Modifie la décision d'un département
 *
 * @author Antoine Perederii
 * @param lc Liste de choix
 * @param pos Position du choix à modifier
 * @param val Nouvelle valeur de la décision du département
 */
void setDecisionAdmission(ListeChoix lc, int pos, int val)
{
    for (int i = 0; i < pos; i++)
    {
        lc = lc->suiv;
    }
    lc->choix.decisionAdmission = val;
}

/**
 * @brief Retourne la position dans la liste de choix d'un choix recherché
 *
 * @author Antoine Perederii
 * @param lc Liste de choix
 * @param ville Ville du choix à rechercher
 * @param dept Département du choix à rechercher
 * @return int
 */
int trouverPos(ListeChoix lc, char ville[], char dept[])
{
    for (int i = 0; i < longueurChoix(lc); i++)
    {
        if (strcmp(lc->choix.ville, ville) == 0 && strcmp(lc->choix.departement, dept) == 0)
        {
            return i;
        }
    }
}