#include "Macro.h"
#include "CObjectLabel.h"
#include "CObjMessageMove.h"			//pour la classe CObjMessageMove et les direction 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;

#define FONT 0



CObjectLabel::CObjectLabel(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
						  )
						  :CObjectText(cont,layer,x,y,w,h,flags,contflags,textcolor,shadowflag,shadowcolor,
						               transp,textcoefftransp,p_font,texte,forbiddenchar
									   )
{
}

CObjectLabel::~CObjectLabel()
{
}

int CObjectLabel::IsMouseOnObject(int x,int y, int p_tab)
{
	return 1;
}


int CObjectLabel::CursorMove(int x,int y,int keyFlags, int p_tab,int redrawobject)
{
	return 0;
}

//$BLG: v4.6a5 - Modif
/*
int CObjectLabel::CursorMoveIn(int x,int y,int keyFlags, int p_tab,int redrawobject)
{
	return 0;
}
*/
int CObjectLabel::CursorMoveIn(int x, int y, int keyFlags, int p_tab, int redrawobject)
{
	int k,mask,tmp_res;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\CObjectLabel::CursorMoveIn");
#endif
//***********************************

	//$BLG: Del
	//ROBstate=((ROBstate==STATE_OFF)?STATE_OFF_UNDISPLAYED:STATE_OFF);

	// appel du reflexe utilisateur s'il existe
	k=OBJbeginreflex(mm,OBJNODE,(int)this,RFLOBJNODE_CURSORMOVEIN);
	if (k>0) return 1; 
	if (k==0)
	{
		if (redrawobject && IsObjectRepaintBeforeCallback())
			Redraw();
	
		mask=keyFlags&(MK_CONTROL|MK_LBUTTON|MK_MBUTTON|MK_RBUTTON|MK_SHIFT);
		CHECK(MMpush(mm,ITOM(x)));
		CHECK(MMpush(mm,ITOM(y)));
		CHECK(MMpush(mm,ITOM(mask)));
		return OBJcallreflex(mm,3);
	}
	else if ( redrawobject )
		Redraw();

	return 0;
}

int CObjectLabel::CursorMoveInWithBtnPushed(int x,int y,int keyFlags, int p_tab,int redrawobject)
{
	return 0;
}

//$BLG: v4.6a5 - Modif
/*
int CObjectLabel::CursorMoveOut(int x,int y,int keyFlags, int p_tab,int redrawobject)
{
	return 0;
}
*/
int CObjectLabel::CursorMoveOut(int x, int y, int keyFlags, int p_tab, int redrawobject)
{
	int k,mask,tmp_res;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\CObjectLabel::CursorMoveOut");
#endif
//***********************************

	//$BLG: Del
	//ROBstate=((ROBstate==STATE_OFF)?STATE_OFF_UNDISPLAYED:STATE_OFF);

	// appel du reflexe utilisateur s'il existe
	k=OBJbeginreflex(mm,OBJNODE,(int)this,RFLOBJNODE_CURSORMOVEOUT);
	if (k>0) return 1; 
	if (k==0)
	{
		if (redrawobject && IsObjectRepaintBeforeCallback())
			Redraw();
	
		mask=keyFlags&(MK_CONTROL|MK_LBUTTON|MK_MBUTTON|MK_RBUTTON|MK_SHIFT);
		CHECK(MMpush(mm,ITOM(x)));
		CHECK(MMpush(mm,ITOM(y)));
		CHECK(MMpush(mm,ITOM(mask)));
		return OBJcallreflex(mm,3);
	}
	else if ( redrawobject )
		Redraw();

	return 0;
}


int CObjectLabel::CursorMoveOutWithBtnPushed(int x,int y,int keyFlags, int p_tab,int redrawobject)
{
	return 0;
}

int CObjectLabel::CursorMoveOutsideWithBtnPushed(int x,int y,int keyFlags, int p_tab,int redrawobject)
{
	return 0;
}

//$BLG: v4.6a5 - Modif
/*
int CObjectLabel::ClickIn(int x,int y,int btn,int keyFlags, int p_tab,int redrawobject)
{
	return 0;
}
*/
int CObjectLabel::ClickIn(int x,int y,int txt,int keyFlags, int p_tab,int redrawobject)
{
	int k,tmp_res,mask;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectLabel::ClickIn");
#endif
//***********************************

	k=OBJbeginreflex(mm,OBJNODE,(int)this,RFLOBJNODE_CLICK);
	if (k>0) return 1; 
	if (k==0)
	{
			mask=keyFlags&(MK_CONTROL|MK_LBUTTON|MK_MBUTTON|MK_RBUTTON|MK_SHIFT);
			CHECK(MMpush(mm,ITOM(x)));
			CHECK(MMpush(mm,ITOM(y)));
			CHECK(MMpush(mm,ITOM(txt)));
			CHECK(MMpush(mm,ITOM(mask)));
			return OBJcallreflex(mm,4);
	}

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectLabel::ClickIn end");
#endif
//***********************************

	return 0;
}

int CObjectLabel::UnClickIn(int x,int y,int btn,int keyFlags, int p_tab,int redrawobject)
{
	return 0;
}
	
int CObjectLabel::ClickOut(int x,int y,int btn,int keyFlags, int p_tab,int redrawobject)
{
	return 0;
}

int CObjectLabel::UnClickOut(int x,int y,int btn,int keyFlags, int p_tab,int redrawobject)
{
	return 0;
}

