#include "ts_font16.h"
#include "mrc_exb.h"
#include "mrc_bmp.h"


typedef struct fontPoint
{
	int32 fontHandle;	//字库点阵文件句柄（文件读取方式）

	int32 uIndexOff;	//unicode字库索引表在字库文件中的偏移
	int32 uIndexLen;	//unicode字库索引表长度
	uint8 *uIndexBuf;	//unicode字库索引表缓冲区地址，字库索引表是会加载到内存的

	int32 PointOff;		//字库点阵在字库文件中的偏移
	int32 PointLen;		//字库点阵长度
	uint8 *PointBuf;	//字库点阵缓冲区（内存加载方式）

	int32 GBWidth;		//GB单个字符宽度
	int32 AsciiWidth;	//ascii单个字符宽度
	int32 fontHeight;	//单个字符高度
}T_FONT_INFO, *PT_FONT_INFO;


#define FONT_DES		128
#define FILE_NAME		"font16.tsf"


static T_FONT_INFO		g_nowUse;		//当前使用的字库
static uint8			Buf[FONT_DES];  //字体点阵信息缓存
static uint16			scnw, scnh;		//屏幕尺寸
static uint8			enable;			//是否可用标志

#define MAKERGB(r, g, b)     (uint16) ( ((uint32)(r>>3) << 11) + ((uint32)(g>>2) << 5) + ((uint32)(b>>3)) )



//获取一个字符在字库点阵中的索引
static 
int32 GetOffSet(uint16 chr)
{	//flag TRUE 标识为UNICODE串，FALSE标识为GB串
	uint16 iM = 0;//(一个索引项含16位UNICODE值16位偏移量)
	uint16 iB = 1;
	uint16 iE = 0;
	int32 UValue = 0;
	int32 indexLen = 0;
	uint8 *buf = NULL;

	indexLen = g_nowUse.uIndexLen;
	buf = g_nowUse.uIndexBuf;

	iE = indexLen /5;
	while(iB <= iE)
	{
		iM = (iB + iE)/2;
		UValue = buf[(iM-1)*5];
		UValue = UValue << 8;
		UValue += buf[(iM-1)*5+1];

		if(chr == UValue)
		{
			UValue = buf[(iM-1)*5+2];
			UValue = UValue << 8;
			UValue += buf[(iM-1)*5+3];
			UValue = UValue << 8;
			UValue += buf[(iM-1)*5+4];

			return UValue;
		}
		else if(chr > UValue)
		{
			iB = iM+1;
		}
		else
		{
			iE = iM-1;
		}
	}

	return 0;
}

//获取字符点阵位图
static const 
uint8* GetUniBitmap(uint16 ch)
{
	int32 offset = GetOffSet(ch);

	if(offset == 0) {
		return GetUniBitmap(0x25a1);	//返回 □ 
	}

	mrc_memset(Buf, 0, FONT_DES);
	mrc_seek(g_nowUse.fontHandle, g_nowUse.PointOff + offset, MR_SEEK_SET);
	mrc_read(g_nowUse.fontHandle, Buf, FONT_DES);

	return (uint8*)Buf;
}

