/**
 * @file structuresP1.c
 * @author Kyllian Chabanon
 * @brief Fichier contenant les fonctions des structures de la partie 1
 */
#include "SAE.h"

/**
 * @brief Retourne une nouvelle liste vide
 *
 * @author Kyllian Chabanon
 * @return ListeDept
 */
ListeDept listenouv(void)
{
    ListeDept l;
    l = NULL;
    return l;
}

/**
 * @brief Insère un département en tête d'une liste de départements
 *
 * @author Kyllian Chabanon
 * @param l Liste de départements
 * @param departement Nom du département à insérer
 * @param nbP Nombre de places dans le département
 * @param resp Responsable du département
 * @return ListeDept
 */
ListeDept insererEnTete(ListeDept l, char departement[], int nbP, char resp[])
{
    MaillonDept *m;
    m = (MaillonDept *)malloc(sizeof(MaillonDept));
    if (m == NULL)
    {
        printf("Fonction insererEnTete : problème malloc\n");
        exit(1);
    }
    strcpy(m->departement, departement);
    m->nbP = nbP;
    strcpy(m->resp, resp);
    m->suiv = l;
    return m;
}

/**
 * @brief Insère un département dans une liste de départements en respectant l'ordre alphabétique
 *
 * @author Kyllian Chabanon
 * @param l Liste de départements
 * @param departement Nom du département à insérer
 * @param nbP Nombre de places dans le département
 * @param resp Responsable du département
 * @return ListeDept
 */
ListeDept inserer(ListeDept l, char departement[], int nbP, char resp[])
{
    if (l == NULL)
    {
        return insererEnTete(l, departement, nbP, resp);
    }
    if (strcmp(departement, l->departement) < 0)
    {
        return insererEnTete(l, departement, nbP, resp);
    }
    if (departement == l->departement)
    {
        return l;
    }
    l->suiv = inserer(l->suiv, departement, nbP, resp);
    return l;
}

/**
 * @brief Affiche tous les départements dans une liste de départements
 *
 * @author Kyllian Chabanon
 * @param l La liste de départements
 */
void afficher(ListeDept l)
{
    if (vide(l))
    {
        printf("\n");
        return;
    }
    printf("%s\t%d\t%s\n", l->departement, l->nbP, l->resp);
    afficher(l->suiv);
}

/**
 * @brief Affiche le nom de tous départements dans une liste de départements
 *
 * @author Kyllian Chabanon
 * @param l Liste de départements
 */
void afficherDept(ListeDept l)
{
    if (vide(l))
    {
        printf("\n");
        return;
    }
    printf("\t\t%s\n", l->departement);
    afficherDept(l->suiv);
}

/**
 * @brief Vérifie si une liste est vide
 *
 * @author Kyllian Chabanon
 * @param l Liste de départements
 * @return true
 * @return false
 */
bool vide(ListeDept l)
{
    return l == NULL;
}

/**
 * @brief Recherche un département dans une liste de départements
 *
 * @author Kyllian Chabanon
 * @param l Liste de départements
 * @param departement Nom du département à rechercher
 * @param trouve Pointeur sur un booléen qui prend la valeur true si le département est trouvé et false sinon
 * @return int
 */
int rechercheDept(ListeDept l, char departement[], bool *trouve)
{
    if (vide(l))
    {
        *trouve = false;
        return 0;
    }
    if (strcmp(departement, l->departement) != 0)
    {
        *trouve = false;
        return 1 + rechercheDept(l->suiv, departement, trouve);
    }
    if (strcmp(departement, l->departement) == 0)
    {
        *trouve = true;
        return 0;
    }
    return rechercheDept(l->suiv, departement, trouve);
}

/**
 * @brief Retourne le nombre de places dans un département
 *
 * @author Kyllian Chabanon
 * @param l Liste de départements
 * @param pos Position du département duquel on veut récupérer le nombre de places
 * @return int
 */
int getNbP(ListeDept l, int pos)
{
    for (int i = 0; i < pos; i++)
    {
        l = l->suiv;
    }
    return l->nbP;
}

/**
 * @brief Modifie le nombre de places dans un département
 *
 * @author Kyllian Chabanon
 * @param l Liste de départements
 * @param pos Position du département à modifier
 * @param valeur Nouveau nombre de places dans le département
 */
void setNbP(ListeDept l, int pos, int valeur)
{
    for (int i = 0; i < pos; i++)
    {
        l = l->suiv;
    }
    l->nbP = valeur;
}

/**
 * @brief Supprime le département en tête d'une liste de départements
 *
 * @author Kyllian Chabanon
 * @param l Liste de départements
 * @return ListeDept
 */
ListeDept supprimerEnTete(ListeDept l)
{
    MaillonDept *aux;
    if (l == NULL)
    {
        printf("Opération interdite.\n");
        exit(1);
    }
    aux = l;
    l = l->suiv;
    free(aux);
    return l;
}

/**
 * @brief Supprime un département particulier d'une liste de départements
 *
 * @author Kyllian Chabanon
 * @param l Liste de départements
 * @param departement Nom du département à supprimer
 * @return ListeDept
 */
ListeDept supprimer(ListeDept l, char departement[])
{
    if (l == NULL)
    {
        return l;
    }
    if (strcmp(departement, l->departement) < 0)
    {
        return l;
    }
    if (strcmp(departement, l->departement) == 0)
    {
        return supprimerEnTete(l);
    }
    l->suiv = supprimer(l->suiv, departement);
    return l;
}

/**
 * @brief Retourne le nom du responsable d'un département
 *
 * @author Kyllian Chabanon
 * @param l Liste de départements
 * @param pos Position du département duquel on veut récupérer le nom du responsable
 * @return char*
 */
char *getResp(ListeDept l, int pos)
{
    for (int i = 0; i < pos; i++)
    {
        l = l->suiv;
    }
    return l->resp;
}

/**
 * @brief Modifie le nom du responsable d'un département
 *
 * @author Kyllian Chabanon
 * @param l Liste de départements
 * @param pos Position du département à modifier
 * @param valeur Nouveau nom du responsable
 */
void setResp(ListeDept l, int pos, char valeur[])
{
    for (int i = 0; i < pos; i++)
    {
        l = l->suiv;
    }
    strcpy(l->resp, valeur);
}

/**
 * @brief Retourne le nom d'un département
 *
 * @author Kyllian Chabanon
 * @param l Liste de départements
 * @param pos Position du département duquel on veut récupérer le nom
 * @return char*
 */
char *getDept(ListeDept l, int pos)
{
    for (int i = 0; i < pos; i++)
    {
        l = l->suiv;
    }
    return l->departement;
}

/**
 * @brief Retourne la longueur d'une liste de départements
 *
 * @author Kyllian Chabanon
 * @param l Liste de départements
 * @return int
 */
int longueur(ListeDept l)
{
    if (vide(l))
    {
        return 0;
    }
    return 1 + longueur(l->suiv);
}