int CObjectLabel::DblClickIn(int x,int y,int btn,int keyFlags, int p_tab,int redrawobject)
{
	return 0;
}



int CObjectLabel::MouseWheel(int delta,int x,int y,int keyFlags,int p_tab,int redrawobject)
{
//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectLabel::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;

	if ( redrawobject )
	{
		RepaintLinkedScroll();
		Redraw();
	}
	return 0;
}

int CObjectLabel::KeyUp(UINT vk,int cRepeat, UINT flags, int p_tab)
{
	return 0;
}

int CObjectLabel::KeyDown(UINT vk,int keysys,int cRepeat, UINT flags, int p_tab)
{
	return 0;
}

int CObjectLabel::SetFocus(int reset,int p_tab,int redraw)
{
	return 0;
}

int CObjectLabel::KillFocus(int p_tab,int redraw)
{
	return 0;
}

int CObjectLabel::Timer( int timerID )
{
	return 0;
}





// pour les liens entre objets
int CObjectLabel::handle(CObjMessage* msg)
{
	int direction, value, redrawobject;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectLabel::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);
			}
		}
		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);
			}
		}
		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, "\nCObjectLabel::handle end");
#endif
//***********************************

	return 0;
}




int CObjectLabel::supports( int type )
{
	return ( type == LINK_MOVE || type == LINK_STRING_SELECT || type == LINK_RESIZE);
}






// centre la vue sur le charactere d'indice nIndex appartenant à
// la sous-ligne d'indice ndxSubLine
int  CObjectLabel::HorizontalCenterOnIndex(unsigned int nIndex,unsigned int ndxSubLine,int suppress,int p_tab)
{

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectLabel::HorizontalCenterOnIndex");
#endif
//***********************************

	int res=0;
	if (!TEXTwordwrap)
	{
		int w,h;
		unsigned int first=TEXTtexte->getInfoLine(ndxSubLine).first;
//		unsigned int count=TEXTtexte->TILsubline[ndxSubLine].nCount;
		int			 decalage=EvalDecalageFlags(ndxSubLine);

		TEXTtexte->GetStringWidthHeight(nIndex,nIndex-first,1,&w,&h);
		if (decalage+w<0)
		{
			if (TEXTtexte->getInfoLine(ndxSubLine).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
				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
				unsigned int i=nIndex;
				int wtemp=w;
				while (i>first && w-wtemp<ObjW)
				{
					i=TEXTtexte->PreviousIndex(i);
					TEXTtexte->GetStringWidthHeight(first,i-first,1,&wtemp,&h);
				}
				GoLeft(-decalage-wtemp,p_tab,1);
			}
			res=1;
		}
		else if (decalage+w>ObjW)
		{
			GoRight(decalage+w-ObjW,p_tab,1);
			res=1;
		}
		else if (suppress && TEXTHorizontalScrollBarIndex>0 && decalage+TEXTtexte->getInfoLine(ndxSubLine).stringw<ObjW)
		{
			GoLeft(min((int)TEXTHorizontalScrollBarIndex,-decalage-TEXTtexte->getInfoLine(ndxSubLine).stringw+ObjW),p_tab,1);
			res=1;
		}
	}


//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectLabel::HorizontalCenterOnIndex end");
#endif
//***********************************

	return res;
}





void CObjectLabel::SetPositionCursorAndScroll(int scrolltype,int suppress,int p_tab)
{

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectLabel::SetPositionCursorAndScroll");
#endif
//***********************************

	switch(scrolltype)
	{
		case CT_NOCHANGE:
		{
			int i=0;
			while ((TEXTFirstVisibleSubLine-i+TEXTnbVisibleSubLines)>(TEXTtexte->getNbLines()-1) && (TEXTFirstVisibleSubLine-i)>0) i++;
			if (i)
			{
				TEXTFirstVisibleSubLine-=i;
				SetScrollPositionVertical(i,-1,1);
			}

			if (TEXTHorizontalScrollBarIndex>TEXTnbHorizontalScrollBarPos)
				TEXTHorizontalScrollBarIndex=TEXTnbHorizontalScrollBarPos;
			
			ClearAllText(p_tab);
			DrawObjectText(TEXTFirstVisibleSubLine);
			break;
		}
		case CT_BEGIN:
		{
			TEXTFirstVisibleSubLine=0;
			SetScrollPositionVertical(TEXTVerticalScrollBarIndex,-1,1);
			
			if (!HorizontalCenterOnIndex(0,0,suppress,p_tab))
			{
				ClearAllText(p_tab);
				DrawObjectText(TEXTFirstVisibleSubLine);
			}
			break;
		}
		case CT_END:
		{
			int l;
			if ((l=TEXTtexte->getNbLines()-TEXTnbVisibleSubLines)<0)
				TEXTFirstVisibleSubLine=0;
			else
				TEXTFirstVisibleSubLine=l;	
			int diff=TEXTVerticalScrollBarIndex-TEXTtexte->getNbLines();
			SetScrollPositionVertical(abs(diff),diff>0?-1:1,diff>0?0:1);
			if (!HorizontalCenterOnIndex(TEXTtexte->getLen(),TEXTtexte->getNbLines()-1,suppress,p_tab))
			{
				ClearAllText(p_tab);
				DrawObjectText(TEXTFirstVisibleSubLine);
			}
			break;
		}
	}


//***********************************
#if DEBUG_LIB2D
MMechostr (0, "\nCObjectLabel::SetPositionCursorAndScroll end");
#endif
//***********************************
}