BOOL DoubleBuffer=FALSE, curseur=1, occupe=0;
#define ModeConsole()		(DoubleBuffer=0)
#define ModeGraphique()		(DoubleBuffer=1)

__inline void EtatCurseur(int etat)		{
	curseur=etat;
}

void printf_xy(int x, int y, const char *format, ...)	{ 
	int *a=NULL;
	char      vbuf[1024];
	va_list   arg_ptr;
	va_start(arg_ptr, format);
	_vsnprintf(vbuf, sizeof(vbuf), format, arg_ptr);
	DessTexte(x,y,vbuf);
}

int texteX=0, texteY=0;
int WordWrap=1, gblIndex=-1, gblX=0, gblY=0;
int LONG_MAX=4096;
int offsetX=0, offsetY=0;

#undef printf

#define LARG_CAR 8
#define HAUT_CAR 12
BOOL printfMode=0;

void MoveTo(int x, int y)		{
	texteX=x*LARG_CAR;
	texteY=y*HAUT_CAR;
}

#define printfLent()	(printfMode=0)
#define printfRapide()	(printfMode=1)
#define LongueurMax(n)	(LONG_MAX=n)

#define printfOk()

int printf(const char *format, ...)	{ 
	int *a=NULL, i,j, defile=0, yAvant=texteY,x,ii,passeLigne=0;
	char      vbuf[1024];
	va_list   arg_ptr;

	va_start(arg_ptr, format);
	j=_vsnprintf(vbuf, sizeof(vbuf), format, arg_ptr);
	FondTexte(TRANSPARENT);

	ChangeFonte("Courier New",16);

	for (i=0;i<j;i++)	{
		if (texteY>=HAUT-HAUT_CAR)		{
			memmove(Bits+LARG_BUF*3*HAUT_CAR,Bits,LARG_BUF*HAUT_BUF*3-LARG_BUF*3*HAUT_CAR);
			memset(Bits,0,LARG_BUF*3*HAUT_CAR);
			defile=1;
			texteY-=HAUT_CAR;
		}

		if (WordWrap)		{
/*			if (vbuf[i]==' ' || vbuf[i]=='\'' || vbuf[i]==',' || vbuf[i]=='\"' || vbuf[i]=='.' || vbuf[i]==':' || vbuf[i]==';' || vbuf[i]=='-' || vbuf[i]=='<' || vbuf[i]=='>' || vbuf[i]=='\\' || vbuf[i]=='(' || vbuf[i]==')' || vbuf[i]=='[' || vbuf[i]==']' || vbuf[i]=='+' || vbuf[i]=='*' || vbuf[i]=='&' || vbuf[i]=='|' || vbuf[i]=='/')		{
				x=texteX;
				ii=i+1;
				while(!(vbuf[ii]==' ' || vbuf[ii]=='\'' || vbuf[ii]==',' || vbuf[ii]=='\"' || vbuf[ii]=='.' || vbuf[ii]==':' || vbuf[ii]==';' || vbuf[ii]=='-' || vbuf[ii]=='<' || vbuf[ii]=='>' || vbuf[ii]=='\\' || vbuf[ii]=='(' || vbuf[ii]==')' || vbuf[ii]=='[' || vbuf[ii]==']' || vbuf[ii]=='+' || vbuf[ii]=='*' || vbuf[ii]=='&' || vbuf[ii]=='|' || vbuf[ii]=='/') && vbuf[ii])
					x+=LARG_CAR, ii++;
*/
			if (vbuf[i]==' ')		{
				x=texteX;
				ii=i+1;
				while(!(vbuf[ii]==' ' || vbuf[ii]=='\n') && vbuf[ii])
					x+=LARG_CAR, ii++;
				if (x>=LARG)		{
					passeLigne=1;
				}
			}
		}

		if (vbuf[i]=='\n')		{
			if (gblIndex==i)
				gblX=texteX, gblY=texteY;
			texteX=0;
			texteY+=HAUT_CAR;
			continue;
		}

		if (gblIndex==i)
			gblX=texteX, gblY=texteY;

		Cadre(texteX,texteY,LARG_CAR,HAUT_CAR,0);
		TextOut(hdcImage,texteX,texteY-2,vbuf+i,1);

		texteX+=LARG_CAR;
		if (texteX>=LARG || passeLigne)		{
			passeLigne=0;
			texteX=0;
			texteY+=HAUT_CAR;
			if (vbuf[i+1]==' ' && WordWrap)
				i++;
		}
	}
	if (gblIndex==i)
		gblX=texteX, gblY=texteY;
	gblIndex=-1;
	return 0;
}

#define scanf _scanf

/*#define scanf(tout,fsf...)		{														\
									char __tmpstr[4096];							\
									LongueurMax(4096);								\
									gets(__tmpstr);									\
									sscanf(__tmpstr,tout);							\
								}*/

