/**
 * \file    tris.c
 * \brief   Fonction de tri par différentes méthodes
 * \authors LAVERGNE Rémi ; DELINAC Inès ; RAYNAUD Camille
 * \date    12 janvier 2024
*/

#include "specification1.h"

// =======================================================
// ================== TRI PAR INSERTION ==================
// =======================================================

/**
 * \brief                       Permet de trier la liste des Devis
 * \struct[out]     *ldevis      Liste des devis
*/
void trierListeDevis(ListeDevis *ldevis)
{
    ListeDevis ldevisTriee = NULL;

    while (*ldevis != NULL)
    {
        MaillonDevis* maillon = *ldevis; // Premier de la liste récuperer
        *ldevis = (*ldevis)->suiv; // -> Donc on passe au suivant (on le retire)

        insererDevisTriee(&ldevisTriee, maillon);
    }

    *ldevis = ldevisTriee;
}

/**
 * \brief                       Inserer le devis trié
 * \struct[out]     *ldevis     Liste des devis
 * \struct[out]     *maillon    Maillon de devis
*/
void insererDevisTriee(ListeDevis *ldevis, MaillonDevis *maillon)
{
    MaillonDevis* precedent = NULL;
    MaillonDevis* actuel = *ldevis;
    while (actuel != NULL && strcmp(actuel->devis.entreprise, maillon->devis.entreprise) < 0)
    {
        precedent = actuel;
        actuel = actuel->suiv;
    }

    // Si emplacement trouvé, insérer le devis
    if (precedent == NULL)
    {
        maillon->suiv = *ldevis;
        *ldevis = maillon;
    } 
    else
    {
        // Sinon on continue
        maillon->suiv = precedent->suiv;
        precedent->suiv = maillon;
    }
}


// =======================================================
// =================== TRI PAR ECHANGE ===================
// =======================================================

/**
 * \brief   Trie la liste de devis par ordre croissant du coût, puis par ordre décroissant du capital
 * \param[out]      *ldevis   Liste des devis  
*/
void triEchange(ListeDevis *ldevis)
{
    if (*ldevis == NULL || (*ldevis)->suiv == NULL)
        return;

    MaillonDevis *i, *j;
    for (i = *ldevis; i->suiv != NULL; i = i->suiv)
    {
        MaillonDevis* min = i;
        for (j = i->suiv; j != NULL; j = j->suiv)
        {
            if (comparer(&j->devis, &min->devis) < 0)
            {
                min = j;
            }
        }

        if (min != i)
        {
            inverser(&i->devis, &min->devis);
        }
    }
}

/**
 * \brief               Compare deux devis en fonction du coût et du capital
 * \param[in]   "d1"    Le premier devis
 * \param[in]   "d2"    Le deuxième devis
 * \return      <0      Si d1 < d2 
 * \return      0       Si d1 == d2
 * \return      >0      Si d1 > d2
*/
int comparer(const Devis* d1, const Devis* d2)
{
    if (d1->cout != d2->cout)
    {
        return d1->cout - d2->cout;
    }
    else
    {
        return d2->capital - d1->capital; // Si le coût est le même, on prend celui qui a le plus de capital
    }
}

/**
 * \brief                  Inverse les positions de deux devis
 * \param[in]     "d1"     Le premier devis
 * \param[in]     "d2"     Le deuxième devis
*/
void inverser(Devis* d1, Devis* d2)
{
    Devis temp = *d1;
    *d1 = *d2;
    *d2 = temp;
}

