#!/usr/bin/perl

#####################################
# Dictionnaire Lempel-Ziv
#####################################

#####################################
# Variables

$chaine = shift(@ARGV); #Récupération du nom de fichier écrit dans la console passé en argument
$passage = shift(@ARGV);
$fichier=$chaine; #Variable nom de fichier correspondant à la chaine précedemment citée

open(FILEDES, "<$fichier"); #Ouverture du fichier en lecture
@lignes=<FILEDES>; #Récupération des lignes du fichier dans 1 tableau
close(FILEDES); #Fermeture du fichier
$NombreDeLignes=@lignes; #Variable qui permet de récupérer le nbre de lignes du fichier

recupereMotMesh(); #Permet de récupérer les mots Mesh avant le symbole |
# 
#####################################

for ($p=0;$p<$passage;$p++) {
	for ($i=0;$i<$NombreDeLignes;$i++){ #Pour chaque ligne du fichier
	    @chaine_de_base = lecture_chaine_caractere($lignes[$i]); #Récupération de la chaine de base
	    $taille = length($lignes[$i]); #Taille de la chaine de base
	    print "Chaine : $lignes[$i]\n"; #Ecriture de la chaine
	    creation_dico(@chaine_de_base); #Création du dico sur la chaine de base
	}
}
imprime_dico(); #Ecriture du dico dans la console
ecrire_dico($chaine); #Ecriture du dico dans un fichier
exit; #Fin de la fonction


#####################################
# Creer le dictionnaire en fonction
# du tableau chaine en entree
#####################################

sub creation_dico #Création du dico
	{
	my (@chaine_initiale) = @_; #Récupération de la chaine initiale passée en argument
	my ($caractere_innovant) = ""; #Chaine vide à l'initialisation
	my ($caractere_precedent) = ""; #Chaine vide à l'initialisation
	my ($caractere_suivant) = ""; #Chaine vide à l'initialisation
	for ($m=0;$m<@chaine_initiale;$m++) #Pour chaque chaine de caractère
	# while(@chaine_initiale)
	{
		#$caractere_innovant = shift(@chaine_initiale); #Récupération du premier caractère de la chaine et diminution de la chaine
		$caractere_innovant = $chaine_initiale[$m]; #Caractère pris en considération
		$caractere_suivant = $chaine_initiale[$m+1]; #Caractère suivant le caractère innovant
		$caractere_precedent = $chaine_initiale[$m-1]; #Caractère précédant le caractère innovant
		if ($caractere_precedent =~ /\s/)  #Si le caractère précédent n'est pas un espace,etc...
		{
		    if (!est_dans_dico($caractere_innovant.$caractere_suivant) ) #Si ce n'est pas dans le dico
		    {
			ajoute_dans_dico($caractere_innovant.$caractere_suivant); #Ajouter dans le dico
		    }
		    else
		    {
			$k=$m+1; #On incrémente le pas de 1
			do
			{
			    $caractere_innovant = $caractere_innovant.$caractere_suivant; #On prend comme caractère innovant le caractère innovant ancien + le caractère suivant
			    #shift(@chaine_initiale);
			    $caractere_suivant = $chaine_initiale[$k+1]; #Le caractère suivant du nouveau caractère innovant
				$k++;
			}
			while(est_dans_dico($caractere_innovant.$caractere_suivant) &&($caractere_suivant  ne "")); #Faire ceci tant que c'est dans le dico
			if(!est_dans_dico($caractere_innovant.$caractere_suivant)){
				ajoute_dans_dico($caractere_innovant.$caractere_suivant);} #Sinon rajouter au dico
		    }
		}
	}
    }	

#####################################
# Lit la chaine et range les lettres
# dans un tableau
#####################################

sub lecture_chaine_caractere
	{
	my ($chaine_brute) = @_; #Chaine passée en argument
	my (@tableau_caractere) = split ('',$chaine_brute); #Retire les espaces dans la chaine
	return @tableau_caractere; #Retourne donc un tableau de caractères sans espace
	}

#####################################
# Regarde si le mot est dans le dico
# retourne 0 ou 1
#####################################

sub est_dans_dico
	{
	my ($mot) = @_; #mot passé en argument
	my $mon_mot;
	my $var_return = 0;
	for($j=0;$j<@dico;$j++) #Pour chaque mot du dictionnaire
	        {
		if ($dico[$j] eq $mot) #Si le mot du dictionnaire est égal au mot considéré
		      {
		      $var_return = 1;  #Retourne la valeur 1
		      $compteur[$j]++; #Et augmente le compteur de 1
		      }
		}
	return $var_return; #Retourne la valeur de la fonction ( 0 ou 1 )
	}

#####################################
# ajoute le mot dans le dico
#
#####################################

sub ajoute_dans_dico {
    my ($mot) = @_; #mot passé en argument
    if (!($mot =~ /\s/)) { #Si le mot est accepté
	push (@dico,$mot); #ajouter le mot dans le dico
	$compteur[@dico-1] = 1; #Réinitialiser le compteur à 1
    }
}

#####################################
# imprime le dico
#
#####################################

sub imprime_dico
	{
	my ($i);
	$i=0;
	print "\n\n********** DICTIONNAIRE **********\n\n";
	print "**chaine**\t**longueur**\t**indice**\t**compteur**\n";
	foreach (@dico) #Pour chaque ligne du dico
		{
		print "  $_\t\t    ".length($_)."\t\t    ".$i;
		print "\t\t    ".$compteur[$i]."\n";
		$i++;
		}
	}

#####################################
# ecrit le dico
#
#####################################

sub ecrire_dico
	{
	open(FILEDES, ">$fichier.dico"); #Ouverture du fichier en écriture
	$longueur = 1;
	do {
		$continue = 1;
		for($i=0;$i<@dico;$i++) #Pour chaque mot du dico
			{
			if ( length($dico[$i]) == $longueur ) {
				print FILEDES $dico[$i]; #Ecrire dans le fichier
				print FILEDES "\n"; #Faire un retour chariot
				}
			else { 
				if (length($dico[$i]) > $longueur )
					{$continue = 0; }
				}			
			}
		$longueur++;
		}
	while( $continue == 0 );
	close(FILEDES); #Fermeture du fichier
	}

#####################################
# Recupere la chaine de caractere
# avant le symbole |
#####################################

sub recupereMotMesh {
    for($i=0;$i< $NombreDeLignes;$i++){ #Pour chaque ligne du fichier
       	@temp  = split(/\|/,$lignes[$i]); #Supprimer les |
	$lignes[$i] = " ".$temp[0]; #Retour du premier mot Mesh
    }
}


