//
// Modifications History
//
//$LB (20/12/2002) : 16bits to 24bits
//

#include "Macro.h"
#include "CObjectEditText.h"
#include "CObjMessageMove.h"			//pour la classe CObjMessageMove et les directions prédéfinies
#include "CObjMessageStringSelect.h"
#include "../x/Objstr.h"
#include "utils.h"
#include "container.h"
#include <Tchar.h>



extern int OBJNODE;
extern mmachine mm;
extern HINSTANCE hinst;

#define FONT 0

#define SIZECURSOR 1
#define TIMER_CURSOR 500
#define TIMER_SCROLL 250

#define SCROLL_H	 (1<<0)
#define SCROLL_V	 (1<<1)

CObjectEditText::CObjectEditText(container * cont,
								 Layer *layer,
								 int x,int y,int w,int h,
								 int flags,int contflags,
								 int transp,
								 int p_font,int textcolor,int textcoefftransp,int shadowflag,int shadowcolor,
								 char * texte,const char *forbiddenchar,
								 int select_color,int coeff_transp
								)
								:CObjectText(cont,
											layer,
											x,y,w,h,
											flags,
											contflags,
											textcolor,
											shadowflag,
											shadowcolor,
											transp,
											textcoefftransp,
											p_font,
											texte,
											forbiddenchar)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CObjectEditText");
#endif
//***********************************

	if (ObjFlags&CT_EDITLINE)
		TEXTtexte->CrunchText(TEXTwordwrap);

	TEXTFirstVisibleSubLine=EDTFirstSubLine=0;
	EDTBeginSubLineSelect=EDTCurrentSubLine=0;
	EDTBeginSelectIndex=EDTCurrentIndex=0;
	
	EDTnbCharVisible=0;

	EDTCurrentHorizontalIndex=0;

	// Le curseur
	EDTcursorPreviousPosX=EDTcursorPosX=0;
	EDTcursorPosY=0;
	EDTcursorVisible=0;
	
	
	InitLayerCursor(textcolor,TEXTcyChar,textcoefftransp);
	
	// si le container possede une fenetre
	
	EDTpreviousCursor=0;
	if (EDTnbEdit==0)
		EDTibeamCursor=cont->GetPtrWindow()!=NULL?(cont->GetPtrWindow())->CrCursor(IDC_IBEAM):0;
	
	// Les Timers
	EDTtimerCursorID=-1;
	EDTtimerScrollID=-1;
	EDTtimerScrollDir=0;

	EDTselect=0;
	
	EDTlayerSelect=new Layer(ObjW,ObjH,select_color,1);
	EDTlayerSelect->Transparency=NO_TRANSPARENCY;
	EDTlayerSelect->clearAlphaLayer(Rect2D(0,0,ObjW,ObjH));	

	EDTselectColor=select_color;
	EDTselectCoeff=coeff_transp;
		
	EvalCursorPosition(p_font);

	EDTnbEdit++;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CObjectEditText end");
#endif
//***********************************

}









CObjectEditText::~CObjectEditText()
{

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::~CObjectEditText");
#endif
//***********************************

	EDTnbEdit--;
	if (EDTtimerCursorID!=-1)
		Container()->Unregister(EDTtimerCursorID);
	StopScroll(SCROLL_V|SCROLL_H);
	if (ObjLayer!=NULL)
		ObjLayer->removeAllNext();
	delete(EDTlayerCursor);
	delete(EDTlayerSelect);
	if (EDTnbEdit==0 && EDTibeamCursor && Container()->GetPtrWindow()!=NULL)
		Container()->GetPtrWindow()->DsCursor(EDTibeamCursor);

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::~CObjectEditText end");
#endif
//***********************************
		
}













int CObjectEditText::EDTnbEdit=0;
int CObjectEditText::EDTibeamCursor=0;;

int CObjectEditText::IsMouseOnObject(int x,int y, int p_tab)
{
	return 1;
}


int CObjectEditText::CursorMove(int x,int y,int keyFlags, int p_tab,int redrawobject)
{
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	int x_inobj=x-ObjX;
	int y_inobj=y-ObjY;
	int i=y_inobj/TEXTcyChar;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CursorMove");
#endif
//***********************************

	if (EDTtimerCursorID!=-1 && (keyFlags&MK_LBUTTON) !=0) 
	{
		Container()->Unregister(EDTtimerCursorID);	

		// le positionnement vertical avec possibilité de scroll
		// vers le bas ou vers la gauche
		EDTCurrentSubLine=i+TEXTFirstVisibleSubLine;
#if DEBUG_OBJTEXT		
		MMechostr(1,"CursorMove:nombre de lignes %d %d\n",EvalNbVisibleSubLine(TEXTFirstVisibleSubLine),TEXTnbVisibleSubLines);
#endif
		/*int last_visi_sub=TEXTFirstVisibleSubLine+EvalNbVisibleSubLine(TEXTFirstVisibleSubLine);
		int lasth=TEXTtexte->TILsubline[last_visi_sub].stringh;
		if (TEXTFirstVisibleSubLine>0 && y_inobj<TEXTtexte->TILsubline[TEXTFirstVisibleSubLine].stringh/2)
		*/
		if (TEXTFirstVisibleSubLine>0 && y_inobj<TEXTcyChar/2)
		{
			if (IsScroll(SCROLL_V))
			{
				EDTCurrentSubLine--;
				EDTCurrentIndex=SearchIndex(x_inobj,EDTCurrentSubLine,p_font);
			}
			StartScroll(SCROLL_V);
		}
		else if (EDTCurrentSubLine<(TEXTtexte->getNbLines()-1) && y_inobj>((int)TEXTnbVisibleSubLines-0.5)*TEXTcyChar)
		/*else if (EDTCurrentSubLine<(TEXTtexte->TILsize-1) && 
			     y_inobj>(TEXTtexte->TILsubline[last_visi_sub].postop-			//y_inobj > demi hauteur de la derniere
						  TEXTtexte->TILsubline[TEXTFirstVisibleSubLine].postop+//sous-ligne visible
						  lasth/2
						 )
				)
		*/
		{
			if (IsScroll(SCROLL_V))
			{
				
				EDTCurrentSubLine++;
				EDTCurrentIndex=SearchIndex(x_inobj,EDTCurrentSubLine,p_font);
			}
			StartScroll(SCROLL_V);
		}
		else if (EDTCurrentSubLine>=TEXTtexte->getNbLines())
		{
			EDTCurrentSubLine=TEXTtexte->getNbLines()-1;
			EDTCurrentIndex=TEXTtexte->getLen();
			StopScroll(SCROLL_V);
		}
		else
		{
			EDTCurrentIndex=SearchIndex(x_inobj,EDTCurrentSubLine,p_font);
			EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
			StopScroll(SCROLL_V);
		}
		
		if (!TEXTwordwrap &&!IsScroll(SCROLL_V))
		{
			unsigned int first=TEXTtexte->getInfoLine(EDTCurrentSubLine).first;
			unsigned int last=first+TEXTtexte->getInfoLine(EDTCurrentSubLine).nCount;
			unsigned int searchlastindex=SearchIndex(ObjW-10,EDTCurrentSubLine,p_font);
			unsigned int searchfirstindex=SearchIndex(10,EDTCurrentSubLine,p_font);
			unsigned int realfirstindex=SearchIndex(0,EDTCurrentSubLine,p_font);
			unsigned int reallastindex=SearchIndex(ObjW,EDTCurrentSubLine,p_font);
			unsigned int tmpindex;

			if (TEXTHorizontalScrollBarIndex>0 && 
				EDTCurrentIndex<=searchfirstindex
			   )
			{
				
				if (IsScroll(SCROLL_H) && (tmpindex=TEXTtexte->PreviousIndex(realfirstindex))>=first)
						EDTCurrentIndex=tmpindex;
				StartScroll(SCROLL_H);
			}
			else if (
					 EDTCurrentIndex<last && 
					 EDTCurrentIndex>=searchlastindex
					)
			{
					
				if (IsScroll(SCROLL_H) && (tmpindex=TEXTtexte->NextIndex(reallastindex))<=last)
						EDTCurrentIndex=tmpindex;
				StartScroll(SCROLL_H);
			}
			else
				StopScroll(SCROLL_H);
		}

		CenterOnCursor(0,p_tab);
				
		
		EDTFirstSubLine=TEXTFirstVisibleSubLine;
		EvalCursorPosition(p_font);

		if (EDTcursorPosY+TEXTcyChar>ObjH)
		//if (EDTcursorPosY+lasth>ObjH)
		{
			// au cas ou le texte soit tronqué en bas
			EDTFirstSubLine=GoDown(1,p_tab,1);
			EvalCursorPosition(p_font);
		}
		

		EDTcursorVisible=1;
		EDTselect=1;
		EvalSelectedZone(p_font);
		
		EDTtimerCursorID=Container()->Register(TIMER_CURSOR,this);
		
		if (redrawobject) Redraw();
		RepaintLinkedScroll();
	}	

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CursorMove end");
#endif
//***********************************

	return 0;
}









int CObjectEditText::CursorMoveIn(int x,int y,int keyFlags, int p_tab,int redrawobject)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CursorMoveIn");
#endif
//***********************************
	ChangeCursorToBeam();	
	return 0;
}





int CObjectEditText::CursorMoveInWithBtnPushed(int x,int y,int keyFlags, int p_tab,int redrawobject)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CursorMoveInWithBtnPushed");
#endif
//***********************************
	ChangeCursorToBeam();
	StopScroll(SCROLL_V|SCROLL_H);
	return 0;
}





int CObjectEditText::CursorMoveOut(int x,int y,int keyFlags, int p_tab,int redrawobject)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CursorMoveOut");
#endif
//***********************************
	RetrieveDefaultCursor();	
	StopScroll(SCROLL_V|SCROLL_H);
	return 0;
}






