//
// Modifications History
//
//$ LB (13/06/2002)  : changed ObjBitmap management, according to the new ObjBitmap structure
//




#include <Tchar.h>
#include "CObjLayerFont.h"
#include "CObjectBase.h"



#define LF_LEFT			 (1<<(LAST_OBJ_FLAG+1))
#define LF_RIGHT		 (1<<(LAST_OBJ_FLAG+2))
#define LF_TOP			 (1<<(LAST_OBJ_FLAG+3))
#define LF_BOTTOM		 (1<<(LAST_OBJ_FLAG+4))
#define LF_H_CENTER		 (1<<(LAST_OBJ_FLAG+5))
#define LF_V_CENTER		 (1<<(LAST_OBJ_FLAG+6))


#if DEBUG_FONT
int CObjLayerFont::CLFnb=0;
#endif


//$BLG - v4.6a4
//Currently inactive function:
//- GetCharWidth should only be used if Font isn't TrueType (we now only use TT Fonts)
//- GetCharABCWidths should be the solution for TT Fonts but values are quite strange (or not using the proper dim mapping): 1Mpixels width for a char ???
/*
void BLG_GetCharWidth(HDC dc, int *tab)
{
	//ABC abc[256];
	//ABC abc;
	
	//GetCharABCWidths(dc, 0, 255, abc);   <- [256] tab version
	GetCharWidth(dc,0, 255, tab);
	for (int i=0;i<256;i++)
	{
		//GetCharABCWidths(dc, i, i, &abc);  <- single value version
		//tab[i] = abc[i].abcA + abc[i].abcB + abc[i].abcC; <- tab
		//tab[i] = abc.abcA + abc.abcB + abc.abcC;          <- single
	}	
}
*/

CObjLayerFontService Lib2dFontService;

CObjLayerFont::CObjLayerFont(PtrObjFont font)
{
	CLFnb=0;
	CLFfont=font;
	if (font!=NULL)
	{
		TEXTMETRIC tm;


		CLFdc = CreateCompatibleDC ( NULL ) ;                 
		CLFoldfont   = (HFONT)  SelectObject ( CLFdc , font->WHandler ) ;


		GetTextMetrics(CLFdc,&tm);
		CLFaverageCharHeight = tm.tmHeight + tm.tmExternalLeading;
		CLFaverageCharWidth  = tm.tmAveCharWidth;
		CLFdescent=tm.tmDescent;
		CLFascent=tm.tmAscent;

		// le tableau des tailles de characteres
		//$BLG - v4.6a4 - Restore
		GetCharWidth(CLFdc,0, 255, CLFcharWidths);
		//BLG_GetCharWidth(CLFdc, CLFcharWidths);

		// le tab
		CLFtabStop = LOWORD(GetTabbedTextExtent(CLFdc,_T("\t"), 1, 0, NULL));
		CLFid=(int)font->WHandler;
	}
	else
	{
		TEXTMETRIC tm;
		
		CLFdc = CreateCompatibleDC ( NULL ) ;                 
		CLFoldfont   = NULL;
		
		GetTextMetrics(CLFdc,&tm);
		CLFaverageCharHeight = tm.tmHeight + tm.tmExternalLeading;
		CLFaverageCharWidth  = tm.tmAveCharWidth;
		CLFdescent=tm.tmDescent;
		CLFascent=tm.tmAscent;

		// le tableau des tailles de characteres
		//$BLG - v4.6a4 - Restore
		GetCharWidth(CLFdc,0, 255, CLFcharWidths);
		//BLG_GetCharWidth(CLFdc, CLFcharWidths);

		// le tab
		CLFtabStop = LOWORD(GetTabbedTextExtent(CLFdc,_T("\t"), 1, 0, NULL));
		CLFid=0;
	}
#if DEBUG_FONT
	MMechostr(1,"Nbre de Fontes:%d\n",++CLFnb);
#endif
}