int32 tsf_drawTextLeft(uint8 *pcText, int16 x, int16 y, 
					   mr_screenRectSt rect, mr_colourSt colorst, uint16 flag)
{
	if (!enable || !pcText || rect.w == 0 || rect.h == 0) {
		return -1;
	}

	{
		uint16 ch;
		//uint8 a_ch[4] = {0};
		uint16* screenBuf = w_getScreenBuffer();
		const char *current_bitmap;
		uint8  *p = (uint8*)pcText;
		int16 chx=x,chy=y;
		int32 totalIndex,totalPoint,X1,Y1,index_I,index_J;
		uint8 temp = 0;
		uint16 color=MAKERGB(colorst.r, colorst.g, colorst.b);
		int32 right = rect.x+rect.w, btm = rect.y+rect.h;
		int32 fw, fh = g_nowUse.fontHeight, flen;
		int32 lines = 0;


		//生成unicode/GB编码值
		ch = (uint16) ((*p<<8)+*(p+1));

		while(ch)
		{
			if ((ch == 0x0a) || (ch == 0x0d))
			{//换行处理
				if(ch == 0x0d)	//移除第二个换行符
					p += 2;

				if(flag & TS_FT_CRLFNEWLINE) {
					chy += (fh + TS_FONT_VMARGIN);
					chx = x;
					lines++;
					goto sign;
				}else {
					//ch = 0x20;	//转为空格
					goto kongge;
				}
				
				//p += 2;//移除后一个空格
			}
			else if(ch == 0x20)
			{//空格处理
kongge:
				chx += g_nowUse.AsciiWidth;
				
				if( (chx > right)) {	//自动换行属性
					if((TS_FT_AUTONEWLINE & flag)){
						chy += (fh + TS_FONT_VMARGIN);
						chx = x;
						lines++;
					}else
						goto end;					
				}

				goto sign;
			}
			else
			{//其他字符
				current_bitmap = (char*)GetUniBitmap(ch);
				
				//if(!current_bitmap) return -1;	//没有这个字
				
				fw = *current_bitmap;		//字符宽
				flen = *(current_bitmap + 1);	//点阵字节数
				current_bitmap += 2;
			}

			if(chx > right && chy > btm)	//超出了绘制区域
				goto end;

			//测量换行
			if(((chx + fw) > right))
			{
				if(flag & TS_FT_AUTONEWLINE){
					chy += (fh + TS_FONT_VMARGIN);
					chx = x;
					lines++;
				}else
					goto end;				
			}

			//填充点阵
			if( ((chx + fw) <= right) 
				&& (chx >= rect.x) 
				&& ((chy + fh) <= btm) 
				&& (chy >= rect.y) 
				&& chx >= 0 
				&& chy >= 0)
			{
				totalPoint = fh * fw;
				X1 = Y1 = 0;
				totalIndex = 0;
				
				for ( index_I = 0; index_I < flen; index_I++)	//点阵占字节数
				{
					temp = current_bitmap[index_I];
					
					for (index_J = 0; index_J < 8; index_J++)
					{
						totalIndex++;
						
						if (temp & 0x80) {	//屏幕绘点
							*(screenBuf + (chy + Y1) * scnw + (chx + X1)) = color;
						}

						X1++;
						//if(!g_nowUse.fontWidth) return -1;

						if ((totalIndex % fw) == 0) {	//点阵换行
							Y1++;
							X1= 0;
						}

						if (totalIndex >= totalPoint)
							break;

						temp = temp << 1;
					}
				}
			}

			//累计宽度
			chx = chx + fw + TS_FONT_HMARGIN;
sign:
			p += 2; //下一个字符

			ch = (uint16)((*p<<8)+*(p+1));
		}

end:
		return ( ((lines<<20)&0xFFF00000) | (p-pcText) );
	}

	return 0;
}

//获取多行文本宽高
int32 tsf_textWidthHeightLines(uint8 *pcText, uint16 showWidth, 
							  int32 *width, int32 *height, int32 *lines)
{
	uint16 chU;
	int32 tempAdd = 0, tempWidth = 0;
	uint8* tempChr = (uint8*)pcText;
	uint8 *bmpPoint = NULL;
	int32 linewidth = showWidth;


	*width = *height = *lines = 0;

	if(!enable || !tempChr || showWidth == 0) {
		return -1;
	}

	chU = (uint16) ((*tempChr<<8)+*(tempChr+1));
		
	while(chU)
	{
		if(chU == 0x20)	//空格
		{
			tempAdd = g_nowUse.AsciiWidth;
						
			goto LineCheck;
		}
		else if(chU == 0x0a || chU == 0x0d)
		{
			goto NewLine;				
		}
		else
		{
			bmpPoint = (uint8*)GetUniBitmap(chU);
			tempAdd = (*bmpPoint + TS_FONT_HMARGIN);
		}
				
LineCheck:
		if(tempWidth + tempAdd > linewidth)
		{
NewLine:
			*width = (tempWidth>*width)? tempWidth : *width;
			*height += g_nowUse.fontHeight + TS_FONT_VMARGIN;

			(*lines)++;
			tempWidth = 0;
		}else{
			tempWidth += tempAdd;
		}

		//下一个字符
		tempChr +=  2;
		chU = (uint16) ((*tempChr<<8)+*(tempChr+1));
	}
	
	*height += g_nowUse.fontHeight + TS_FONT_VMARGIN;
	*width = (tempWidth>*width)? tempWidth : *width;
	(*lines)++;

	return MR_SUCCESS;
}