int CObjectEditText::CursorMoveOutWithBtnPushed(int x,int y,int keyFlags, int p_tab,int redrawobject)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CursorMoveOutWithBtnPushed");
#endif
//***********************************
	RetrieveDefaultCursor();
	return 0;
}









int CObjectEditText::CursorMoveOutsideWithBtnPushed(int x,int y,int keyFlags, int p_tab,int redrawobject)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CursorMoveOutsideWithBtnPushed");
#endif
//***********************************
	
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	
	int x_inobj=x-ObjX;
	int y_inobj=y-ObjY;
	
	if (EDTtimerCursorID!=-1 && (keyFlags&MK_LBUTTON) !=0) 
	{
		Container()->Unregister(EDTtimerCursorID);	
		
		// evaluation de la ligne courante et de la premiere visible
		if (y_inobj<=0)
		{
			// curseur au dessus			
			int i,j;	
			if (i=min(abs(y_inobj)/TEXTcyChar+1,(int)EDTCurrentSubLine))
			{
				if (IsScroll(SCROLL_V))
				{
					if (j=min(i,(int)TEXTFirstVisibleSubLine))
						EDTFirstSubLine=GoUp(j,p_tab,1);
					EDTCurrentSubLine-=i;
				}
				StartScroll(SCROLL_V);
			}
			else
				StopScroll(SCROLL_V);

			
		}
		else if (y_inobj>=(int)TEXTnbVisibleSubLines*TEXTcyChar)
		{
			int i,j;
			if (i=min(abs(y_inobj-ObjH)/TEXTcyChar+1,(int)TEXTtexte->getNbLines()-(int)EDTCurrentSubLine-1))
			{
				if (IsScroll(SCROLL_V))
				{
					EDTCurrentSubLine+=i;
					if (j=min(i,(int)TEXTtexte->getNbLines()-(int)TEXTFirstVisibleSubLine-(int)TEXTnbVisibleSubLines))
						EDTFirstSubLine=GoDown(j,p_tab,1);
				}
				StartScroll(SCROLL_V);
			}
			else
				StopScroll(SCROLL_V);

		}
		else
		{
			
			// curseur au milieu 
			EDTCurrentSubLine=(y_inobj/TEXTcyChar)+TEXTFirstVisibleSubLine;
			if (y_inobj<5 && TEXTFirstVisibleSubLine>0)
			{
				if (IsScroll(SCROLL_V))
				{
					EDTCurrentSubLine--;
					EDTFirstSubLine=GoUp(1,p_tab,1);
				}
				StartScroll(SCROLL_V);
			}
			else if (y_inobj>(int)(TEXTnbVisibleSubLines-1)*TEXTcyChar && EDTCurrentSubLine<(TEXTtexte->getNbLines()-1) )
			{
				if (IsScroll(SCROLL_V))
				{
					EDTCurrentSubLine++;
					EDTFirstSubLine=GoDown(1,p_tab,1);
				}
				StartScroll(SCROLL_V);
			}
			else if (EDTCurrentSubLine>=TEXTtexte->getNbLines())
			{
				EDTCurrentSubLine=TEXTtexte->getNbLines()-1;
				EDTCurrentIndex=TEXTtexte->getLen();
				StopScroll(SCROLL_V);
			}
			else
			{
				EDTCurrentIndex=SearchIndex(x_inobj,EDTCurrentSubLine,p_font);
				EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
				StopScroll(SCROLL_V);
			}
		}
		
		// evaluation de l'index courant du curseur
		if (x_inobj<0)
			// curseur en debut de ligne
			EDTCurrentIndex=TEXTtexte->getInfoLine(EDTCurrentSubLine).first;
		else if(x_inobj>ObjW)
			// curseur en fin de ligne
			EDTCurrentIndex=TEXTtexte->getInfoLine(EDTCurrentSubLine).first+TEXTtexte->getInfoLine(EDTCurrentSubLine).nCount;
		else
				// curseur au milieu
			EDTCurrentIndex=SearchIndex(x_inobj,EDTCurrentSubLine,p_font);
		
		CenterOnCursor(0,p_tab);
		EDTFirstSubLine=TEXTFirstVisibleSubLine;
		EvalCursorPosition(p_font);

		if (EDTcursorPosY+TEXTcyChar>ObjH)
		{
			// au cas ou le texte soit tronqué en bas
			EDTFirstSubLine=GoDown(1,p_tab,1);
			EvalCursorPosition(p_font);
		}
		
		EvalSelectedZone(p_font);
		
		EDTcursorVisible=CursorIsVisible();
		
		EDTselect=1;
		EDTtimerCursorID=Container()->Register(TIMER_CURSOR,this);
	
		if (redrawobject) Redraw();
		RepaintLinkedScroll();
	}	

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CursorMoveOutsideWithBtnPushed end");
#endif
//***********************************

	return 0;
}










int CObjectEditText::ClickIn(int x,int y,int btn,int keyFlags, int p_tab,int redrawobject)
{
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	int x_inobj=x-ObjX;
	int y_inobj=y-ObjY;
	int shift=(int)(GetKeyState(VK_SHIFT)>>8)&1;


//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::ClickIn");
#endif
//***********************************

	if (btn==1)
	{
#if DEBUG_OBJTEXT		
		MMechostr(1,"ClickIn\n");
#endif
		if (EDTtimerCursorID!=-1)
			Container()->Unregister(EDTtimerCursorID);	
		
		EDTCurrentHorizontalIndex=TEXTHorizontalScrollBarIndex;
		
		
		//EDTCurrentSubLine=y_inobj/TEXTcyChar+TEXTFirstVisibleSubLine;
		// jos new
		EDTCurrentSubLine=SearchSubLine(y_inobj,TEXTFirstVisibleSubLine);
		EDTFirstSubLine=TEXTFirstVisibleSubLine;
		if (EDTCurrentSubLine>=TEXTtexte->getNbLines())
		{
				EDTCurrentSubLine=TEXTtexte->getNbLines()-1;
				EDTCurrentIndex=TEXTtexte->getLen();
		}
		else
		{
//				PtrObjFont font=GET_PTR_OBJ_FONT(p_font);
				
				EDTCurrentIndex=SearchIndex(x_inobj,EDTCurrentSubLine,p_font);
				EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
		}		
		
		
		EvalCursorPosition(p_font);
		
		// jos new
		//TEXTcyChar<->TEXTtexte->TILsubline[EDTCurrentSubLine].stringh
		if (EDTcursorPosY+TEXTtexte->getInfoLine(EDTCurrentSubLine).stringh>ObjH)
		{
			EDTFirstSubLine=GoDown(1,p_tab,1);
			EvalCursorPosition(p_font);
		}

		if (shift)
		{
			EDTselect=1;
			EvalSelectedZone(p_font);
		}
		else
		{
			EDTselect=0;
			EDTBeginSelectIndex=EDTCurrentIndex;
			EDTBeginSubLineSelect=EDTCurrentSubLine;
			EDTcursorPreviousPosX=EDTcursorPosX;
			EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);
		}
		
		
		EDTcursorVisible=1;
		
		EDTtimerCursorID=Container()->Register(TIMER_CURSOR,this);
		
		if (redrawobject)
		{
			RepaintLinkedScroll();
			Redraw();
		}
	}		

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::ClickIn end");
#endif
//***********************************

	return 0;
}










int CObjectEditText::UnClickIn(int x,int y,int btn,int keyFlags, int p_tab,int redrawobject)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::UnClickIn");
#endif
//***********************************
	StopScroll(SCROLL_V|SCROLL_H);
	return 0;
}
	



int CObjectEditText::ClickOut(int x,int y,int btn,int keyFlags, int p_tab,int redrawobject)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::ClickOut");
#endif
//***********************************

	if (EDTtimerCursorID!=-1)
		Container()->Unregister(EDTtimerCursorID);
	StopScroll(SCROLL_V|SCROLL_H);
	EDTtimerCursorID=-1;
	EDTcursorVisible=0;
	EDTselect=0;
	
	// recuperation du curseur
	Point2D curpos=(Container()->GetPtrWindow()!=NULL)?Container()->GetPtrWindow()->GetCursorPosClient():Point2D(0,0); 
	if ( (ObjFlags&(OBJ_DISABLE|OBJ_HIDE)) && IsPointInRectangle(curpos,RectangleIncludingObject()))
		RetrieveDefaultCursor();
	
	if (( ObjFlags&CT_EDITLINE || ObjFlags&CT_MULTIEDITLINE) && btn!=-1 && btn!=0 && TEXTclickvalidation&CT_VALIDCLICK) 
	   ExecuteReflexeValidation(CT_VALIDCLICK,redrawobject);
	else
	{
		Redraw();
		RepaintLinkedScroll();
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::ClickOut end");
#endif
//***********************************

	return 0;
}





int CObjectEditText::UnClickOut(int x,int y,int btn,int keyFlags, int p_tab,int redrawobject)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::UnClickOut");
#endif
//***********************************

	StopScroll(SCROLL_V|SCROLL_H);
	return 0;
}





int CObjectEditText::DblClickIn(int x,int y,int btn,int keyFlags, int p_tab,int redrawobject)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::DblClickIn");
#endif
//***********************************
	
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	int x_inobj=x-ObjX;
	int y_inobj=y-ObjY;
