#ifndef _TEXT_H_
#define _TEXT_H_

//#include "windows.h"
//#include "Rect.h"
#include "CObjLayerFont.h"


#define DEBUG_WRAP 0

typedef struct
{
	unsigned int first;			// indice du premier char de la sous_ligne
	unsigned int nCount;		// nb de characters de la sous-ligne
	unsigned int ndx;			// indice de la ligne à laquelle appartient la sous ligne
	int			 stringw;		// largeur de la chaine
	int			 stringh;		// hauteur de la chaine
	int			 maxstringw;	// largeur maximale des sous chaines jusqu'à cette sous ligne
	int			 postop;		// position du haut de la sous-ligne par rapport à la premiere 			
	int			 posbaseline;	// position de la baseline para rapport à son top
} InfoLine;


////////////////////////////////////////////////////////////////////////////////////////////////////////
//                             LA CLASSE DE BASE TEXTE                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////////
class Text
{
private:
	void AssignValueToTab(unsigned int,unsigned int,unsigned int,unsigned int,int,int,int);


protected:

	char	 *		TILtexte;		// texte
	unsigned int	TILlen;			// longueur du texte
	InfoLine *		TILsubline;		// sous ligne
	unsigned int	TILsize;		// nombre de sous lignes
	int				TILmaxstringw;	// taille maximale des sous-chaines
	int				TILhtexte;		// hauteur totale du texte
	unsigned int	TILwrap;		// texte wrappé
	int				TILcx;			// largeur de la zone de wrap

public:

	Text(char *texte,int wrap,int cx);
	virtual ~Text();
	
	inline char *		getText()			{return TILtexte;};
	inline unsigned int getLen()			{return TILlen;};
	inline unsigned int getNbLines()		{return TILsize;};
	inline InfoLine		getInfoLine(int i)	{return TILsubline[i];};
	inline int			getMaxWidth()		{return TILmaxstringw;};
	inline int			getHeight()			{return TILhtexte;};

	// decoupe le texte en sous ligne a partir de la sous-ligne d'index nIndexSubStart
	int WordWrap(unsigned int nIndexSubStart,unsigned int nIndexStop);
	
	// Clip d'une ligne 
	//unsigned int ClipLine(unsigned int nIndex,unsigned int nIndexEnd,int *w,int *h,int *baseline);
	unsigned int ClipLine(unsigned int nIndex,unsigned int nIndexEnd);

	// Renvoie l'index de la sous ligne à laquelle appartient la lettre d'indice nIndexStart
	unsigned int SearchSubLineInTab(unsigned int nIndexStart);
	
	// Renvoie l'index du charactere se situant à la position xpos et compris entre nIndex et nIndexEnd
	unsigned int SearchIndexInTab(int xpos,int nIndex,int nIndexEnd);
	
	unsigned int GetCharWidth(int nIndex);

	// Renvoie l'index du charactere suivant
	unsigned int NextIndex(unsigned int nIndex);
	
	// Renvoie l'index du charactere precedant
	unsigned int PreviousIndex(unsigned int nIndex);

	// Renvoie le nombre de characters visibles dans la sous-ligne
	// a laquelle appartient nIndex
	int NumberCharacterVisible(unsigned int ndxSubLine,unsigned int nIndex);

	// Renvoie l'index pour lequel on a nbchars visible dans la sous-ligne ndxSubLine
	unsigned int IndexFromCharacterVisible(unsigned int ndxSubLine,int nbchars);
	
	// Modifie la taille du wrap du texte
	void ChangeWrapSize(int newcx);
	
	virtual char *getRealText();
	
	// Change le texte Rem:le nouveau texte ne dois posseder aucun \n
	virtual void SetText(char *newtext,int execwordwrap);

	// Ajoute du texte en fin de chaine Rem:le nouveau texte ne dois posseder aucun \n
	virtual void AddText(char *newtext,int execwordwrap);

	// Coupe le texte au premier retour chariot trouve
	// ou bien si testclip clip de la ligne
	virtual int  CrunchText(int testclip);