//获取单行文本宽高
int32 tsf_textWidthHeight(uint8 *pcText, int32 *width, int32 *height)
{
	uint16 chU;
	uint8* tempChr = (uint8*)pcText;
	uint8 *bmpPoint = NULL;

	if(!enable || !tempChr) {
		return -1;
	}

	*width = *height = 0;

	chU = (uint16) ((*tempChr<<8)+*(tempChr+1));

	while(chU)
	{
		
		if(chU == 0x20 || (chU == 0x0a) || (chU == 0x0d))	//不可显示的
		{
			*width += g_nowUse.AsciiWidth;
		}else{
			bmpPoint = (uint8*)GetUniBitmap(chU);
			*width += (*bmpPoint + TS_FONT_HMARGIN);
		}
		
		//if(chU < 0x80 && flag==MR_SET_GB)
		//{
		//	tempChr += 1;
		//}
		tempChr +=  2;
		chU = (uint16) ((*tempChr<<8)+*(tempChr+1));
	}
	
	*height = g_nowUse.fontHeight + TS_FONT_VMARGIN;	//包括间距
	
	return MR_SUCCESS;
}

void tsf_getSizeInfo(int32 *gbWidth, int32 *ascWidth, int32 *height){
	uint8 head[128] = {0};

	if(!enable) return;

	//读取字库头
	mrc_seek(g_nowUse.fontHandle, 0, MR_SEEK_SET);
	mrc_read(g_nowUse.fontHandle, head, 128);
	if(gbWidth) *gbWidth = head[28];
	if(ascWidth) *ascWidth = head[29];
	if(height) *height = head[30];
}

//初始化字库
int32 tsf_loadTSF(const char *filePath){
	uint8 head[128] = {0};
	int32 fd;
	mr_screeninfo scn;

	enable = 0;	//可用标志为0

	mrc_getScreenInfo(&scn);
	scnw = scn.width, scnh = scn.height;


	mrc_memset(&g_nowUse, sizeof(T_FONT_INFO), 0);

	fd = mrc_open(filePath, MR_FILE_RDONLY);

	if(!fd) return -1;

	//读取字库头
	mrc_read(fd, head, 128);
	if(0 != mrc_memcmp(head, "\x54\x53\x46\x4F\x4E\x54", 6)){
		mrc_close(fd);
		return -1;
	}

	//读取unicode索引表信息
	g_nowUse.uIndexOff = readLittleEndianUint32(head+12);
	g_nowUse.uIndexLen = readLittleEndianUint32(head+16);
	mrc_seek(fd, g_nowUse.uIndexOff, MR_SEEK_SET);
	g_nowUse.uIndexBuf = mrc_malloc(g_nowUse.uIndexLen);
	mrc_read(fd, g_nowUse.uIndexBuf, g_nowUse.uIndexLen);

	//读取点阵表信息
	g_nowUse.PointOff = readLittleEndianUint32(head+20);
	g_nowUse.PointLen = readLittleEndianUint32(head+24);

	//字体尺寸信息
	g_nowUse.GBWidth = head[28];
	g_nowUse.AsciiWidth = head[29];
	g_nowUse.fontHeight = head[30];

	g_nowUse.fontHandle = fd;
	enable = 1;	//加载成功，可用

	return fd;
}

void tsf_release(void){
	mrc_free(g_nowUse.uIndexBuf);
	mrc_close(g_nowUse.fontHandle);
}