//	int shift=(int)(GetKeyState(VK_SHIFT)>>8)&1;

	if (btn==1)
	{
		if (EDTtimerCursorID!=-1)
			Container()->Unregister(EDTtimerCursorID);	
		
		EDTCurrentHorizontalIndex=TEXTHorizontalScrollBarIndex;

		EDTCurrentSubLine=y_inobj/TEXTcyChar+TEXTFirstVisibleSubLine;
		EDTFirstSubLine=TEXTFirstVisibleSubLine;
		if (EDTCurrentSubLine>=TEXTtexte->getNbLines())
		{
				EDTCurrentSubLine=TEXTtexte->getNbLines()-1;
				EDTCurrentIndex=TEXTtexte->getLen();
		}
		else
		{
//				PtrObjFont font=GET_PTR_OBJ_FONT(p_font);
				
				EDTCurrentIndex=SearchIndex(x_inobj,EDTCurrentSubLine,p_font);
				EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
		}		
		
		if (_istspace(TEXTtexte->getText()[EDTCurrentIndex]) || EDTCurrentIndex==(unsigned int)TEXTtexte->getLen())
		{
			EDTselect=0;
			EDTBeginSelectIndex=EDTCurrentIndex;
			EDTBeginSubLineSelect=EDTCurrentSubLine;
			EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);
			
			CenterOnCursor(0,p_tab);
			EvalCursorPosition(p_font);
			
			if (EDTcursorPosY+TEXTcyChar>ObjH)
			{
				EDTFirstSubLine=GoDown(1,p_tab,1);
				EvalCursorPosition(p_font);
			}
			EDTcursorPreviousPosX=EDTcursorPosX;
		}
		else
		{
			
			// evaluation du debut de la selection
			
			EDTBeginSelectIndex=PreviousWord(TEXTtexte->getText(),EDTCurrentIndex);
			EDTBeginSubLineSelect=TEXTtexte->SearchSubLineInTab(EDTBeginSelectIndex);		
			EDTcursorPreviousPosX=EvalPositionInHref(EDTBeginSelectIndex,EDTBeginSubLineSelect);

			// evaluation de la position du curseur
			EDTCurrentIndex=NextWord(TEXTtexte->getText(),EDTCurrentIndex);
			EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
			
			if (EDTCurrentSubLine-TEXTFirstVisibleSubLine>=TEXTnbVisibleSubLines)
			{
				int i=0;
				while ( EDTCurrentSubLine-(TEXTFirstVisibleSubLine+i)>=TEXTnbVisibleSubLines) i++;
				EDTFirstSubLine=GoDown(i,p_tab,1);
			}
			
			CenterOnCursor(0,p_tab);
			EvalCursorPosition(p_font);
			
			if (EDTcursorPosY+TEXTcyChar>ObjH)
			{
				EDTFirstSubLine=GoDown(1,p_tab,1);
				EvalCursorPosition(p_font);
			}

			EDTselect=1;

			EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);

			EvalSelectedZone(p_font);
		
		}		
		
		EDTcursorVisible=1;
		
		EDTtimerCursorID=Container()->Register(TIMER_CURSOR,this);
		
		if (redrawobject) Redraw();
		RepaintLinkedScroll();
	}		

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::DblClickIn end");
#endif
//***********************************

	return 0;

}










int CObjectEditText::MouseWheel(int delta,int x,int y,int keyFlags,int p_tab,int redrawobject)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::MouseWheel");
#endif
//***********************************

	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
		
	if (delta<0 && (TEXTFirstVisibleSubLine+TEXTnbVisibleSubLines)<TEXTtexte->getNbLines())
	{
		int i=min(-delta,(int)TEXTtexte->getNbLines()-(int)TEXTnbVisibleSubLines-(int)TEXTFirstVisibleSubLine);
		if (i)
			GoDown(i,p_tab,1);
	}
	else if (delta>0 && TEXTFirstVisibleSubLine>0)
	{
		int i=min(delta,(int)TEXTFirstVisibleSubLine);
		if (i)
			GoUp(i,p_tab,1);	
	}
	else
		return 0;


	EvalCursorPosition(p_font);
			
	if (!CursorIsVisible())
		EDTcursorVisible=0;
			

	if (EDTselect)
		EvalSelectedZone(p_font);
	
	if ( redrawobject )
	{
		RepaintLinkedScroll();
		Redraw();
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::MouseWheel end");
#endif
//***********************************

	return 0;

}





int CObjectEditText::KeyUp(UINT vk,int cRepeat, UINT flags, int p_tab)
{	
	return 0;
}




int CObjectEditText::KeyDown(UINT vk,int keysys,int cRepeat, UINT flags, int p_tab)
{
	int type_reflexe=0;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyDown");
#endif
//***********************************
#if DEBUG_OBJTEXT
	MMechostr(MSKTRACE,"********************>KeyDown\nkey pressed:%d %d;%s \n",vk,EDTCurrentIndex,TEXTtexte);
#endif

	switch(vk)
	{
		
		// les touches F1-F12
		case XK_F1:
		case XK_F2:
		case XK_F3:
		case XK_F4:
		case XK_F5:
		case XK_F6:
		case XK_F7:
		case XK_F8:
		case XK_F9:
		case XK_F10:
		case XK_F11:
		case XK_F12:
		case XK_F13:
		case XK_F14:
		case XK_F15:
		case XK_F16:
		//Page Down
		case XK_Next:
		//Page Up
		case XK_Prior:
		case XK_Num_Lock:
		case XK_Scroll_Lock:
		case XK_Caps_Lock:
		case XK_Pause:
		// Esc
		case 27:
			break;
		

		// select all
		case 1:
			if ((type_reflexe=KeySelectAll(p_tab))==-1) return 0;
			break;
		
		// copy
		case 3:
			if ((type_reflexe=KeyCopy(p_tab))==-1) return 0;
			break;
		
		// paste
		case 22:
			if ((type_reflexe=KeyPaste(p_tab))==-1) return 0;
			break;
		
		// cut
		case 24:
			if ((type_reflexe=KeyCut(p_tab))==-1) return 0;
			break;
		
		// debut
		case XK_Home:
			if ((type_reflexe=KeyHome(p_tab))==-1) return 0;
			break;
		
		//fin
		case XK_End:
			if ((type_reflexe=KeyEnd(p_tab))==-1) return 0;
			break;
		
		// insert
		case XK_Insert:
			if ((type_reflexe=KeyInsert(p_tab))==-1) return 0;
			break;

		// arrow left
		case XK_Left:
			if ((type_reflexe=KeyArrowLeft(p_tab))==-1) return 0;
			break;

		// arrow right
		case XK_Right:
			if ((type_reflexe=KeyArrowRight(p_tab))==-1) return 0;
			break;			
		
		// arrow up
		case XK_Up:
			if ((type_reflexe=KeyArrowUp(p_tab))==-1) return 0;
			break;

		// arrow down
		case XK_Down:
			if ((type_reflexe=KeyArrowDown(p_tab))==-1) return 0;
			break;
		
		// delete
		case XK_Delete:
			if ((type_reflexe=KeySuppress(p_tab))==-1) return 0;	
			break;
		
		// backspace
		case 8:
			if ((type_reflexe=KeyBackspace(p_tab))==-1) return 0;
			break;
		
		// tts le reste
		default:
			if ((type_reflexe=KeyChar(vk,p_tab))==-1) return 0;
			break;
	}
	
	// fin du traitement + execution des possibles reflexes
	EndKey(type_reflexe);

#if DEBUG_OBJTEXT
	MMechostr(MSKTRACE,"********************>Fin KeyDown:%d %d\n",EDTCurrentIndex,EDTCurrentSubLine);
#endif
	return 0;

}





int CObjectEditText::SetFocus(int reset,int p_tab,int redraw)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::SetFocus");
#endif
//***********************************
	
	if (EDTtimerCursorID!=-1)
		Container()->Unregister(EDTtimerCursorID);	
	
	if (reset)
	{
		EDTCurrentIndex=0;	
		EDTCurrentSubLine=0;
		EDTBeginSelectIndex=EDTBeginSubLineSelect=0;	
		EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);
			
		if (!CenterOnCursor(0,p_tab))
		{
			ClearAllText(p_tab);
			DrawObjectText(TEXTFirstVisibleSubLine);
		}	
	}
	
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));	
	EvalCursorPosition(p_font);	
	
	EDTcursorVisible=1;
	EDTtimerCursorID=Container()->Register(TIMER_CURSOR,this);
		
	if (redraw)
	{
			RepaintLinkedScroll();
			Redraw();
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::SetFocus end");
#endif
//***********************************
	return 0;
}






int CObjectEditText::KillFocus(int p_tab,int redraw)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KillFocus");
#endif
//***********************************
	
	if (EDTtimerCursorID!=-1)
		Container()->Unregister(EDTtimerCursorID);
	StopScroll(SCROLL_V|SCROLL_H);
	EDTtimerCursorID=-1;
	EDTcursorVisible=0;
	EDTselect=0;
	
	Redraw();
	RepaintLinkedScroll();
	
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KillFocus end");
#endif
//***********************************

	return 0;
}










int CObjectEditText::Timer( int timerID )
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::Timer");
#endif
//***********************************
	
	if (timerID==EDTtimerCursorID)
	{
		if (CursorIsVisible())
		{
			EDTcursorVisible=!EDTcursorVisible;
			Redraw();
		}
		else
		{
			if (EDTcursorVisible)
			{
				EDTcursorVisible=0;
				Redraw();
			}
		}
	}
	else if (timerID==EDTtimerScrollID)
	{
#if DEBUG_OBJTEXT
		MMechostr(1,"Timer Scroll\n");
#endif
		
		// on recupere les coordonées de la souris par rapport à la zone client
		Point2D P=Container()->GetCursorPosClient();
		if (P.iptX<ObjX || P.iptX>ObjX+ObjW || P.iptY<ObjY || P.iptY>ObjY+ObjH)
		{
			if ((Container()->CoCurrentKeyFlags & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON) )!=0)
				CursorMoveOutsideWithBtnPushed(P.iptX,P.iptY,Container()->CoCurrentKeyFlags,GetTab(mm,FindObjNodeFromHdlSys(mm,(int)this)),1);
		}
		else
			CursorMove(P.iptX,P.iptY,Container()->CoCurrentKeyFlags,GetTab(mm,FindObjNodeFromHdlSys(mm,(int)this)),1);
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::Timer end");
#endif
//***********************************

	return 0;
}








