#pragma once

#include "ICompresseur.h"
#include "bitfile.h"
#include <stdlib.h>

/*
 * Constantes relatives à l'implémentation LZW
 * Le codage varie de 9 à 15 bits
 */
#define BITS	15
#define CODE_MAX	((1 << BITS ) -1)
#define TAILLE_TABLE	35023L
#define TABLE_PAGE (( TAILLE_TABLE >> 8) +1)
#define FIN_DE_FLUX_LZ 256
#define CHANGEMENT_CODAGE 257
#define CODE_PURGE 258
#define PREMIER_CODE 259
#define MUNUSED -1

/*
 * Le dictionnaire de chaînes est un arbre
 *
 */
struct Dictionnaire {
	int code_value;		// code LZW
	int parent_code;	// chaînage
	char character;		// caractère
};

/*
 * Cette macro est utile avec les compilateurs 16 bits
 */
#define DICT(i) dict[i >> 8][i & 0xff]

class LZW : public ICompresseur  
{
private:
	Dictionnaire* dict[TABLE_PAGE];
	char decode_stack[TAILLE_TABLE];
	unsigned int code_suivant;
	int largeur_codage;
	unsigned int prochain_code_saut;
	int cb;

	void expandFile(BitFile*input,FILE*output);
	unsigned int decodage_chaine(int count,int code);
	void compressFile(FILE*input,BitFile*output);
	unsigned int trouve_chaine(int parent_code,int child_character);
	void initialiseStockage();
	void initialiseDictionnaire();

public:
	virtual int comprimer(char*nom,FILE*source,FILE*dest);
	virtual void expanser(char*nom,int taille_originale,int taille_archive,FILE*source);
};
