#include "struct.h"



    /*PROTOTYPES*/
void part1() ;
void part1_1_It (LSC*) ; //Paramètres : la LSC
void part1_1_Rec (LSC*, int) ; //Paramètres : la LSC, la taille de la liste
void part1_2_It (LSC*) ; //Paramètres : la LSC, la taille de la liste
void part1_2_Rec (LSC*, Maillon*, Maillon*, int) ; //Paramètres : la LSC, l'adresse du maillon anté-précédent, l'adresse du maillon précédent, la taille de la liste
void part1_3_It (LSC*) ; //Paramètres : la LSC
void part1_3_Rec (Maillon*) ; //Paramètres : le maillon à partir duquel afficher la liste



    /* MENU DE LA PARTIE 1*/
void part1()
{
    int resulScan ;
    char ItOrRec, Q1OrQ2, AffItOrRec ;

    //Création de la liste :
    LSC *liste = malloc(sizeof(*liste)) ;
    liste->first = NULL ;

    //Nettoyage de la console :
    system ("CLS") ;

    //Choix de la question (Q1 ou Q2) :
    printf ("Liste chainee de 1 a n (1) ou liste chainee de Fibonacci (2) ? ") ;
    resulScan = scanf ("%c", &Q1OrQ2) ;
    fflush (stdin) ;
    while (resulScan != 1 || ((Q1OrQ2 != '1') && (Q1OrQ2 != '2')))
    {
        printf ("\nERREUR : Entree incorrecte !\nDe 1 a n (1) ou Fibonacci (2) ? ") ;
        resulScan = scanf ("%c", &Q1OrQ2) ;
        fflush (stdin) ;
    }

    //Choix du mode itératif ou récursif :
    printf ("\n\nIteratif (i) ou recursif (r) ? ") ;
    resulScan = scanf ("%c", &ItOrRec) ;
    fflush (stdin) ;
    while (resulScan != 1 || ((ItOrRec != 'i') && (ItOrRec != 'r')))
    {
        printf ("\nERREUR : Entree incorrecte !\nIteratif (i) ou recursif (r) ? ") ;
        resulScan = scanf ("%c", &ItOrRec) ;
        fflush (stdin) ;
    }

    //Choix de la fonction d'affichage :
    printf ("\n\nFonction d'affichage iterative (i) ou recursive (r) ? ") ;
    resulScan = scanf ("%c", &AffItOrRec) ;
    fflush (stdin) ;
    while (resulScan != 1 || ((AffItOrRec != 'i') && (AffItOrRec != 'r')))
    {
        printf ("\nERREUR : Entree incorrecte !\nIteratif (i) ou recursif (r) ? ") ;
        resulScan = scanf ("%c", &AffItOrRec) ;
        fflush (stdin) ;
    }

    //Saisie de la taille de la liste par l'utilisateur :
    printf ("\n\nLongueur de la liste ? ") ;
    resulScan = scanf ("%d", &liste->taille) ;
    fflush (stdin) ;
    while ( (resulScan != 1) || (liste->taille < 1) )
    {
        printf ("\nERREUR : Entree incorrecte !\nLongueur de la liste ? ") ;
        resulScan = scanf ("%d", &liste->taille) ;
        fflush (stdin) ;
    }

    //Création de la liste demandée :
    if (Q1OrQ2 == 1)
    {
        if (ItOrRec == 'i') { part1_1_It(liste) ; } //Q1 itérative
        else { part1_1_Rec(liste, liste->taille) ; } //Q1 récursive
    }
    else
    {
        if (ItOrRec == 'i') { part1_2_It (liste) ; } //Q2 itérative
        else { part1_2_Rec (liste, NULL, NULL, liste->taille) ; } //Q2 récursive
    }

    //Affichage de la liste :
    if (AffItOrRec == 'i') { part1_3_It (liste) ; }
    else { part1_3_Rec (liste->first) ; }
}



    /*SUITE 1 A N - ITERATIF*/