Layer *CObjectEditText::GetLayer(mmachine m,int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::GetLayer");
#endif
//***********************************
	
	if (ObjLayer==NULL) return NULL;

	ObjLayer->removeAllNext();
	ObjLayer->sourceRect = Rect2D(0,0,ObjW-1,ObjH-1);

	if (EDTcursorVisible)
	{
		ObjLayer->addLayer(EDTlayerCursor);
		EDTlayerCursor->Xdecal=EDTcursorPosX;
		EDTlayerCursor->Ydecal=EDTcursorPosY;
	}
	if (EDTselect)
		ObjLayer->addLayer(EDTlayerSelect);

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::GetLayer end");
#endif
//***********************************

	return ObjLayer;
}






Layer *CObjectEditText::GetLayerPart(mmachine m,Rect2D *paintrect,int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::GetLayerPart");
#endif
//***********************************
	
	if (ObjLayer==NULL) return NULL;

	// on cherche quelle est la sous-bitmap de l'objet	
	ObjLayer->removeAllNext();
	ObjLayer->sourceRect = IntersectionRectangle(
									Rect2D	(
												0,
												0,
												ObjW,
												ObjH
											),
									*paintrect
								  );
	if (EDTcursorVisible)
	{
		ObjLayer->addLayer(EDTlayerCursor);
		EDTlayerCursor->Xdecal=EDTcursorPosX-paintrect->RctHG.iptX;
		EDTlayerCursor->Ydecal=EDTcursorPosY-paintrect->RctHG.iptY;
	}
	if (EDTselect)
	{
		ObjLayer->addLayer(EDTlayerSelect);
		EDTlayerSelect->sourceRect=ObjLayer->sourceRect;
		EDTlayerSelect->Xdecal=0;
		EDTlayerSelect->Ydecal=0;
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::GetLayerPart end");
#endif
//***********************************
	return ObjLayer;
}









int CObjectEditText::DestroyAllLayers()
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::DestroyAllLayers");
#endif
//***********************************
	CObjectText::DestroyAllLayers();
	delete(EDTlayerSelect);
	EDTlayerSelect=NULL;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::DestroyAllLayers end");
#endif
//***********************************
	return 0;
}






int CObjectEditText::ResizeLayer(int w,int h,int p_tab)
{	
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::ResizeLayer");
#endif
//***********************************
	CObjectText::ResizeLayer(w,h,p_tab);
	
	// creation du nouveau layer de selection
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	EDTlayerSelect=new Layer(ObjW,ObjH,EDTselectColor,1);
	EDTlayerSelect->Transparency=NO_TRANSPARENCY;
	EvalSelectedZone(p_font);
	
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::ResizeLayer end");
#endif
//***********************************
	return 0;
}










// pour les liens entre objets
int CObjectEditText::handle(CObjMessage* msg)
{
	int direction, value, redrawobject;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::handle");
#endif
//***********************************

	switch(msg->GetType())
	{
	case LINK_MOVE:
		//recherche les informations du message
		direction = (int)(static_cast <CObjMessageMove*> (msg))->GetDirection();
		value =		(int)(static_cast <CObjMessageMove*> (msg))->GetOffset();
		redrawobject = msg->GetRedrawObject();
		
		//traite les informations du message
		if ( direction == DIR_VERTICAL || direction == -DIR_VERTICAL)
		{
			int p_tab=GetTab(mm,FindObjNodeFromHdlSys(mm,(int)this));			
			int p_font=MTOP(MMfetch(mm,p_tab,FONT));
			if ( direction == DIR_VERTICAL )
			{
				if (value>0)
					GoDown(value,p_tab,0);
				else
					GoUp(-value,p_tab,0);
			}
			else // direction == -DIR_VERTICAL
			{
				if (value>0)
					GoUp(value,p_tab,0);
				else
					GoDown(-value,p_tab,0);
			}
			
			EvalCursorPosition(p_font);
			
			if (!CursorIsVisible())
				EDTcursorVisible=0;
			
			if (EDTselect)
				EvalSelectedZone(p_font);
		}
		else if (!TEXTwordwrap && (direction == DIR_HORIZONTAL || direction == -DIR_HORIZONTAL) )
		{
			int p_tab=GetTab(mm,FindObjNodeFromHdlSys(mm,(int)this));			
			int p_font=MTOP(MMfetch(mm,p_tab,FONT));
			if ( direction == DIR_HORIZONTAL )
			{
				if (value>0)
					GoRight(value,p_tab,0);
				else
					GoLeft(-value,p_tab,0);
			}
			else // direction == -DIR_HORIZONTAL
			{
				if (value>0)
					GoLeft(value,p_tab,0);
				else
					GoRight(-value,p_tab,0);
			}
			
			EvalCursorPosition(p_font);
			
			if (!CursorIsVisible())
				EDTcursorVisible=0;
			
			if (EDTselect)
				EvalSelectedZone(p_font);
		}

		if ( redrawobject )
			Redraw();

		break;
	case LINK_STRING_SELECT:
	{
		char *texte;
		int len;
		len = strlen( (char *)(static_cast <CObjMessageStringSelect*> (msg))->GetString() );
		texte=(char *)malloc(sizeof(char)*(len+1));
		memcpy(texte,(char *)(static_cast <CObjMessageStringSelect*> (msg))->GetString(),len+1);
		
		// solution pour le combo un petit peu porc
		int p_tab=GetTab( mm, FindObjNodeFromHdlSys( mm, (int)this ) );
		int p_font=MTOP(MMfetch(mm,p_tab,FONT));
		PtrObjFont font=GET_PTR_OBJ_FONT(p_font);
		
		int col,coeff,sf,sc;
		TEXTtexte->RetrieveCharParam(0,&col,&coeff,&sf,&sc);
		this->SetText( texte,
					   font,
					   col,
					   coeff,
					   sf,
					   sc,
					   CT_NOCHANGE, p_tab );
		free(texte);
		if ( msg->GetRedrawObject() )
			Redraw();

		break;
	}
	default:
		break;
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::handle end");
#endif
//***********************************

	return 0;
}




int CObjectEditText::supports( int type )
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::supports");
#endif
//***********************************

	return ( type == LINK_MOVE || type == LINK_STRING_SELECT || type == LINK_RESIZE);
}










//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                    LES FONCTIONS INTERNES DE L'EDITTEXT                                                                  //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int CObjectEditText::RemoveSelectedZone(int FirstIndex,int LastIndex,int execwordwrap)
{

	int res;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::RemoveSelectedZone");
#endif
//***********************************

	if (FirstIndex>LastIndex)
		res=RemoveSelectedZone(LastIndex,FirstIndex,execwordwrap);
	else
	{
		if ((res=TEXTtexte->DeleteSubString(FirstIndex,LastIndex,execwordwrap))!=-1)
		{
			EDTBeginSelectIndex=EDTCurrentIndex=res;
			EDTBeginSubLineSelect=EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
			EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);
		}
	}


//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::RemoveSelectedZone end");
#endif
//***********************************
	return res;

}






int  CObjectEditText::CopyToClipboard()
{

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CopyToClipboard");
#endif
//***********************************
	if (!(ObjFlags&CT_PASSWORD))
	{
		int min,max,len;
	
#if DEBUG_OBJTEXT
		MMechostr(1,"CObjectEditText::CopyToClipboard --> EDTBeginSelectIndex:%d EDTCurrentIndex:%d\n",EDTBeginSelectIndex,EDTCurrentIndex);
#endif
	
		if (EDTBeginSelectIndex>EDTCurrentIndex)
		{
			min=EDTCurrentIndex;
			max=EDTBeginSelectIndex;
		}
		else
		{
			min=EDTBeginSelectIndex;
			max=EDTCurrentIndex;
		}
		if ((len=max-min)==0) return 0;
    
		// on evalue la nouvelle chaine au format windows
		char *temp=ReplaceRByRn(TEXTtexte->getText()+min,len);
		if (Container()->GetPtrWindow()!=NULL) 
			Container()->GetPtrWindow()->CopyToClipBoard(temp);
		free(temp);
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CopyToClipboard end");
#endif
//***********************************
	return 0;

}








int  CObjectEditText::PasteFromClipboard(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::PasteFromClipboard");
#endif
//***********************************
	
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));

	if (Container()->GetPtrWindow()!=NULL)
	{
		char * lpdata,*clip;
		if ((clip=Container()->GetPtrWindow()->GetFromClipBoard())!=NULL)
		{
			// on supprime la zone selectionnée
			if (EDTselect) RemoveSelectedZone(EDTBeginSelectIndex,EDTCurrentIndex,0);
			
			TEXTtexte->InsertSubString(lpdata=ReplaceRnByR(clip),EDTCurrentIndex,1);
			free(clip);

			// on cruch le texte s'il est trop long
			if (ObjFlags&CT_EDITLINE) 
				TEXTtexte->CrunchText(TEXTwordwrap);
			

			SetScrollNbLines(1);
			SetScrollNbColonnes(1);

			EDTCurrentIndex+=strlen(lpdata);
			EDTCurrentIndex=min(TEXTtexte->getLen(),EDTCurrentIndex);
			EDTBeginSelectIndex=EDTCurrentIndex;
			EDTBeginSubLineSelect=EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
			EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);

			free(lpdata);

			if (!CenterOnCursor(0,p_tab))
			{
//				int clearall=EDTCurrentSubLine-EDTFirstSubLine>=TEXTnbVisibleSubLines?1:0;
				while (EDTCurrentSubLine-EDTFirstSubLine>=TEXTnbVisibleSubLines)
						TEXTFirstVisibleSubLine=++EDTFirstSubLine;

				ClearAllText(p_tab);
				DrawObjectText(EDTFirstSubLine);
				
			}
			EvalCursorPosition(p_font);
			EDTcursorPreviousPosX=EDTcursorPosX;
			EDTselect=0;
			
		}
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::PasteFromClipboard end");
#endif
//***********************************
	return 0;

}









