#ifndef CHAINE_H_
#define CHAINE_H_

/**
 * @file Chaine.h
 * Projet sem06-td-Cpp2
 * @author l'équipe pédagogique 
 * @version 1 25/01/05
 * @brief Composant de chaîne d'items à double chaînage
 * Structures de données et algorithmes - DUT1 Paris 5
 */

#include "Item.h"

/** Type Maillon avec le principe du double chaînage
 *  (maillon suivant et maillon précédent)
 */
struct Maillon {
    Item elem;			// Elément (du maillon) de la liste
    Maillon* suiv;		// Pointeur sur le maillon suivant
    Maillon* prec;		// Pointeur sur le maillon précédent
};

/** Type Chaine 
 *  Repères de début et de fin de chaîne
 *  Repère de l'élément courant
 */
 struct Chaine {
    Maillon* tete;		//Pointeur sur le maillon de tête
    Maillon* queue;		//Pointeur sur le maillon de queue
    Maillon* courant; 	//Pointeur sur le maillon courant		   		   
};

/** 
 * brief Initialisation d'une chaîne vide
 * la liste est allouée en mémoire dynamique
 * @see detruire, la liste est à désallouer en fin d’utilisation
 * @param[out] c : la chaîne
 */
void initialiser(Chaine& c);

/** 
 * brief Désallocation d'une chaîne
 * @see initialiser, la liste a déjà été allouée en mémoire dynamique
 * @param[out] c : la chaîne
 */
 void detruire(Chaine& c);

/**
 * @brief Test de chaîne vide
 * @param[in] c : la chaîne testée
 * @return true si c est vide, false sinon
 */
bool estVide(const Chaine& c);

/**
 * @brief Insertion d'un élément à l'emplacement courant de la chaîne 
 * @param[in,out] c : la chaîne
 * @param[in] elem : l'élément inséré
 */
 void inserer(Chaine& c, const Item& elem);

/**
 * @brief Suppression de l'élément à l'emplacement courant de la chaîne 
 * @param[in,out] c : la chaîne
 */
void supprimer(Chaine& c);

/**
 * @brief Ecriture d'un élément à l'emplacement courant de la chaîne 
 * @param[in,out] c : la chaîne
 * @param[in] elem : l'élément à écrire
 * @pre le maillon courant est dans la chaîne
 */
 void ecrire(Chaine& c, const Item& elem);

/**
 * @brief Lecture d'un élément à l'emplacement courant de la chaîne 
 * @param[in] c : la chaîne
 * @return l'élément lu
 * @pre le maillon courant est dans la chaîne
 */
Item lire(const Chaine& c);

/**
 * @brief Positionnement du maillon courant en début de chaîne 
 * @param[in,out] c : la chaîne
 * @pre le maillon courant est dans la chaîne
 */
void debut(Chaine& c);

/**
 * @brief Test de debut de chaine
 * @param[in] c : la chaîne testée
 * @return true si le maillon courant est le début de chaîne, false sinon
 */
bool estDebut(const Chaine& c);

/**
 * @brief Positionnement du maillon courant en fin de chaîne
 * @param[in,out] c : la chaîne
 */
void fin(Chaine& c);

/**
 * @brief Test de fin de chaîne
 * @param[in] c : la chaîne testée
 * @return true si le maillon courant est la fin de chaîne, false sinon
 */
 bool estFin(const Chaine& c);

/**
 * @brief Positionnement du maillon courant au maillon suivant
 * @param[in,out] c : la chaîne
 * @pre le maillon courant est dans la chaîne
 */
void suivant(Chaine& c);

/**
 * @brief Positionnement du maillon courant au maillon précédent
 * @param[in,out] c : la chaîne
 * @pre le maillon courant n'est pas le début de chaîne
 */
 void precedent(Chaine& c);

#endif /*CHAINE_H_*/
