#include "StdAfx.h"
#include ".\huffman.h"

void Huffman::encoder_fichier(FILE*src,BitFile*dest)
{

}

void Huffman::decoder_fichier(BitFile*src,FILE*dest)
{

}

void Huffman::ecrire_statistiques(FILE*dest)
{

}

int Huffman::comprimer(char*nom,FILE*source,FILE*dest)
{
	FILE*src=fopen(nom,"rb");
	compter(src);
	rewind(src);

	// construction de l'arbre
	sommet=256;
	int min1,min2;
	min1=min2=-1;
	int poids=0;

	while(poids<lus && sommet<MAX)
	{
		// recherche le plus petit non nul
		min1=rechercher_min();
		if(min1<0)
			break;
		
		stats[sommet]->fils1=min1;
		stats[sommet]->freq=stats[min1]->freq;
		
		stats[min1]->sauve=stats[min1]->freq;
		stats[min1]->freq=0;

		// recherche le second plus petit non nul
		min2=rechercher_min();
		if(min2<0)
			break;

		stats[sommet]->fils2=min2;
		stats[sommet]->freq+=stats[min2]->freq;
		stats[min2]->sauve=stats[min2]->freq;
		stats[min2]->freq=0;

		poids+=stats[sommet]->freq;
		sommet++;
	}

	// génération du codage
	genere_code(stats[sommet],0,0,0);	

	// encodage
	ecrits=0;
	ecrire_statistiques(dest);
	BitFile*bf=new BitFile;
	bf->openOutput(dest);	

	encoder_fichier(src,bf);

	// fin
	fclose(src);

	return ecrits;
}

void Huffman::expanser(char*nom,int taille_originale,int taille_archive,FILE*source)
{

}

void Huffman::genere_code(Noeud*n,int code,int lcode,int m)
{
	n->code=(code << 1) | m;
	n->lcode=lcode;

	if(n->fils1>=0)
		genere_code(stats[n->fils1],n->code,lcode+1,0);

	if(n->fils2>=0)
		genere_code(stats[n->fils1],n->code,lcode+1,1);
}

Huffman::Huffman(void)
{
	int i;
	stats=new Noeud*[MAX];

	for(i=0; i<512; i++)
		stats[i]=new Noeud;
}

Huffman::~Huffman(void)
{
	for(int i=0; i<512; i++)
		delete stats[i];
	delete stats;
}

void Huffman::compter(FILE*src)
{
int c;
	lus=0;
	while((c=fgetc(src))!=-1)
	{
		stats[c]->freq++;		
		lus++;
	}
}

void Huffman::afficher_stats()
{
	for(int i=0; i<MAX; i++)
		if(stats[i]->freq!=0)
		{
			printf("%c:%d\t",(i>32 && i<127)?i:32,stats[i]->freq);
		}
}

int Huffman::rechercher_min()
{
	// recherche du premier non nul
	int i;
	for(i=0; i<MAX && stats[i]->freq==0; i++);
		
	if(i==MAX)
		return -1;

	// mémorisation valeur et recherche plus petite;
	int v=stats[i]->freq;
	int index=i;
	for(; i<MAX; i++)
		if(stats[i]->freq>0 && stats[i]->freq<v)
		{
			v=stats[i]->freq;
			index=i;
		}
	return index;
}