void CObjectEditText::ChangeCursorToBeam()
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::ChangeCursorToBeam");
#endif
//***********************************
	if (Container()->GetPtrWindow()!=NULL)
		EDTpreviousCursor=Container()->GetPtrWindow()->ChangeCursor(EDTibeamCursor);
}





void CObjectEditText::RetrieveDefaultCursor()
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\n CObjectEditText::RetrieveDefaultCursor");
#endif
//***********************************
	if (Container()->GetPtrWindow()!=NULL)
		Container()->GetPtrWindow()->ChangeCursor(EDTpreviousCursor);
}



	
// Initialise le layerCursor
void CObjectEditText::InitLayerCursor(int color,int size,int coefftransp)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::InitLayerCursor");
#endif
//***********************************

	EDTlayerCursorSize=size;
	EDTlayerCursorCoeffTransp=coefftransp;
	EDTlayerCursorColor=color;
	EDTlayerCursor=new Layer(SIZECURSOR,EDTlayerCursorSize,color,EDTlayerCursorCoeffTransp!=255);
	EDTlayerCursor->Transparency=NO_TRANSPARENCY;
	if (EDTlayerCursorCoeffTransp!=255)
		EDTlayerCursor->fillAlphaLayer (EDTlayerCursorCoeffTransp);

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::InitLayerCursor end");
#endif
//***********************************
}






// cree le layerCursor
void CObjectEditText::CreateLayerCursor(int color,int size)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CreateLayerCursor");
#endif
//***********************************
	
	if (color!=EDTlayerCursorColor || size!=EDTlayerCursorSize)
	{
		if (ObjLayer!=NULL)
			ObjLayer->removeAllNext();	// on vire touts les layers!!!! pour que le GetLayer ne plante pas
										// avec le changement de reference de LayerCursor
		delete(EDTlayerCursor);
		InitLayerCursor(color,size,EDTlayerCursorCoeffTransp);
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CreateLayerCursor end");
#endif
//***********************************
}
	




void CObjectEditText::EvalCursorPosition(int p_font)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::EvalCursorPosition");
#endif
//***********************************
	
	CreateLayerCursor(TEXTtexte->GetTextColor(EDTCurrentIndex),TEXTtexte->GetLayerFont(EDTCurrentIndex)->CLFaverageCharHeight);
	
	EDTcursorPosX=EvalPositionInHref(EDTCurrentIndex,EDTCurrentSubLine);
	
	EDTcursorPosY=TEXTtexte->getInfoLine(EDTCurrentSubLine).postop-TEXTtexte->getInfoLine(TEXTFirstVisibleSubLine).postop
		         +TEXTtexte->getInfoLine(EDTCurrentSubLine).posbaseline-TEXTtexte->GetLayerFont(EDTCurrentIndex)->CLFascent;
	
#if DEBUG_OBJTEXT
	MMechostr(1,"CursorPosition:%d %d\n",EDTcursorPosX,EDTcursorPosY);
#endif
}





void CObjectEditText::EvalSelectedZone(int p_font)
{

	int firstx,lastx;
	unsigned int firstsubline,lastsubline;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::EvalSelectedZone");
#endif
//***********************************

	int previousx_in_new_ref=EDTcursorPreviousPosX;
	
	if (!TEXTwordwrap)
		// on reevalue la coordonnée du debut de selection car elle a pu changer
		previousx_in_new_ref=EvalPositionInHref(EDTBeginSelectIndex,EDTBeginSubLineSelect);

	// on clear toute l'ancienne selection
	EDTlayerSelect->clearAlphaLayer(Rect2D(0,0,ObjW,ObjH));	

	// on evalue quelle est la ligne la plus haute et les differentes valeurs		
	if (EDTCurrentSubLine==EDTBeginSubLineSelect)
	{
		if (EDTcursorPosX>previousx_in_new_ref)
		{
			firstx=previousx_in_new_ref;
			lastx=EDTcursorPosX;
		}
		else
		{
			firstx=EDTcursorPosX;
			lastx=previousx_in_new_ref;
		}
		firstsubline=lastsubline=EDTCurrentSubLine;
	}
	else if (EDTCurrentSubLine>EDTBeginSubLineSelect)
	{
		firstx=previousx_in_new_ref;
		lastx=EDTcursorPosX;
		
		firstsubline=EDTBeginSubLineSelect;
		lastsubline=EDTCurrentSubLine;
	}
	else
	{
		firstx=EDTcursorPosX;
		lastx=previousx_in_new_ref;
		
		firstsubline=EDTCurrentSubLine;
		lastsubline=EDTBeginSubLineSelect;
	}

#if DEBUG_OBJTEXT
	MMechostr(1,"EvalSelectedZone:firstx:%d lastx:%d firstsubline:%d lastsubline:%d\n",firstx,lastx,firstsubline,lastsubline);
#endif

	// creation du layer de Selection
	if (lastsubline<TEXTFirstVisibleSubLine || 
		firstsubline>=(TEXTFirstVisibleSubLine+TEXTnbVisibleSubLines)
	   )
		return;

	if (firstx<0) firstx=0;
	
	if (lastx>ObjW) lastx=ObjW-1;
		
	if (firstsubline==lastsubline)
	{
		int y=(firstsubline-TEXTFirstVisibleSubLine)*TEXTcyChar;
		EDTlayerSelect->fillPartAlphaLayer(EDTselectCoeff,Rect2D(firstx,y,lastx,y+TEXTcyChar));
	}
	else if (lastsubline==TEXTFirstVisibleSubLine)
	{
		if ((firstx=EvalPositionInHref(TEXTtexte->getInfoLine(TEXTFirstVisibleSubLine).first,TEXTFirstVisibleSubLine))<0)
			firstx=0;
		
		EDTlayerSelect->fillPartAlphaLayer(EDTselectCoeff,Rect2D(firstx,0,lastx,TEXTcyChar));
	}
	else
	{
		int lastposx,firstposx,y,i;

		if (firstsubline<TEXTFirstVisibleSubLine)
		{
			i=0;
			y=0;
			
			firstsubline=TEXTFirstVisibleSubLine;

			if ((firstposx=EvalPositionInHref(TEXTtexte->getInfoLine(TEXTFirstVisibleSubLine).first,TEXTFirstVisibleSubLine))<0)
				firstposx=0;

		}
		else
		{
			i=(firstsubline-TEXTFirstVisibleSubLine);
			y=i*TEXTcyChar;
			firstposx=firstx;
		}

		do
		{
			// evaluation de la position du dernier charactere de la sous-ligne i+TEXTFirstVisibleSubLine
			if ((lastposx=EvalPositionInHref(TEXTtexte->getInfoLine(i+TEXTFirstVisibleSubLine).first+TEXTtexte->getInfoLine(i+TEXTFirstVisibleSubLine).nCount,
					                         i+TEXTFirstVisibleSubLine
											)
				)>ObjW)
				lastposx=ObjW-1;
			
			EDTlayerSelect->fillPartAlphaLayer(EDTselectCoeff,Rect2D(firstposx,y,lastposx,y+TEXTcyChar<ObjH?y+TEXTcyChar:ObjH));
			
			firstsubline++;
			i++;
			
			// evaluation de la posiiton du premier charactere de la nouvelle sous-ligne à traiter
			if ((firstposx=EvalPositionInHref(TEXTtexte->getInfoLine(i+TEXTFirstVisibleSubLine).first,i+TEXTFirstVisibleSubLine))<0)
				firstposx=0;
			
			y+=TEXTcyChar;
		
		} while ( firstsubline<lastsubline && y<ObjH);
		
		if (firstsubline==lastsubline && y<ObjH)
			EDTlayerSelect->fillPartAlphaLayer(EDTselectCoeff,Rect2D(firstposx,y,lastx,y+TEXTcyChar<ObjH?y+TEXTcyChar:ObjH));
	}


//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::EvalSelectedZone end");
#endif
//***********************************
}







// Evalue la coordonée x dans le referentiel visible
int CObjectEditText::EvalPositionInHref(unsigned int index,unsigned int subline)
{
	// on recalcule les coordonées du debut de selection dans le nouveau
	// referentiel
	int w,h,res;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::EvalPositionInHref");
#endif
//***********************************

	int first=TEXTtexte->getInfoLine(subline).first;
	TEXTtexte->GetStringWidthHeight(first,index-first,1,&w,&h);
	res=EvalDecalageFlags(subline)+w;
	
	if (res==ObjW)
		res--;

	return res;
}






// Evalue la coordonée y dans le referentiel visible
int CObjectEditText::EvalPositionInVref(unsigned int firstsubline,unsigned int subline)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::EvalPositionInVref");
#endif
//***********************************
	return TEXTtexte->getInfoLine(subline).postop-TEXTtexte->getInfoLine(firstsubline).postop;
}
	





void CObjectEditText::EdtClearText(int p_tab,int always)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::EdtClearText");
#endif
//***********************************
	
	int decal=EDTCurrentSubLine-TEXTFirstVisibleSubLine;
	if (decal>0 || always)
	{	
		int t=((decal>0)?(decal-1):decal);
#if DEBUG_OBJTEXT
		MMechostr(1,"Clear:%d %d %d\n",ObjW,t*TEXTcyChar,ObjH);
#endif
		if (ObjLayer!=NULL)
			ObjLayer->fillPartLayer( ObjTransparency,Rect2D(0,t*TEXTcyChar,ObjW,ObjH) );
	}
}