typedef struct		{
	void *donnees[100];
} SCANF_DATA;

void _scanf(const char *format, ...)			{
	SCANF_DATA dt;
	const char *fmt=format;
	char str[4096];
	int i,nbre;
	va_list vl;

	va_start(vl,format);

	nbre=0;
	while(*fmt && nbre<100)			{
		if (*fmt=='%')
			nbre++;
		fmt++;
	}

	for (i=0;i<nbre;i++)
		dt.donnees[i]=va_arg(vl,void*);


	LongueurMax(4096);
	gets(str);
	sscanf(str,format,dt);
}


#define VideTamponTouche()		(nTouches=0)

#define cls clrscr
void clrscr()		{
	EffaceEcran(0);
	texteX=texteY=0;
}

#define TE_InsereCar(k)	{	memmove(chaine+curs+1,chaine+curs,longueur-curs); chaine[curs++]=k; chaine[++longueur]=0;	}
#define TE_BackSpace()		{	curs--; memmove(chaine+curs,chaine+curs+1,longueur-curs); chaine[--longueur]=0;	}
#define TE_Delete()		{	memmove(chaine+curs,chaine+curs+1,longueur-curs); chaine[--longueur]=0;			}


char *gets(char *chaine)		{
	int texteXsauv=texteX, texteYsauv=texteY, DoubleBufferSauv=DoubleBuffer;
	unsigned char *tampon=(unsigned char*)malloc(LARG_BUF*HAUT_BUF*3), *acoller, *retour=(unsigned char*)chaine;
	int longueur=0,k, curs=0,i;
	HANDLE h;

	if (!tampon)		{
		printf("Erreur: Mémoire\n");
		return chaine;
	}

	memcpy(tampon,Bits,LARG_BUF*HAUT_BUF*3);
	DoubleBuffer=TRUE;

	chaine[0]=0;
	while(1)		{
		memcpy(Bits,tampon,LARG_BUF*HAUT_BUF*3);
		texteX=texteXsauv,texteY=texteYsauv;
		gblIndex=curs;							//Pose une question globale
		printf("%s",chaine);					//printf va afficher et répondre par la même occasion
//		MoveTo(gblX/LARG_CAR,gblY/HAUT_CAR);	//Et la réponse est là.
		texteX=gblX, texteY=gblY;
		DoubleBuffer=FALSE;
		while(1)		{
			k=getkey();
			if (k)
				break;
			if (toucheAppuyee(T_HAUT) && curs>0)		{
				curs--;
				if (chaine[curs]=='\n' && curs>0)
					curs--;
				while (chaine[curs]!='\n' && curs>0)
					curs--;
				if (curs>0)
					curs++;
				break;
			}
			if (toucheAppuyee(T_BAS) && curs<longueur)		{
				curs++;
				while (chaine[curs]!='\n' && curs<longueur)
					curs++;
				break;
			}
			if (toucheAppuyee(T_GAUCHE) && curs>0)		{
				curs--;
				break;
			}
			if (toucheAppuyee(T_DROITE) && curs<longueur)		{
				curs++;
				break;
			}
			if (toucheAppuyee(T_DELETE) && curs<longueur)		{
				TE_Delete();
				break;
			}
			if (toucheAppuyee(T_ESCAPE))		{
				chaine[0]=0;
				getch();									//Vide le tampon
				k='\r';
				retour=NULL;
				break;
			}
			if (toucheAppuyee('V') && testTouche(T_CTRL))		{
				OpenClipboard(hConsole);
				h=GetClipboardData(CF_TEXT);
				acoller=(unsigned char*)GlobalLock(h);
				i=strlen((const char*)acoller);
				if (longueur+i<LONG_MAX)			{
	//				printf("%i %i %i",curs+i,curs,longueur-curs);
	//				getch();
					memmove(chaine+curs+i,chaine+curs,longueur-curs);
					memcpy(chaine+curs,acoller,i);
					curs+=i;
	//				chaine[curs]=k;
					longueur+=i;
					chaine[longueur]=0;
	//				TE_ColleTexte(acoller);
				}
				GlobalUnlock(h);
				CloseClipboard();
			}
		}
		DoubleBuffer=TRUE;
		if (k=='\r')				//'\n' si entrée avec ctrl enfoncé...
			break;
		if (k==8 && curs>0)		{	//Retour arrière
			TE_BackSpace();
		}
		if (((k>=32 && k<=255) || k=='\n') && longueur<LONG_MAX-1)		{			//Un caractère
			TE_InsereCar(k);
		}
	}

	DoubleBuffer=DoubleBufferSauv;
	printf("\n");
	return (char*)retour;
}