CObjLayerFont::~CObjLayerFont()
{
	CLFnb=0;
	if (CLFoldfont!=NULL)
		SelectObject ( CLFdc , CLFoldfont ) ;
	DeleteDC ( CLFdc ) ;
#if DEBUG_FONT
	MMechostr(1,"Nbre de Fontes:%d\n",--CLFnb);
#endif
}

//$BLG - v4.6a4
//New function removed from .h - Restoring former version
/*
int CObjLayerFont::BLG_GetStringWidth(char *txt,int nCount,int usetab)
{
	int w = 0;
	
	for (int i = 0; i < nCount; i++)
	{
		w += CLFcharWidths[txt[i]];
	}
	MMechostr(0,"$BLG 2: %d\n", w);
	return w;
}
*/

int CObjLayerFont::GetStringWidth(char *txt,int nCount,int usetab)
{
	return LOWORD(GetTabbedTextExtent(CLFdc,txt,nCount,usetab?1:0,usetab?&CLFtabStop:NULL));
}

int CObjLayerFont::GetStringHeight(char *txt,int nCount,int usetab)
{
	return HIWORD(GetTabbedTextExtent(CLFdc,txt,nCount,usetab?1:0,usetab?&CLFtabStop:NULL));
}

int CObjLayerFont::CopyStringOnLayer(Layer *layer,int x,int y,char *txt,int nCount,int color,int transp,int usetab,int multi)
{
	int oldsbk;
	HBITMAP OldBuffer ;
    UINT  OldAlignement;
	
	if (layer!=NULL)
	{
		OldBuffer = (HBITMAP)SelectObject (CLFdc , layer->RGBbitmap->DIBhandler ) ;        
		
		OldAlignement=SetTextAlign(CLFdc,TA_LEFT|(multi?TA_BASELINE:0));

		SetTextColor (CLFdc, color ) ;
		oldsbk = SetBkMode (CLFdc, TRANSPARENT ) ;       
		
		TabbedTextOut(CLFdc,x,y,txt,nCount,usetab?1:0,usetab?&CLFtabStop:NULL,0);

		SetBkMode ( CLFdc , oldsbk );
		OldBuffer = (HBITMAP)SelectObject ( CLFdc , OldBuffer ) ;
		SetTextAlign(CLFdc,OldAlignement);
		return 1;
	}
	return 0;
}

int CObjLayerFont::CopyStringOnRectLayer(Layer *layer,Rect2D rect,int Flags,char *txt,int nCount,int color,int transp,int usetab)
{
	int oldsbk;
	HBITMAP OldBuffer ;
    UINT  OldAlignement;
	
	if (layer!=NULL)
	{
		int x,y,w,h;
		SizeRectangle(rect,&w,&h);
		OldBuffer = (HBITMAP)SelectObject (CLFdc , layer->RGBbitmap->DIBhandler ) ;        
		
		x=rect.RctHG.iptX;
		y=rect.RctHG.iptY;

		// calcul de l'alignement
		if (Flags&LF_LEFT)
			x=rect.RctHG.iptX;
		
		if (Flags&LF_RIGHT)
			x=rect.RctBD.iptX-GetStringWidth(txt,nCount,usetab);	
		
		if (Flags&LF_H_CENTER)
			x=rect.RctHG.iptX+(w-GetStringWidth(txt,nCount,usetab))/2;
		
		if (Flags&LF_TOP)
			y=rect.RctHG.iptY;

		if (Flags&LF_BOTTOM)
			y=rect.RctBD.iptY-GetStringHeight(txt,nCount,usetab);

		if (Flags&LF_V_CENTER)
			y=rect.RctHG.iptY+(h-GetStringHeight(txt,nCount,usetab))/2;
		
		OldAlignement=SetTextAlign(CLFdc,TA_LEFT);

		SetTextColor (CLFdc, color ) ;
		oldsbk = SetBkMode (CLFdc, TRANSPARENT ) ;       
		
		TabbedTextOut(CLFdc,x,y,txt,nCount,usetab?1:0,usetab?&CLFtabStop:NULL,0);

		SetBkMode ( CLFdc , oldsbk ) ;
		OldBuffer = (HBITMAP)SelectObject ( CLFdc , OldBuffer ) ;
		SetTextAlign(CLFdc,OldAlignement);
		return 1;
	}
	return 0;
}