int CObjectEditText::CenterOnCursor(int suppress,int p_tab)
{	
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CenterOnCursor");
#endif
//***********************************
	
	int res=0;
	if (!TEXTwordwrap)
	{
		//////////
		// le deplacement horizontal
		//////////
		int w,h;
		unsigned int first=TEXTtexte->getInfoLine(EDTCurrentSubLine).first;
//		unsigned int count=TEXTtexte->TILsubline[EDTCurrentSubLine].nCount;
		int			 decalage=EvalDecalageFlags(EDTCurrentSubLine);

		TEXTtexte->GetStringWidthHeight(first,EDTCurrentIndex-first,1,&w,&h);
		if (decalage+w<0)
		{
			if (TEXTtexte->getInfoLine(EDTCurrentSubLine).stringw-w>ObjW)
				// le charactere possede des characteres suivants qui rentrent
				// nickel chrome dans la zone visible donc on positionnem le charactere
				// en premiere position
				EDTCurrentHorizontalIndex=GoLeft(-decalage-w,p_tab,1);
			else
			{
				// le charactere ne possede pas de characteres suivants qui rentrent
				// nickel chrome dans la zone visible donc on essaye d'en case le plus
				// possible
#if DEBUG_OBJTEXT
				MMechostr(1,"CenterOnCursor::Left Actu\n");
#endif
				unsigned int i=EDTCurrentIndex;
				int wtemp=w;
				while (i>first && w-wtemp<ObjW)
				{
					i=TEXTtexte->PreviousIndex(i);
					TEXTtexte->GetStringWidthHeight(first,i-first,1,&wtemp,&h);
				}
				EDTCurrentHorizontalIndex=GoLeft(-decalage-wtemp,p_tab,1);
			}
			res=1;
		}
		else if (decalage+w>ObjW)
		{
			EDTCurrentHorizontalIndex=GoRight(decalage+w-ObjW,p_tab,1);
			res=1;
		}
		else if (suppress && EDTCurrentHorizontalIndex>0 && decalage+TEXTtexte->getInfoLine(EDTCurrentSubLine).stringw<ObjW)
		{
#if DEBUG_OBJTEXT
			MMechostr(1,"CenterOnCursor::Left suppress\n");
#endif
			EDTCurrentHorizontalIndex=GoLeft(min(EDTCurrentHorizontalIndex,-decalage-TEXTtexte->getInfoLine(EDTCurrentSubLine).stringw+ObjW),p_tab,1);
			res=1;
		}
	}

	//////////
	// la barre verticale
	//////////
	
	if (EDTCurrentSubLine<TEXTFirstVisibleSubLine)
	{
#if DEBUG_OBJTEXT
		MMechostr(1,"CenterOnCursor::VCourante\n");
#endif
		// on remonte la barre au niveau de la ligne courante
		if (EDTCurrentSubLine+TEXTnbVisibleSubLines<=TEXTtexte->getNbLines())
			// la sous-ligne a des sous-ligne suibvantes qui sont toutes visibles donc on la positionne en premiere
			// visible
			EDTFirstSubLine=GoUp(TEXTFirstVisibleSubLine-EDTCurrentSubLine,p_tab,1);
		else
		{
#if DEBUG_OBJTEXT
			MMechostr(1,"CenterOnCursor::VCourante Reeval\n");	
#endif
			// la sous-ligne et les sous-lignes suivantes sont - nombreuses que le nombre de lignes visibles
			// donc on essaye d'en caser le plus possible
			int i=0;
			while (EDTCurrentSubLine-i>0 && EDTCurrentSubLine-i+TEXTnbVisibleSubLines>TEXTtexte->getNbLines()) i++;
			EDTFirstSubLine=GoUp(TEXTFirstVisibleSubLine-EDTCurrentSubLine+i,p_tab,1);
		}
#if DEBUG_OBJTEXT
		MMechostr(1,"CenterOnCursor::End VCourante\n");
#endif
		res=1;
	}
	else if ((TEXTFirstVisibleSubLine+TEXTnbVisibleSubLines)<=EDTCurrentSubLine)
	{	// on descend la barre verticale
		int i=0;
		while ((TEXTFirstVisibleSubLine+TEXTnbVisibleSubLines+i)<=EDTCurrentSubLine) i++;
		EDTFirstSubLine=GoDown(i,p_tab,1);
		res=1;
	}
	
	else if (suppress && TEXTFirstVisibleSubLine>0 && TEXTFirstVisibleSubLine+TEXTnbVisibleSubLines>TEXTtexte->getNbLines())
	{
#if DEBUG_OBJTEXT
			MMechostr(1,"CenterOnCursor::Vsupp\n");
#endif
			// on vient de supprimer un certain nombre de lignes mais la Ligne courante est tjs la meme
			// dans ce cas on scroll en fontction du nombre de sous-lignes apres EDTCurrentSubLine visibles
			int i=max((int)TEXTFirstVisibleSubLine-max(0,(int)TEXTtexte->getNbLines()-(int)TEXTnbVisibleSubLines),1);
			EDTFirstSubLine=GoUp(i,p_tab,1);
			res=1;
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CenterOnCursor end");
#endif
//***********************************

	return res;
}





// Evalue la coordonée x dans le referentiel visible
int  CObjectEditText::SearchIndex(int x,int SubLine,int p_font)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::SearchIndex");
#endif
//***********************************
	
	int first=TEXTtexte->getInfoLine(SubLine).first;
	int count=TEXTtexte->getInfoLine(SubLine).nCount;
	
	return TEXTtexte->SearchIndexInTab(x-EvalDecalageFlags(SubLine),first,first+count);

}





// Evalue la coordonée y dans le referentiel visible
int CObjectEditText::SearchSubLine(int y,int FirstSubLine)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::SearchSubLine");
#endif
//***********************************
	int i=FirstSubLine;
	int h=TEXTtexte->getInfoLine(i).stringh;
	while (i<(int)TEXTtexte->getNbLines()-1 && h<y)
		h+=TEXTtexte->getInfoLine(++i).stringh;
	return i;
}





void CObjectEditText::SetPositionCursorAndScroll(int scrolltype,int suppress,int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::SetPositionCursorAndScroll");
#endif
//***********************************
	
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));

	switch(scrolltype)
	{
		case CT_NOCHANGE:
		{
			int i=0;
			
			if (EDTCurrentIndex>(unsigned int)TEXTtexte->getLen())
			{
				EDTBeginSelectIndex=EDTCurrentIndex=TEXTtexte->getLen();	
				EDTBeginSubLineSelect=EDTCurrentSubLine=TEXTtexte->getNbLines()-1;
				EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);
			}
			
			while ((TEXTFirstVisibleSubLine-i+TEXTnbVisibleSubLines)>(TEXTtexte->getNbLines()-1) && (TEXTFirstVisibleSubLine-i)>0) i++;
			if (i)
			{
				TEXTFirstVisibleSubLine-=i;
				SetScrollPositionVertical(i,-1,1);
			}

			if (TEXTHorizontalScrollBarIndex>TEXTnbHorizontalScrollBarPos)
				EDTCurrentHorizontalIndex=TEXTHorizontalScrollBarIndex=TEXTnbHorizontalScrollBarPos;
			ClearAllText(p_tab);
			DrawObjectText(TEXTFirstVisibleSubLine);
			
			break;

		}
		case CT_BEGIN:
		{
			EDTCurrentIndex=0;	
			EDTCurrentSubLine=0;
			EDTBeginSelectIndex=EDTBeginSubLineSelect=0;	
			EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);
			
			if (!CenterOnCursor(suppress,p_tab))
			{
				ClearAllText(p_tab);
				DrawObjectText(TEXTFirstVisibleSubLine);
			}
			break;
		}
		case CT_END:
		{			
			
			EDTBeginSelectIndex=EDTCurrentIndex=TEXTtexte->getLen();	
			EDTBeginSubLineSelect=EDTCurrentSubLine=TEXTtexte->getNbLines()-1;
			EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);
			
			if (!CenterOnCursor(suppress,p_tab))
			{
				ClearAllText(p_tab);
				DrawObjectText(TEXTFirstVisibleSubLine);
			}
			break;
		}
	}
		
	EvalCursorPosition(p_font);			
	EDTcursorPreviousPosX=EDTcursorPosX;
	EDTselect=0;
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::SetPositionCursorAndScroll end");
#endif
//***********************************

}






// renvoie 1 si le curseur est visible dans le referentiel courant
// 0 sinon	
int CObjectEditText::CursorIsVisible()
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::CursorIsVisible");
#endif
//***********************************
	
	int diff=(int)EDTCurrentSubLine-(int)TEXTFirstVisibleSubLine;
	return ( diff>=0 &&
			 diff<(int)TEXTnbVisibleSubLines && 
			 ( TEXTwordwrap ||
			   (!TEXTwordwrap && EDTcursorPosX>=0 && EDTcursorPosX<=ObjW)
			 )
		   );
}






void CObjectEditText::StartScroll(int dir)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::StartScroll");
#endif
//***********************************
	
	if (EDTtimerScrollID==-1)
		EDTtimerScrollID=Container()->Register(TIMER_SCROLL,this);
	EDTtimerScrollDir|=dir;	
}





void CObjectEditText::StopScroll(int dir)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::StopScroll");
#endif
//***********************************
	
	EDTtimerScrollDir&=(0xFFFF-dir);

	if (EDTtimerScrollID!=-1 && !EDTtimerScrollDir)
	{
		Container()->Unregister(EDTtimerScrollID);	
		EDTtimerScrollID=-1;
	}
}






