//
//			+----------------------------------------------------------------+
//			|							PAck.h				 		  |
//			| C'est ici que je vais gérer les fichiers packés tant en		  |
//			|					écriture qu'en lecture					  |
//			|														  |
//			|  David-U2/GameSquad 1999(c)								  |
//			+----------------------------------------------------------------+


#ifndef _GTZpack_H_
#define _GTZpack_H_

//#define GTZPAKER			// version pour le prog MFC du paker !!

#include "Zlib.h"

//===================
// definition d'un fichier dans la base de donnée

#define FILE_NOCOMPRESS	0x1
#define FILE_LZWCOMPRESS	0x2


class FileDataBase{

	char Flag	;				// flag décrivant le fichier
	char FlagType	;				// type de packing

	int			UnCompressSize	;
	int			CompressSize		;
	CByteArray	Data				;	// pointeur sur les données non compressées
	CByteArray	Pack				;	// pointeur sur les données une fois compressées

	BOOL			IsLoaded	;	// fichier chargé en RAM ou sur le dur ?
	unsigned int	seek		;	// position data dans le fichier !
	CFile		*file	;	// pointeur sur le CFile du fichier ou ce trouve le FileDataBase

	CString	RealPath		;	// veritable localisation du fichier !
	CTime	LastModified	;	// date da la dernière modif du fichier

	void	LoadDepuisFile()	;	// load réellement les données depuis le fichier


public:

	CString		nom		;	// nom du fichier !
	FileDataBase *suiv	;	// fichier suivant dans le liste
	
	FileDataBase()								;
	FileDataBase(LPCSTR dir, LPCSTR _nom,HWND=NULL)	;
	~FileDataBase()								;

	LPCSTR	GetNom(){return (LPCSTR)nom;}
	int		GetSize()									;
	int		GetCompressedSize()							;
	int		GetUnCompressSize(){ return UnCompressSize; }
	void		GetSize( int &uncompressed, int &compressed )	;
	int		GetStatus(){return Flag;}

	void			Compress(int type,HWND=NULL)		;
	// decompress les données si destruc == TRUE alors on detruit les infos
	// relatives aux données packées
	// Renvoie un pointeur sur les données
	CByteArray	*UnCompress(BOOL destruc=FALSE)	;

	void Unpack(){Flag = FILE_NOCOMPRESS;}

	// vois si ya eut des changement sur le fichier pointé et si oui -> Reload le fichier si il existe encore et renvoie TRUE
	// ou si il n'existe plus renvoie FALSE !
	BOOL TestAndReload( int &nbreload )	;

	// permet de gagné de la place en ne stoclant plus l'emplacement d'origine du fichier !
	void RemoveRealPath()	;

	FileDataBase& operator=(FileDataBase& m)	;

	// si RealFile!=NULL alors on ne load pas les données en mémoire on met juste en place toutes
	// les structures nécessaires pour l'utilisation de la base de donnée.
	// Les données seront alors chargées depuis RealFile lors d'un appel de decompression !
	void Serialize(CArchive &ar, CFile *RealFile=NULL )	;
	
	// va sauver toute les données en format non compressées et en fichier séparés dans le répertoire loca
	void Serialize( LPCSTR loca )	;
};



//==================
// définition d'un folder 

struct GTZfolder{

	CString		nom		;
	GTZfolder	*suiv	;	// folder au même niveau que lui

	GTZfolder	*parent	;	// folder parent a celui-ci
	GTZfolder	*child	;	// folder dependant de lui
	int			nbChild	;	// nombre de folder dependant

	FileDataBase *liste	;	// liste de fichier
	int			nbFile	;	// nombre de fichier


	GTZfolder()				;
	GTZfolder( LPCSTR n )		;
	~GTZfolder()				;
	void SetNom( LPCSTR n )	{nom=n;}

	BOOL			FolderNameValid( GTZfolder *f )	;
	LPCSTR		AddFolder(  GTZfolder *f )		;
	GTZfolder*	AddFolder( LPCSTR path )		;	// rajoute un folder en fct du path et renvoie le folder ajouté
	GTZfolder*	Find( LPCSTR nom )			;	// retourne folder adequate
	BOOL			Delete( GTZfolder *f )			;	// a deleté le folder sur TRUE renvoyé
	BOOL			Enleve( GTZfolder *f )			;	// enleve tout simplement f ( sans le detruire!!! ) renvoie TRUE si reussi

	void				Add( FileDataBase *f )							;
	FileDataBase*		Add( LPCSTR directory, LPCSTR nomFile )			;
	FileDataBase*		GetFile( LPCTSTR n )							;
	FileDataBase*		GetNextFile( FileDataBase	*&file, CString &cs )	;	//	renvoie le fichier suivant celui-ci  dans la database et son path
	BOOL				Delete( FileDataBase *f )						;	// a deleté le fichier sur TRUE renvoyé
	BOOL				Enleve( FileDataBase *f )						;	// enleve tout simplement f ( sans le detruire!!! )
	void				DeleteAllFile()								;	// detruit tout les fichiers de ce folder ( mais pas dans les sous folders )
	void				DeleteFormExtension( LPCSTR ext, int &nbdel )	;	// detruit les fichiers avec l'extension donnée

	CByteArray* GTZfolder::GetData( LPCSTR nom,BOOL destruc=FALSE)	;	// si destruc==TRUE alors on supprime les données après

	// renvoie la taille du fichier ( non packé ) si existe sinon renvoie 0
	int Exist( LPCSTR nom )	;

