/*
 * Cours Langage C - AIR1
 * C. Recanati 27/08/2019 12:43
 * TP4 exo2
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>		/* pour les erreurs */
#include <string.h>		/* pour les chaines de caracteres */

/* les tailles de lignes et le nombre maximum de lignes */
/* d'un fichier lu */
#define MAX_SIZE_LINE 240
#define MAXLINE	300

/* pour les listes chainees de mots */
struct s_mot {
	char * mot; 
	struct s_mot *suivant;
} ;	
typedef struct s_mot element; 
typedef  element*  liste_mots;

/* les fonctions sur les listes */
void afficheListeMots(liste_mots list);	
element * newElem(char * mot);
liste_mots addBegin(liste_mots ls, element* nouv); /* ajout en tete de liste */
liste_mots addEnd(liste_mots ls, element* nouv); /* ajout en queue de liste */

/* creation d'une liste de mots a partir d'un char ligne[] (lu dans le fichier) */
liste_mots creer(char ligne[], int n);

/* variables globales au fichier */
char nom_fichier[40];		/* pour ouvrir un fichier */
FILE *fichier;

char ligne[MAX_SIZE_LINE]; /* ligne[] pour lire les lignes du fichier */
liste_mots tab[MAXLINE];	/* tableau tab pour stocker les listes de mots */

int nb_line=0;	/* nb de lignes lues */


int main() {	
 	char *s; 	
	liste_mots  liste = NULL;

/* ouverture du fichier */
	printf("Entrez un nom de fichier texte: ");
	scanf("%s", nom_fichier);
 	fichier = fopen(nom_fichier, "r");
 	if (fichier == NULL) {
 		printf("impossible d'ouvrir %s ! erreur %d: %s\n", 
 					nom_fichier, errno, strerror(errno));
 		return errno;
 	}
 		
/* allocation de char *s pour lire une ligne, et initialisation de ligne[] */
	s = (char *) malloc(sizeof(char) * MAX_SIZE_LINE);
	ligne[MAX_SIZE_LINE-1]='\0';
	
 /* creer une liste de mots pour chaque ligne lue, et la mettre dans tab */
	while ((s = fgets(ligne, MAX_SIZE_LINE, fichier)) != 0) {
		/* pour chaque ligne du fichier */
		ligne[strlen(ligne)-1] = '\0';
		liste = creer(ligne, strlen(ligne));
		tab[nb_line++] = liste;
	}
	
//	tab[nb_line] = NULL; inutile ici car on connait le nb de ligne nb_line
	for(int i=0; i < nb_line; i++)
		afficheListeMots(tab[i]);
	
	if (fclose(fichier) == EOF)
		printf("erreur de fermeture du fichier %s\n", nom_fichier);
	return EXIT_SUCCESS;
}

liste_mots creer(char ligne[], int n) {
		char *p, *q, *deb;
		char motlu[25];
		int i;
		liste_mots list = NULL; /* elle sera allouee dynamiquement */
		
		if (n == 0) /* ligne vide */
			return NULL;
		for (p = ligne; *p != '\0' ; p++) {	/* p parcourt la ligne */
			/* on recherche un mot */
			/* on "mange" d'abord les blancs du debut */			
			for (q = p; *q == ' '; q++) /* la condition pourrait etre isBlanc(*q) */
				; 			
			deb = q; /* le debut du mot eventuel suivant */
			i = 0; /* nombre de lettres du mot qu'on va lire dans motlu */
			while ((*q != ' ') && (*q != '\0') ) {
				motlu[i++] = *q;
				q++; 	/* on avance q jusqu'a trouver un blanc (ou la fin) */
			}
			motlu[i] = '\0'; /* motlu est une chaine de caracteres imprimable */
			if (i!= 0) { /* equivalent de q-deb >0  */ 
				/* on a lu un mot de i lettres */			
//				list = addBegin(list, newElem(motlu)); /* ajout en tete */ 
				list = addEnd(list, newElem(motlu)); /* ajout en queue */ 
				p = q - 1; /* on avance p sur le dernier caractere du mot */			
			/* au prochain tour de boucle for, p sera d'abord incremente */
			/* et pointera finalement sur le meme char que q (celui après le mot) */
			}
		};
		return list;
}

element * newElem(char * motlu) {
	element * nouvElem = (element *) malloc(sizeof(element));
	char* mot = (char*) malloc (strlen(motlu)*sizeof(char));
	nouvElem->mot = strcpy(mot, motlu); /* mot alloue statiquement */
    nouvElem->suivant = NULL;
    return nouvElem;
}

void afficheListeMots(liste_mots list) {
	element * p  = list;
	
	if (p==NULL)
		return;	
	printf("(%s", p->mot);
	while ( (p = p->suivant) != NULL) 
      	printf(",%s",  p->mot); // les suivants...
  	printf(")\n");
  	return;
}    

liste_mots addBegin(liste_mots ls, element* nouv) {
	nouv -> suivant = ls;
	return nouv;
}

liste_mots addEnd(liste_mots ls, element* nouv) {
	element* der = ls;
	
	if (ls == NULL)
		return nouv;
	for (element* p = ls; p-> suivant != NULL; p = p->suivant)
		der = p;
	/* der pointe sur le dernier elem de ls */	
	der -> suivant = nouv;
	return ls;
}