int	CObjectEditText::IsScroll(int dir)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::IsScroll");
#endif
//***********************************

	return (EDTtimerScrollID!=-1 && EDTtimerScrollDir&dir);
}





int CObjectEditText::ExecuteReflexeChange(int redrawobject)
{
	int k;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::ExecuteReflexeChange");
#endif
//***********************************

	k=OBJbeginreflex(mm,OBJNODE,(int)this,RFLOBJNODE_CHANGE);
	if (k>0) return 1; 
	if (k==0)
	{
		if (redrawobject && IsObjectRepaintBeforeCallback())
			Redraw();
		RepaintLinkedScroll();
		return OBJcallreflex(mm,0);
	}
	else if (redrawobject)
	{
		Redraw();
		RepaintLinkedScroll();
	}


//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::ExecuteReflexeChange end");
#endif
//***********************************
	return 0;
}









int CObjectEditText::ExecuteReflexeValidation(int type,int redrawobject)
{
	int k,tmp_res;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::ExecuteReflexeValidation");
#endif
//***********************************

	k=OBJbeginreflex(mm,OBJNODE,(int)this,RFLOBJNODE_VALIDATION);
	if (k>0) return 1; 
	if (k==0)
	{
		if (redrawobject && IsObjectRepaintBeforeCallback())
			Redraw();
		RepaintLinkedScroll();
		
		int p;
		char *p_c;
		int len=TEXTtexte->getLen();
		
		if ((p=MMmalloc(mm,STR_SIZE(len),TYPEBUF))<0) return p;
		MMstore(mm,p,0,len);
		p_c=MMstartstr(mm,p);
		memcpy(p_c,TEXTtexte->getRealText(),len);
		p_c[len]=0;
		CHECK(MMpush(mm,ITOM(type)));
		CHECK(MMpush(mm,PTOM(p)));
		return OBJcallreflex(mm,2);
	}
	else if (redrawobject)
	{
		Redraw();
		RepaintLinkedScroll();
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::ExecuteReflexeValidation end");
#endif
//***********************************
	return 0;

}






//////////////////////////////////////////////////////////////////////////////////////////
// Les differentes methodes relatives à un evenement clavier							//
//////////////////////////////////////////////////////////////////////////////////////////
// select all text
int CObjectEditText::KeySelectAll(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeySelectAll");
#endif
//***********************************
	
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));

	EDTCurrentIndex=0;	
	EDTCurrentSubLine=0;
	EDTnbCharVisible=0;
	
	CenterOnCursor(0,p_tab);

	EDTBeginSelectIndex=TEXTtexte->getLen();	
	EDTBeginSubLineSelect=TEXTtexte->getNbLines()-1;

	EDTcursorPreviousPosX=EvalDecalageFlags(EDTBeginSubLineSelect)+
				          TEXTtexte->getInfoLine(EDTBeginSubLineSelect).stringw;
	
	// on decale au cas ou le curseur est en fin de texte
	if (EDTcursorPreviousPosX==ObjW)
		EDTcursorPreviousPosX--;

	
	EvalCursorPosition(p_font);
	EDTselect=1;
	EvalSelectedZone(p_font);


//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeySelectAll end");
#endif
//***********************************
	return 0;

}







// copy
int CObjectEditText::KeyCopy(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyCopy");
#endif
//***********************************

	if (EDTselect)
		CopyToClipboard();
	return 0;
}





// cut
int CObjectEditText::KeyCut(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyCut");
#endif
//***********************************
	
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	
	if (EDTselect)
	{
		CopyToClipboard();
		int res;
		if ((res=RemoveSelectedZone(EDTBeginSelectIndex,EDTCurrentIndex,1))!=-1)
		{	
			// le scrollbar
			SetScrollNbLines(1);
			SetScrollNbColonnes(1);
			if (!CenterOnCursor(1,p_tab))
			{
				EdtClearText(p_tab,1);
				DrawObjectText(EDTCurrentSubLine);
			}
			
			EvalCursorPosition(p_font);
			EDTcursorPreviousPosX=EDTcursorPosX;
			EDTselect=0;

			return 1;
		}
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyCut end");
#endif
//***********************************
	return 0;

}








// paste
int CObjectEditText::KeyPaste(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyPaste");
#endif
//***********************************
	if (EDTselect)
	{
		int res;
		if ((res=RemoveSelectedZone(EDTBeginSelectIndex,EDTCurrentIndex,1))!=-1)
		{

			// les scrollbars	
			SetScrollNbColonnes(1);
			SetScrollNbLines(1);
			CenterOnCursor(1,p_tab);
		}
	}
	PasteFromClipboard(p_tab);


//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyPaste end");
#endif
//***********************************
	return 1;
}





// home
int CObjectEditText::KeyHome(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyHome");
#endif
//***********************************

	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	int shift=(int)(GetKeyState(VK_SHIFT)>>8)&1;
	int ctrl=(int)(GetKeyState(VK_CONTROL)>>8)&1;
	
	if (ctrl)
	{
		EDTCurrentIndex=0;	
		EDTCurrentSubLine=0;
	}
	else
		EDTCurrentIndex=TEXTtexte->getInfoLine(EDTCurrentSubLine).first;
	
	CenterOnCursor(0,p_tab);
	EvalCursorPosition(p_font);
	
	if (shift)
	{
		EDTselect=1;
		EvalSelectedZone(p_font);
	}
	else
	{
		EDTBeginSelectIndex=EDTCurrentIndex;
		EDTBeginSubLineSelect=EDTCurrentSubLine;
		EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);
		EDTselect=0;
		EDTcursorPreviousPosX=EDTcursorPosX;

	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyHome end");
#endif
//***********************************
	return 0;
}





//end
int CObjectEditText::KeyEnd(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyEnd");
#endif
//***********************************
	
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	int shift=(int)(GetKeyState(VK_SHIFT)>>8)&1;
	int ctrl=(int)(GetKeyState(VK_CONTROL)>>8)&1;
	
	if (ctrl)
	{
		EDTCurrentIndex=TEXTtexte->getLen();	
		EDTCurrentSubLine=TEXTtexte->getNbLines()-1;
	}
	else
		EDTCurrentIndex=TEXTtexte->getInfoLine(EDTCurrentSubLine).first+TEXTtexte->getInfoLine(EDTCurrentSubLine).nCount;
	
	CenterOnCursor(0,p_tab);
	EvalCursorPosition(p_font);
	
	if (shift)
	{
		EDTselect=1;
		EvalSelectedZone(p_font);
	}
	else
	{
		EDTBeginSelectIndex=EDTCurrentIndex;
		EDTBeginSubLineSelect=EDTCurrentSubLine;
		EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);
		EDTselect=0;
		EDTcursorPreviousPosX=EDTcursorPosX;

	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyEnd end");
#endif
//***********************************
	return 0;
}






//insert
int CObjectEditText::KeyInsert(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyInsert");
#endif
//***********************************
	
	int shift=(int)(GetKeyState(VK_SHIFT)>>8)&1;
	int ctrl=(int)(GetKeyState(VK_CONTROL)>>8)&1;
	
	if (shift)
	{
		if (EDTselect)
		{
			int res;
			if ((res=RemoveSelectedZone(EDTBeginSelectIndex,EDTCurrentIndex,1))!=-1)
			{

				// les scrollbars	
				SetScrollNbColonnes(1);
				SetScrollNbLines(1);
				CenterOnCursor(1,p_tab);
			}
		}
		PasteFromClipboard(p_tab);
		return 1;
	}
	else if (ctrl)
		CopyToClipboard();
	

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyInsert end");
#endif
//***********************************
	return 0;
}










//arrow left
int CObjectEditText::KeyArrowLeft(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyArrowLeft");
#endif
//***********************************
	
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	int shift=(int)(GetKeyState(VK_SHIFT)>>8)&1;
	int ctrl=(int)(GetKeyState(VK_CONTROL)>>8)&1;
	
	if (EDTCurrentIndex==0)
	{
		// on ne bouge pas le curseur... au pire on centre sur le curseur si la barre a été deplacée
		if (CenterOnCursor(0,p_tab))
		{
			RepaintLinkedScroll();
			Redraw();
		}
		return -1;
	}
	else
	{
		if (ctrl)
			EDTCurrentIndex=PreviousWord(TEXTtexte->getText(),EDTCurrentIndex);
		else
			EDTCurrentIndex=TEXTtexte->PreviousIndex(EDTCurrentIndex);
	}
	EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
	
	CenterOnCursor(0,p_tab);
	
	EvalCursorPosition(p_font);

	if (shift)
	{
		EDTselect=1;
		EvalSelectedZone(p_font);
		EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);
	}
	else
	{
		EDTBeginSelectIndex=EDTCurrentIndex;
		EDTBeginSubLineSelect=EDTCurrentSubLine;
		EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);
		EDTselect=0;
		EDTcursorPreviousPosX=EDTcursorPosX;
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyArrowLeft end");
#endif
//***********************************
	return 0;
}









//arrow right
int CObjectEditText::KeyArrowRight(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyArrowRight");
#endif
//***********************************
	
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	int shift=(int)(GetKeyState(VK_SHIFT)>>8)&1;
	int ctrl=(int)(GetKeyState(VK_CONTROL)>>8)&1;
	
	if (EDTCurrentIndex==TEXTtexte->getLen())
	{
		// on ne bouge pas le curseur... au pire on centre sur le curseur si la barre a été deplacée
		if (CenterOnCursor(0,p_tab))
		{
			RepaintLinkedScroll();
			Redraw();
		}
		return -1;
	}
	else
	{
		if (ctrl)
			EDTCurrentIndex=NextWord(TEXTtexte->getText(),EDTCurrentIndex);
		else
			EDTCurrentIndex=TEXTtexte->NextIndex(EDTCurrentIndex);
	}

	EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
	
	// on recentre sur le curseur s'il y a lieu
	CenterOnCursor(0,p_tab);

	EvalCursorPosition(p_font);
	
	if (shift)
	{
		EDTselect=1;
		EvalSelectedZone(p_font);
		EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);
	}
	else
	{
		EDTBeginSelectIndex=EDTCurrentIndex;
		EDTBeginSubLineSelect=EDTCurrentSubLine;
		EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);
		EDTselect=0;
		EDTcursorPreviousPosX=EDTcursorPosX;
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyArrowRight end");
#endif
//***********************************
	return 0;
}