	// Insere le charactere vk à la position nIndex
	// Les couleurs sont celles de l'index d'insertion
	virtual void InsertChar(int vk,int nIndex,int execwordwrap);

	// Supprime le charactere à la position nIndex
	virtual void DeleteChar(int nIndex,int execwordwrap);

	// Insere la sous-chaine à la position nIndex Rem:le nouveau texte ne dois posseder aucun \n
	// Les couleurs sont celles de l'index d'insertion
	virtual void InsertSubString(char *string,int nIndex,int execwordwrap);

	// Supprime la sous-chaine commencant à l'index nIndexStart comportant nCount characteres
	// renvoie -1 si aucun caharactere n'a ete supprime
	// renvoie nIndexStart si tout c'est bien passé
	virtual int DeleteSubString(int nIndexStart,int nIndexEnd,int execwordwrap);

	// Fonction d'affichage
	virtual void Print();

	// Evalue la largeur et la heuteur d'un texte multi-font
	// Renvoie la position de la baseline
	virtual int GetStringWidthHeight(int nStart,int nCount,int usetab,int *w,int *h)=0;
	
	// Renvoie le Layer font du nIndex Charactere
	virtual CObjLayerFont * GetLayerFont(int nIndex)=0;
	
	// Renvoie la couleur du texte d'indice nIndex
	virtual int				GetTextColor(int nIndex)=0;

	// Affiche la sous-ligne IndexSubString dans le layer layer
	virtual int DrawSubString(Layer *layer,int x,int y,int Flags,int IndexSubString)=0;

	// Retrouve les parametres du charactere nIndex
	virtual CObjLayerFont * RetrieveCharParam(int nIndex,int *textcolor,int *coefftransp,int *shadowflag,int *shadowcolor)=0;
};

////////////////////////////////////////////////////////////////////////////////////////////////////////
//                             LA CLASSE DE TEXTE MONOFONT                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////
class TextMonoFont:public Text
{
private:

	CObjLayerFont * TMOFfont;
	int				TMOFtextcolor;
	int				TMOFcoefftransp;
	int				TMOFshadowflag;
	int				TMOFshadowcolor;
	
public:

	TextMonoFont(char *texte,CObjLayerFont *layerfont,int textcolor,int shadowflag,int shadowcolor,int coefftransp,int wrap,int cx);
	virtual ~TextMonoFont();
	
	// Renvoie le Layer font du nIndex Charactere
	CObjLayerFont * GetLayerFont(int nIndex);
	
	int				GetTextColor(int nIndex);

	// Evalue la largeur et la heuteur d'un texte multi-font
	// Renvoie la position de la baseline
	int GetStringWidthHeight(int nStart,int nCount,int usetab,int *w,int *h);
	
	// Affiche la sous-ligne IndexSubString dans le layer layer
	int DrawSubString(Layer *layer,int x,int y,int Flags,int IndexSubString);

	// Retrouve les parametres du charactere nIndex
	CObjLayerFont * RetrieveCharParam(int nIndex,int *textcolor,int *coefftransp,int *shadowflag,int *shadowcolor);
	
	void Print();
};

////////////////////////////////////////////////////////////////////////////////////////////////////////
//                             LA CLASSE DE TEXTE PASSWORD                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////
class TextPassword:public TextMonoFont
{
private:
	char		* TTPtexte;
	
	char		* replaceByStar(char *);
public:
	TextPassword(char *texte,CObjLayerFont *layerfont,int textcolor,int shadowflag,int shadowcolor,int coefftransp,int wrap,int cx);
	virtual ~TextPassword();

	char *getRealText();

	// Change le texte Rem:le nouveau texte ne dois posseder aucun \n
	void SetText(char *newtext,int execwordwrap);

	// Ajoute du texte en fin de chaine Rem:le nouveau texte ne dois posseder aucun \n
	void AddText(char *newtext,int execwordwrap);

	// Coupe le texte au premier retour chariot trouve
	// ou bien si testclip clip de la ligne
	int CrunchText(int testclip);