void part1_1_It (LSC *liste)
{
    int i ;
    Maillon *tmp = NULL ;

    //On créé autant de maillon qu'il le faut en les plaçant en début de liste à chaque fois :
    for (i=liste->taille ; i>0 ; i--)
    {
        tmp = malloc(sizeof(Maillon)) ;
        tmp->val = i ;
        tmp->suiv = liste->first ;
        liste->first = tmp ;
    }
}



    /*SUITE 1 A N - RECURSIF*/
void part1_1_Rec (LSC *liste, int n)
{
    if (n > 0)
    {
        //On créé un maillon :
        Maillon *tmp = malloc(sizeof(Maillon)) ;
        //On lui donne la valeur de n qui se décrémente à chaque appel :
        tmp->val = n ;
        //On place le maillon en première position de la chaîne :
        tmp->suiv = liste->first ;
        //On actualise l'adresse du premier maillon de la chaîne :
        liste->first = tmp ;
        //On rappelle la fonction en décrémentant n :
        part1_1_Rec (liste, n-1) ;
    }
}



    /*FIBONACCI - ITERATIF*/
void part1_2_It (LSC *liste)
{
    int i, preprev = 0, prev = 1 ; //le compteur et les deux premiers nombres de la suite
    Maillon *currMaillon = NULL, *prevMaillon = NULL ;

    //On créé autant de maillon qu'il le faut en les plaçant en fin de liste à chaque fois :
    for (i=0 ; i<liste->taille ; i++)
    {
        //Création d'un maillon :
        if (i==0) //s'il s'agit du premier maillon
        {
            currMaillon = malloc(sizeof(Maillon)) ;
            liste->first = currMaillon ;
            currMaillon->suiv = NULL ;
        }
        else
        {
            prevMaillon = currMaillon ;
            currMaillon = malloc(sizeof(Maillon)) ;
            prevMaillon->suiv = currMaillon ;
            currMaillon->suiv = NULL ;
        }


        //Calcul de la suite de Fibonacci :
        if (i==0) { currMaillon->val = 0 ; }
        else if (i==1) { currMaillon->val = 1 ; }
        else
        {
            currMaillon->val = preprev + prev ;
            preprev = prev ;
            prev = currMaillon->val ;
        }
    }
}



    /*FIBONACCI - RECURSIF*/
void part1_2_Rec (LSC *liste, Maillon *preprevious, Maillon *previous, int n)
{
    if (n > 0)
    {
        //On créé un maillon :
        Maillon *curr = malloc(sizeof(Maillon)) ;

            //S'il s'agit du premier maillon alors... :
        if (previous == NULL)
        {
            liste->first = curr ;
            curr->suiv = NULL ;
            curr->val = 0 ;
        }
        else
        {
            previous->suiv = curr ;
            curr->suiv = NULL ;

            //S'il s'agit du second maillon alors... :
            if (preprevious == NULL) { curr->val = 1 ; }

            //Dans les autres cas... :
            else { curr->val = preprevious->val + previous->val ; }
        }
        part1_2_Rec (liste, previous, curr, n-1) ;
    }
}



    /*AFFICHAGE - ITERATIF*/
void part1_3_It (LSC *liste)
{
    if (liste == NULL)
    {
        exit(EXIT_FAILURE) ;
    }

    Maillon *curr = liste->first ;

    while (curr != NULL)
    {
        printf ("[%d] -> ", curr->val) ;
        curr = curr->suiv ;
    }
    printf ("END OF LIST\n\n") ;
    system ("PAUSE") ;
}



    /*AFFICHAGE - RECURSIF*/
void part1_3_Rec (Maillon *current)
{
    if (current != NULL)
    {
        printf ("[%d] -> ", current->val) ;
        part1_3_Rec (current->suiv) ;
    }
    else
    {
        printf ("END OF LIST\n\n") ;
        system ("PAUSE") ;
    }
}