//arrow up
int CObjectEditText::KeyArrowUp(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyArrowUp");
#endif
//***********************************
	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	int shift=(int)(GetKeyState(VK_SHIFT)>>8)&1;
	
	if (EDTCurrentSubLine == 0)
	{
		// on ne bouge pas le curseur... au pire on centre sur le curseur si la barre a été deplacée
		if (CenterOnCursor(0,p_tab))
		{
			RepaintLinkedScroll();
			Redraw();
		}
		return -1;
	}
	else if ( EDTCurrentSubLine > 0 )
	{
		EDTCurrentSubLine--;
		
		EDTCurrentIndex=TEXTtexte->IndexFromCharacterVisible(EDTCurrentSubLine,EDTnbCharVisible);
		EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
		
		CenterOnCursor(0,p_tab);

		EvalCursorPosition(p_font);
	}
	if (shift)
	{
		EDTselect=1;
		EvalSelectedZone(p_font);
	}
	else
	{
		EDTBeginSelectIndex=EDTCurrentIndex;
		EDTBeginSubLineSelect=EDTCurrentSubLine;
		EDTselect=0;
		EDTcursorPreviousPosX=EDTcursorPosX;
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyArrowUp end");
#endif
//***********************************
	return 0;

}











//arrow down
int CObjectEditText::KeyArrowDown(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyArrowDown");
#endif
//***********************************

	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	int shift=(int)(GetKeyState(VK_SHIFT)>>8)&1;
	
	if (EDTCurrentSubLine == (TEXTtexte->getNbLines()-1))
	{
		// on ne bouge pas le curseur... au pire on centre sur le curseur si la barre a été deplacée
		if (CenterOnCursor(0,p_tab))
		{
			RepaintLinkedScroll();
			Redraw();
		}
		return 0;
	}
	else if ( EDTCurrentSubLine < (TEXTtexte->getNbLines()-1) )
	{
		EDTCurrentSubLine++;

		EDTCurrentIndex=TEXTtexte->IndexFromCharacterVisible(EDTCurrentSubLine,EDTnbCharVisible);
		EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
		
		CenterOnCursor(0,p_tab);

		EvalCursorPosition(p_font);
	}
	if (shift)
	{
		EDTselect=1;
		EvalSelectedZone(p_font);
	}
	else
	{
		EDTBeginSelectIndex=EDTCurrentIndex;
		EDTBeginSubLineSelect=EDTCurrentSubLine;
		EDTselect=0;
		EDTcursorPreviousPosX=EDTcursorPosX;
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyArrowDown end");
#endif
//***********************************
	return 0;
}








//delete
int CObjectEditText::KeySuppress(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeySuppress");
#endif
//***********************************

	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	int shift=(int)(GetKeyState(VK_SHIFT)>>8)&1;
	
	if (EDTselect)
	{
		if (shift)
			CopyToClipboard();

		int res;
		if ((res=RemoveSelectedZone(EDTBeginSelectIndex,EDTCurrentIndex,1))!=-1)
		{

			// les scrollbars	
			SetScrollNbColonnes(1);
			SetScrollNbLines(1);
			if (!CenterOnCursor(1,p_tab))
			{
				EdtClearText(p_tab,1);
				DrawObjectText(EDTCurrentSubLine);
			}
			
			// le curseur
			EvalCursorPosition(p_font);
			EDTcursorPreviousPosX=EDTcursorPosX;
			EDTselect=0;
			
		}
	}
	else
	{
		if (EDTCurrentIndex==TEXTtexte->getLen())
		{
			// on ne bouge pas le curseur... au pire on centre sur le curseur si la barre a été deplacée
			if (CenterOnCursor(1,p_tab))
			{
				RepaintLinkedScroll();
				Redraw();
			}
			return -1;
		}
		else
			TEXTtexte->DeleteSubString(EDTCurrentIndex,TEXTtexte->NextIndex(EDTCurrentIndex),1);

		EDTBeginSelectIndex=EDTCurrentIndex;
		EDTBeginSubLineSelect=EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
		EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);

		// les scrollbars
		SetScrollNbLines(1);
		SetScrollNbColonnes(1);

		if (!CenterOnCursor(1,p_tab))
		{
			EdtClearText(p_tab,1);
			DrawObjectText(EDTCurrentSubLine);
		}

		EvalCursorPosition(p_font);
		EDTcursorPreviousPosX=EDTcursorPosX;
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeySuppress end");
#endif
//***********************************
	return 1;
}








//suppres
int CObjectEditText::KeyBackspace(int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyBackspace");
#endif
//***********************************

	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
	
	if (EDTselect)
	{
		// on supprime la selection
		int res;
		if ((res=RemoveSelectedZone(EDTBeginSelectIndex,EDTCurrentIndex,1))!=-1)
		{
			// les scrollbars
			SetScrollNbLines(1);
			SetScrollNbColonnes(1);

			if (!CenterOnCursor(1,p_tab))
			{
				EdtClearText(p_tab,1);
				DrawObjectText(EDTCurrentSubLine);
			}

			EvalCursorPosition(p_font);
			EDTcursorPreviousPosX=EDTcursorPosX;
			EDTselect=0;

		}
	}
	else
	{					
		// on supprime un charactere 
		
		if (EDTCurrentIndex==0)
		{
			// on ne bouge pas le curseur... au pire on centre sur le curseur si la barre a été deplacée
			if (CenterOnCursor(1,p_tab))
			{
				RepaintLinkedScroll();
				Redraw();
			}
			return -1;
		}
		else
		{
			int tmp;					
			TEXTtexte->DeleteSubString(tmp=TEXTtexte->PreviousIndex(EDTCurrentIndex),EDTCurrentIndex,1);
			EDTCurrentIndex=tmp;
		}

		EDTBeginSelectIndex=EDTCurrentIndex;
		EDTBeginSubLineSelect=EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
		EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);

		// les scrollbars
		SetScrollNbLines(1);
		SetScrollNbColonnes(1);

		if (!CenterOnCursor(1,p_tab))
		{
			EdtClearText(p_tab,1);
			DrawObjectText(EDTCurrentSubLine);
		}
		
		EvalCursorPosition(p_font);
		EDTcursorPreviousPosX=EDTcursorPosX;
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyBackspace end");
#endif
//***********************************
	return 1;
}









//all other
int CObjectEditText::KeyChar(UINT vk,int p_tab)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyChar");
#endif
//***********************************

	int p_font=MTOP(MMfetch(mm,p_tab,FONT));
//	int shift=(int)(GetKeyState(VK_SHIFT)>>8)&1;
	int ctrl=(int)(GetKeyState(VK_CONTROL)>>8)&1;
	int alt=(int)(GetKeyState(VK_MENU)>>8)&1;

	if ( ( !ctrl || (ctrl&&alt) ) && 
		 (TEXTauthorizedChars==NULL || strchr(TEXTauthorizedChars,vk)!=NULL ) && 
		 strchr(TEXTforbiddenchar,vk)==NULL 
	   )
	{
		if (EDTselect) RemoveSelectedZone(EDTBeginSelectIndex,EDTCurrentIndex,0);
		
		// teste pour l'editline en wrap
		if (ObjFlags&CT_EDITLINE && TEXTwordwrap)
		{
			int w,h;
			TEXTtexte->GetStringWidthHeight(0,TEXTtexte->getLen(),1,&w,&h);
			if (w+TEXTtexte->GetLayerFont(TEXTtexte->getLen())->CLFaverageCharWidth>ObjW) return -1;
		}
		
		// insertion du charactere
		TEXTtexte->InsertChar(vk,EDTCurrentIndex,1);
		
		EDTBeginSelectIndex=++EDTCurrentIndex;
		EDTBeginSubLineSelect=EDTCurrentSubLine=TEXTtexte->SearchSubLineInTab(EDTCurrentIndex);
		EDTnbCharVisible=TEXTtexte->NumberCharacterVisible(EDTCurrentSubLine,EDTCurrentIndex);

		// le scrollbar
		SetScrollNbLines(1);
		SetScrollNbColonnes(1);

		if (!CenterOnCursor(0,p_tab))
		{
			EdtClearText(p_tab,1);
			DrawObjectText(EDTCurrentSubLine);
		}
		
		EvalCursorPosition(p_font);
		EDTcursorPreviousPosX=EDTcursorPosX;
		EDTselect=0;

		
		
		return 1;
	}
	else if ( ( !ctrl || (ctrl&&alt) ) && ObjFlags&CT_EDITLINE && vk==13)
		return 2;

	
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::KeyChar end");
#endif
//***********************************
	return 0;
}












// execution d'un reflexe suite au traitementd'une touche
void CObjectEditText::EndKey(int type)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::EndKey");
#endif
//***********************************

	/* le reflexe est envoye avant de repeindre pour pouvoir filtrer les caracteres frappes sans qu'ils s'affichent */
	if (type==1)
		ExecuteReflexeChange(1);
	else if (type==2 && TEXTclickvalidation&CT_VALIDENTER)
		ExecuteReflexeValidation(CT_VALIDENTER,1);
	else
	{
			Redraw();
			RepaintLinkedScroll();
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectEditText::EndKey end");
#endif
//***********************************
}