int CObjLayerFont::addRef()
{
	return (++CLFnb);
}

int CObjLayerFont::remRef()
{
	return (--CLFnb);
}



CObjLayerFontService::CObjLayerFontService()
{
	CLFnblayerFont=0;
	CLFlayerFont=(CObjLayerFont**)malloc(sizeof(CObjLayerFont*));
}

CObjLayerFontService::~CObjLayerFontService()
{
#if DEBUG_FONT
	MMechostr(1,"---Debug CObjLayerFontService::~CObjLayerFontService:%d\n",(int)this);
#endif
    CLFnblayerFont=0;
	free(CLFlayerFont);
}

int	CObjLayerFontService::findLayerFont(int id)
{
	int i=0;
	while (i<CLFnblayerFont)
	{
		if (CLFlayerFont[i]->CLFid==id) return i;
		i++;
	}
	return -1;
}

void CObjLayerFontService::addFont(CObjLayerFont* font)
{
	
	CLFlayerFont=(CObjLayerFont**)realloc(CLFlayerFont,sizeof(CObjLayerFont*)*(CLFnblayerFont+1));
	CLFlayerFont[CLFnblayerFont]=font;
	CLFnblayerFont++;
#if DEBUG_FONT
    MMechostr(1,"---Debug Ajout d'une fonte:%d total:%d\n",font->CLFid,CLFnblayerFont);
#endif
}

void CObjLayerFontService::delFont(CObjLayerFont* font)
{

	int pos=findLayerFont(font->CLFid);
	CObjLayerFont**tmp=(CObjLayerFont**)malloc(sizeof(CObjLayerFont*)*CLFnblayerFont);

	memcpy(tmp,CLFlayerFont,(sizeof(CObjLayerFont*)*pos));
	memcpy(tmp+pos,CLFlayerFont+pos+1,(sizeof(CObjLayerFont*)*(CLFnblayerFont-pos-1)));
	free(CLFlayerFont);
	CLFlayerFont=tmp;
	CLFnblayerFont--;
#if DEBUG_FONT
    MMechostr(1,"---Debug delFont %d total:%d\n",font->CLFid,CLFnblayerFont);
#endif
}

CObjLayerFont * CObjLayerFontService::getLayerFont(PtrObjFont font)
{
#if DEBUG_FONT
    MMechostr(1,"---Debug CObjLayerFontService:%d\n",(int)this);
    MMechostr(1,"---Debug getLayerFont    :%d total:%d\n",font==NULL?0:(int)font->WHandler,CLFnblayerFont);
#endif
    int pos=findLayerFont(font==NULL?0:(int)font->WHandler);
	CObjLayerFont * layer;
	
	if (pos==-1)
		addFont(layer=new CObjLayerFont(font));
	else
		layer=CLFlayerFont[pos];
	
	layer->addRef();
#if DEBUG_FONT	
    MMechostr(1,"---Debug getLayerFontEnd :%d total:%d\n",font==NULL?0:(int)font->WHandler,CLFnblayerFont);
#endif
	return layer;
}

int CObjLayerFontService::delLayerFont(CObjLayerFont * layer)
{
#if DEBUG_FONT
	MMechostr(1,"---Debug delLayerFont:%d total:%d\n",layer->CLFid,CLFnblayerFont);
#endif    
    int i=0;
	while (i<CLFnblayerFont)
	{
		if (CLFlayerFont[i]==layer)
		{
			
			if (CLFlayerFont[i]->remRef()==0)
			{
				delFont(layer);
				delete(layer);
			}
			return 1;
		}
		i++;
	}
	return 0;
}
	