	// Insere le charactere vk à la position nIndex
	// Les couleurs sont celles de l'index d'insertion
	void InsertChar(int vk,int nIndex,int execwordwrap);

	// Supprime le charactere à la position nIndex
	void DeleteChar(int nIndex,int execwordwrap);

	// Insere la sous-chaine à la position nIndex Rem:le nouveau texte ne dois posseder aucun \n
	// Les couleurs sont celles de l'index d'insertion
	void InsertSubString(char *string,int nIndex,int execwordwrap);

	// Supprime la sous-chaine commencant à l'index nIndexStart comportant nCount characteres
	// renvoie -1 si aucun caharactere n'a ete supprime
	// renvoie nIndexStart si tout c'est bien passé
	int DeleteSubString(int nIndexStart,int nIndexEnd,int execwordwrap);

};


typedef struct
{
	int color;
	int shadowflag;
	int shadowcolor;
	int coefftransparancy;
	CObjLayerFont * font;
} InfoChar;


#include <list>

////////////////////////////////////////////////////////////////////////////////////////////////////////
//                             LA CLASSE DE TEXTE MULTIFONT                                           //
////////////////////////////////////////////////////////////////////////////////////////////////////////
class TextMultiFont:public Text
{
public:

	InfoChar *		TILsubchar;		// info charactere

	TextMultiFont(char *texte,CObjLayerFont *layerfont,int textcolor,int shadowflag,int shadowcolor,int coefftransp,int wrap,int cx);
	virtual ~TextMultiFont();
	
	// Renvoie le Layer font du nIndex Charactere
	CObjLayerFont * GetLayerFont(int nIndex);
	
	int				GetTextColor(int nIndex);

	// Evalue la largeur et la heuteur d'un texte multi-font
	// Renvoie la position de la baseline
	int GetStringWidthHeight(int nStart,int nCount,int usetab,int *w,int *h);
	
	// Change le texte Rem:le nouveau texte ne dois posseder aucun \n
	void SetText(char *newtext,InfoChar * info,int execwordwrap);

	// Ajoute du texte en fin de chaine Rem:le nouveau texte ne dois posseder aucun \n
	void AddText(char *newtext,InfoChar * info,int execwordwrap);

	// Coupe le texte au premier retour chariot trouve
	// ou bien si testclip clip de la ligne
	int CrunchText(int testclip);

	// Insere le charactere vk à la position nIndex
	// Les couleurs sont celles de l'index d'insertion
	void InsertChar(int vk,int nIndex,int execwordwrap);

	// Supprime le charactere à la position nIndex
	void DeleteChar(int nIndex,int execwordwrap);

	// Insere la sous-chaine à la position nIndex Rem:le nouveau texte ne dois posseder aucun \n
	// Les couleurs sont celles de l'index d'insertion
	void InsertSubString(char *string,int nIndex,int execwordwrap);

	// Supprime la sous-chaine commencant à l'index nIndexStart comportant nCount characteres
	// renvoie -1 si aucun caharactere n'a ete supprime
	// renvoie nIndexStart si tout c'est bien passé
	int DeleteSubString(int nIndexStart,int nIndexEnd,int execwordwrap);

	// Affiche la sous-ligne IndexSubString dans le layer layer
	int DrawSubString(Layer *layer,int x,int y,int Flags,int IndexSubString);

	// Fonction d'affichage
	void Print();

	// Retrouve les parametres du charactere nIndex
	CObjLayerFont * RetrieveCharParam(int nIndex,int *textcolor,int *coefftransp,int *shadowflag,int *shadowcolor);

};



unsigned int NextWord(char* txt,int nIndex);
unsigned int PreviousWord(char* txt,int nIndex);
unsigned int EndOfLine(char * txt,unsigned int nLen,unsigned int nIndex);


char *       ReplaceRnByR(char *);
char *		 ReplaceRByRn(char *,int count);
char *		 ReplaceRByN (char *);

#endif //_TEXT_H_