	FileDataBase* GetFirstFile( CString &cs )					;
	void		GetSize( int &uncompressed, int &compressed )	;
	void		GetFolderName(CString &nom)						;
	int		GetNBFile()											;	// retourne le nombre de fichier contenus dans le pack !

	void Unpack()											;
	#ifdef GTZPAKER
	void Compress(int type,int &pos, CProgressCtrl &prog)		;	// compress le tout 
	void ConstrucTree( CTreeCtrl &tree, HTREEITEM actua )	;
	#endif
	void UnCompress(int destruc=FALSE)						;

	// Test les fichiers d'origines pour voir si ya eut un changement !
	// si cas = 0 alors quand fichier inexistant on le garde
	// si cas != 0 si fichier inexistant on le supprime
	void TestAndReload( int &nbreload, int &nbdel, int cas=0 );

	// enleve les path d'origine des fichier -> ca permet de gagné de la place mais on 
	// ne pourra plus tester l'existance de ces fichiers ensuite 
	void RemoveRealPath();

	// si RealFile!=NULL alors on ne load pas les données en mémoire on met juste en place toutes
	// les structures nécessaires pour l'utilisation de la base de donnée.
	// Les données seront alors chargées depuis RealFile lors d'un appel de decompression !
	void Serialize( CArchive &ar, CFile *RealFile=NULL );

	// va sauver toute les données en format non compressées et en fichier séparés dans le répertoire loca
	void Serialize( LPCSTR loca )	;

};



//===================
// definition d'une base de donnée packée

class GTZpack{

	unsigned int	nbFolder	;	// nombre de folder de base
	GTZfolder	*liste			;	// liste de folder
	GTZfolder	*actualF		;	// folder actuel
	HWND			m_hWnd		;	// handle de fenètre


	void Add( FileDataBase *fi )			;
	BOOL FolderNameValid( GTZfolder *f )	;	// renvoie TRUE si Ok False sinon

public:

	GTZpack(HWND)	;
	~GTZpack()	;

	// ajoute un folder a la racine
	LPCSTR	AddFolder( GTZfolder *f )	;
	// ajoute un folder ( ou les folders en fait car créé les folder maquants en fct
	// du path qu'on lui file en parametre ) et le met ensuite comme folder courant.
	void		AddFolder( LPCSTR path )	;
	void		SetFolder( LPCSTR nom )		;	// met un folder comme folder courant
	void		Delete( GTZfolder *f )		;	// detruit le folder donné
	void		Enleve( GTZfolder *f )		;	// enleve tout simplement f ( sans le detruire!!! ) renvoie TRUE si reussi
	GTZfolder*	GetActualFolder()			{return actualF;}

	void Delete( FileDataBase *f )						;	// detruit un fichier donné
	void Enleve( FileDataBase *f )						;	// enleve tout simplement f ( sans le detruire!!! )
	void DeleteFormExtension( LPCSTR ext, int &nbdel )	;	// detruit les fichiers avec l'extension donnée

	// retourne un l'adresse du CByteArray qui contient tout les données une fois 
	// decompressée.
	// on peut si on ne réutilise pas ce fichier faire un removeAll sur le CByteArray
	// afin de gagner de la mémoire
	// NB : on recherchre depuis folder courant mi a jour grace a SetFolder( nomFolder )
	CByteArray* GetData(LPCSTR nom,BOOL destruc=FALSE)			;	// si destruc==TRUE alors on supprime les données après
	// la diférence est qu'ici on ne s'occupe pas du folder courant.
	// nom doit comporter tout le path complet ( du GTZ pack )
	CByteArray* GetDataFolder( LPCSTR nom,BOOL destruc=FALSE)		;

	// renvoie la taille du fichier ( non packé ) si existe sinon renvoie 0
	int Exist( LPCSTR nom )	;

	// si RealFile!=NULL alors on ne load pas les données en mémoire on met juste en place toutes 
	// les structures nécessaires pour l'utilisation de la base de donnée.
	// Les données seront alors chargées depuis RealFile lors d'un appel de decompression !
	void Serialize( CArchive &ar, CFile *RealFile=NULL )	;

	// va sauver toute les données en format non compressées et en fichier séparés dans le répertoire loca
	void Serialize( LPCSTR loca )	;

	void	GetSize( int &uncompressed, int &compressed )	;
	int		GetNBFile()										;	// retourne le nombre de fichier contenus dans le pack !

	FileDataBase	*GetFirstFile( CString &cs )						;
	FileDataBase	*GetFileFolder( LPCTSTR n )							;
	FileDataBase	*GetNextFile( FileDataBase	*file, CString &cs )	;	//	renvoie le fichier suivant celui-ci  dans la database et son path


	void Unpack()											;
	#ifdef GTZPAKER
	void Compress(int type,int &pos, CProgressCtrl &prog)		;	// compress le tout
	void ConstrucTree( CTreeCtrl &tree, HTREEITEM actua )	;
	#endif
	void UnCompress(int destruc=FALSE)						;

	// Test les fichiers d'origines pour voir si ya eut un changement !
	// si cas = 0 alors quand fichier inexistant on le garde
	// si cas != 0 si fichier inexistant on le supprime 
	void TestAndReload( int &nbreload, int &nbdel, int cas=0 )	;

	// enleve les path d'origine des fichier -> ca permet de gagné de la place mais on 
	// ne pourra plus tester l'existance de ces fichiers ensuite 
	void RemoveRealPath()	;

	void LoadLst( CStringList *list )	;

};


#endif