#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "file.h"

/* Implémentation des piles par liste chaînée */

typedef struct maillon {
	int elem;
	struct maillon* suivant; // de la tete vers la queue
} maillon_t;


struct file {
	maillon_t* tete;
	maillon_t* queue;
};

file_t* file_vide(){
	printf("Création d'une file implémentée par liste chainée\n");
	file_t* f = malloc(sizeof(file_t));
	f->tete = NULL;
	f->queue = NULL;
	return f;
}

bool est_file_vide(file_t* f){
	return (f->tete == NULL);
}

void enfiler(file_t* f, int x){
	maillon_t* anc_q = f->queue;
	maillon_t* nouv_q = malloc(sizeof(maillon_t));
	
	nouv_q->elem = x;
	nouv_q->suivant = NULL;
	f->queue = nouv_q;

	if (anc_q != NULL){
		anc_q->suivant = nouv_q;
	} else {
		f->tete = nouv_q;
	}
	
}

int defiler(file_t* f){
	assert(!est_file_vide(f));
	maillon_t* anc_t = f->tete;
	int res = anc_t->elem;

	maillon_t* nouv_t = f->tete->suivant;
	f->tete = nouv_t;
	
	if (nouv_t == NULL){
		f->queue = nouv_t;
	}
	
	free(anc_t); // éviter les fuites mémoire
	return res;
}

void free_maillon(maillon_t* m){
    if (m != NULL){
        free_maillon(m->suivant);
        free(m);
    }
}

void free_file(file_t* f){
    free_maillon(f->tete);
    free(f);
}


void affiche_file(file_t* f){
	printf("Etat de la file:\n");
	for (maillon_t* m = f->tete; m != NULL; m = m->suivant){
		printf("%c ", m->elem);
	}
	printf("\n");
}