
#include "glover.h"

UBYTE message[100];

TEXTLIST textList;
TEXT *mtext;

SPRITEX *fontList[NUMFONTS];
int textFrame=0;


#define SETXY(A,X,Y) *(ULONG*)&A=((SHORT)(X<<16)|(SHORT)(Y));	


void NEW_TEXT(short xval,short yval,char rr,char gg,char bb,char aa,int sx,int sy,char bye,char *string,char center)
{
	mtext = (TEXT *)MALLOC(sizeof(TEXT), "Text");
	mtext->flags=0;
	mtext->x = xval;
	mtext->y = yval;
	SETRGBC(mtext->r,rr,gg,bb,aa);
   	mtext->scaleX = sx;
   	mtext->scaleY = sy;
	mtext->byebye = bye;
	STRCPY(mtext->message,string);
	AddText(mtext, center);
}

void TextSetShading(RGBCD *col0, RGBCD *col1)
{
	mtext->flags=TEXT_SHADED;
	*(ULONG*)&mtext->r =*(ULONG*)&col0->r;
	*(ULONG*)&mtext->r1 = *(ULONG*)&col1->r;
}

/*	--------------------------------------------------------------------------------
	Function 	: 
	Purpose 	: 
	Parameters 	: 
	Returns 	: 
	Info 		:
*/
void InitTextList(void)
{
	textList.head.next = textList.head.prev = &textList.head;
	textList.numEntries = 0;
}

/*	--------------------------------------------------------------------------------
	Function 	: 
	Purpose 	: 
	Parameters 	: 
	Returns 	: 
	Info 		:
*/
void AddText(TEXT *text, int centre)
{
	TEXT *ptr = textList.head.next;
	text->centre=centre;
	text->font = messctrl.font;

	text->prev = ptr;
	text->next = ptr->next;
	ptr->next->prev = text;
	ptr->next = text;
	textList.numEntries++;
}

/*	--------------------------------------------------------------------------------
	Function 	: 
	Purpose 	: 
	Parameters 	: 
	Returns 	: 
	Info 		:
*/
void SubText(TEXT *text)
{
	if((text) && (text->next))
	{
		text->prev->next = text->next;
		text->next->prev = text->prev;
		textList.numEntries--;

		text->next = NULL;

//		FREE(&text);
		FREE(text);
	}
}

/*	--------------------------------------------------------------------------------
	Function 	: 
	Purpose 	: 
	Parameters 	: 
	Returns 	: 
	Info 		:
*/
void ClearText()
{
	TEXT *text,*text2;

	for(text = textList.head.next;text != &textList.head;text = text2)
	{
		text2 = text->next;
		if(text->byebye)
			SubText(text);
	}
}

/*	--------------------------------------------------------------------------------
	Function 	: 
	Purpose 	: 
	Parameters 	: 
	Returns 	: 
	Info 		:
*/
void ClearAllText()
{
	TEXT *text,*text2;

	for(text = textList.head.next;text != &textList.head;text = text2)
	{
		text2 = text->next;
		SubText(text);
	}
}

/*	--------------------------------------------------------------------------------
	Function 	: 
	Purpose 	: 
	Parameters 	: 
	Returns 	: 
	Info 		:
*/
void ShowText(void)
{

	TEXT *text;

	for(text = textList.head.next;text != &textList.head;text = text->next)
	{
		if(!(text->a))
			continue;

		messctrl.font=text->font;
	   SETRGBC(sprctrl.r,text->r,text->g,text->b,0);
	 	sprctrl.scalex=text->scaleX;
		sprctrl.scaley=text->scaleY;
		sprctrl.stretch=0;
		sprctrl.shaded=FALSE;

		if(text->flags&TEXT_SHADED)
		{
			sprctrl.r1=text->r1;
			sprctrl.g1=text->g1;
			sprctrl.b1=text->b1;
			sprctrl.shaded=TRUE;
		}

		if(text->centre)
			messctrl.justify=CENTRETEXT;
		else
			messctrl.justify=LEFTTEXT;

		if(text->flags & TEXT_ANIMATED)
			{TEXTPRINTANIMATEDAT((text->x),text->y,text->message);}
		else
			{TEXTPRINTAT((text->x),text->y,text->message);}
	}

	sprctrl.shaded=FALSE;
	sprctrl.scalex=4096;
	sprctrl.scaley=4096;
	SETRGBC(sprctrl.r,128,128,128,0);

	textFrame++;
}

/*	--------------------------------------------------------------------------------
	Function 	: 
	Purpose 	: 
	Parameters 	: 
	Returns 	: 
	Info 		:
*/


MESS messctrl;
UBYTE FontsLoaded=NO;

/********************************************************************************/
void textReset(void)
{
	messctrl.x=0;
	messctrl.y=0;
	messctrl.ox=0;
	messctrl.oy=0;
	messctrl.font=NULL;
	messctrl.propor=ON;
	messctrl.spc=0;
	messctrl.justify=LEFTTEXT;
	messctrl.gapx=-4;
}
/*************************************************************/
SPRITEX *textLoadFont(char *sFile, int intelligent)
{
	int a,aa;
	SPRITEX *pFont, *pLetter;
	TextureBankType *pBank;
	char sSName[8];

	if(intelligent)
	{
		pFont=MALLOC(sizeof(SPRITEX)*235, sFile);

		pBank=textureLoadBank(sFile);
		for(a=0; a<235; a++)
		{
			aa=a+32;
			sprintf(sSName, "%02X", aa);
			pLetter=textureFindInBank(pBank, sSName);
			if(pLetter)
				memcpy(pFont+a, pLetter, sizeof(SPRITEX));
			else
			{
				if(a==0)
				{
					DB("'Intelligent' font MUST have a SPACE character!\n");
					CRASH;
				}
				memcpy(pFont+a, pFont, sizeof(SPRITEX));
			}
		}

		textureDestroyBank(pBank);
	}
	else
		pFont=textureLoadSPT(sFile);

	return(pFont);
}

/**********************************************************************************/

UBYTE textForeignLetters(UBYTE letter){
			switch(letter)
			{
		 		//french
	  		 	case 200:	letter=124; 	break; 	//e`
	  		   	case 201:	letter=123;    	break; 	//e'
	  			case 202:	letter=125; 	break; 	//e^
	  			case 212:	letter=128;	   	break; 	//o^
	  			case 206:	letter=127;		break;	//i^ 
	  			case 207:	letter=126;		break; 	//i ``
	  			case 194:	letter=140; 	break;	//a^
	  			case 192:	letter=121;		break;	//a`
	  			case 219:	letter=120;		break;	//u^
	  			case 217:	letter=130; 	break;	//u`
	  			case 199:	letter=100; 	break;	//c.

				//german		 
				case 182:					  	 	//..
				case 214:	letter=119;		break;	//o
				case 191:	letter=139;		break;	//B
				case 164:		 					//..
				case 196:	letter=118;		break;	//a
				case 220:		 					//u
				case 188:	letter=120;		break;	//U

				//italian and spanish
		  		case 193:	letter=122;		break;  //a/
				case 211:	letter=128;		break;  //o/
				case 218:	letter=130;		break; 	//U/
				case 205:	letter=134;		break;	//i/
				case 209:	letter=132;		break;  //n~
				case 159:	letter=108;		break;	//?
				case 129:	letter=142;		break;	//!
				case 204:	letter=127; printf("i"); break;	// /* i\ */
				case 210:	letter=136;	printf("o"); break;	// /* o\ */
				case 168:	letter=124;	printf("e"); break;	// /* E\ */
  
			}
	return letter;
}

/*********FINDS LENGTH OF LINE TO PRINT*******************************************/
USHORT textFindLineLen(UBYTE *tmp)
{
	USHORT linelen=0;
	LUBYTE  letter;
	LONG calc;

	while ((letter=*tmp++)!=0)
	{
	 	if(letter=='\n' || letter==MESSNEWLINE || letter==13)return linelen;
	
		if((letter > 96) && ((letter < 123) || (letter > 143)))		letter -= 32;
		if(letter>=32)
		{
			letter=textForeignLetters(letter);

			if ((letter==' ')||(messctrl.propor==OFF))	letter = 'A';

								//adds the letter space
			if(sprctrl.scalex == 4096)
			{
				calc = (messctrl.font+(letter-32))->w/2;
				if (calc<=4) calc+=2;
			}
			else
				calc = (((messctrl.font+(letter-32))->w/2)*sprctrl.scalex)/4096;

			calc+=messctrl.spc;	//adds the gap between letters
			linelen += calc; //incriments the x co-ords
		}
	}
	return linelen;
}
/************PRINT MESSAGE********************************************************/
int textPrintf(char* fmt, ...)
{
    va_list	arglist;
    long	r1, r2, r3, r4, r5, r6;
    int		len;

	va_start(arglist, fmt);
    r1 = va_arg(arglist, long);
    r2 = va_arg(arglist, long);
    r3 = va_arg(arglist, long);
    r4 = va_arg(arglist, long);
    r5 = va_arg(arglist, long);
    r6 = va_arg(arglist, long);
	va_end(arglist);
    len = sprintf(message, fmt, r1, r2, r3, r4, r5, r6);

	textPrint(message);

    return len;
}
/***********************************************/
void textPrint(UBYTE *mess)
{
	int messLen,i;
	int xPos, yPos;
	int pixLen=0;
	int gapX;
	ULONG	oldColour;

	if (messctrl.font==NULL)
	{
		DB("ERROR: Font not set. (Tried to print '%s')\n", mess);
		CRASH;
	}

	gapX=(messctrl.gapx*sprctrl.scalex)/4096;

	if((messctrl.font==fontList[2])&&(messctrl.gapx<-2))
		gapX=(-2*sprctrl.scalex)/4096;

	// get length of message in pixels and chars
	for(messLen=0; mess[messLen]; messLen++)
		pixLen+=((messctrl.font[mess[messLen]-32].w*sprctrl.scalex)/4096)+gapX;

	xPos=messctrl.x-scrcenterx;
	yPos=messctrl.y-scrcentery;

	switch(messctrl.justify)
	{
	case RIGHTTEXT:
		break;
	case LEFTTEXT:
		xPos+=pixLen;
		break;
	case CENTRETEXT:
		xPos+=(pixLen>>1);
		break;
	default:
		DB("Invalid TEXT justification\n");
	}

	oldColour=*(ULONG *)&(sprctrl.r);

	for(i=0; i<messLen; i++)
	{
		int b=mess[messLen-1-i];
		int w;

		if((b=='#') || (b=='$') || (b=='%') || (b=='&') || (b=='[') || (b==']') || (b=='<') || (b=='>'))
		{
			*(ULONG *)&(sprctrl.r)=0x00808080;
			sprctrl.shaded=FALSE;
		}
		else
		{
			*(ULONG *)&(sprctrl.r)=oldColour;
			sprctrl.shaded=TRUE;
		}

		b=b-32;
		w=(messctrl.font[b].w*sprctrl.scalex)/4096;

#ifdef MULTI_LANGUAGE
// The italian apostrophe was getting lost in the scaled-down text on the memory-card screen (nell'ingresso)
		if(sprctrl.scalex < 3500 && b == 0x60-32)
		{
			int temp;
			temp = sprctrl.scalex;
			sprctrl.scalex = 3500;
			w=(messctrl.font[b].w*sprctrl.scalex)/4096;
			spritePrint(messctrl.font+b, xPos-(w>>1), yPos, 0);
			sprctrl.scalex = temp;

		}
		else
		{
		// add on half the width because spritePrint() centres the sprite :(
			spritePrint(messctrl.font+b, xPos-(w>>1), yPos, 0);
		}
#else
		// add on half the width because spritePrint() centres the sprite :(
		spritePrint(messctrl.font+b, xPos-(w>>1), yPos, 0);
#endif
		xPos-=w+gapX;
	}

	*(ULONG *)&(sprctrl.r)=oldColour;
	sprctrl.shaded=TRUE;
}
/*******************************************************/

void textPrintAnimated(UBYTE *mess)
{
	int messLen,i;
	int xPos, yPos;
	int pixLen=0;
	int gapX;
	int 	extraHeight=0;

	if (messctrl.font==NULL)
	{
		DB("ERROR: Font not set. (Tried to print '%s')\n", mess);
		CRASH;
	}

	gapX=(messctrl.gapx*sprctrl.scalex)/4096;

	// get length of message in pixels and chars
	for(messLen=0; mess[messLen]; messLen++)
		pixLen+=((messctrl.font[mess[messLen]-32].w*sprctrl.scalex)/4096)+gapX;

	xPos=messctrl.x-scrcenterx;
	yPos=messctrl.y-scrcentery;

	switch(messctrl.justify)
	{
	case RIGHTTEXT:
		break;
	case LEFTTEXT:
		xPos+=pixLen;
		break;
	case CENTRETEXT:
		xPos+=(pixLen>>1);
		break;
	default:
		DB("Invalid TEXT justification\n");
	}

	for(i=0; i<messLen; i++)
	{
		int b=mess[messLen-1-i]-32;
		int w=(messctrl.font[b].w*sprctrl.scalex)/4096;

		extraHeight=abs(rsin((i*500)+(textFrame*400))/1000);
		// add on half the width because spritePrint() centres the sprite :(
		spritePrint(messctrl.font+b, xPos-(w>>1), yPos-extraHeight, 0);
		xPos-=w+gapX;
	}

}
/************************************************************************/

// copies srce string to dest, forcing to upper case
void strcpyi(UBYTE* dest,UBYTE* source)
{
	LONG j;

	j=32;
	while (j>=32)
	{
		j=*(source++);
		if (j>(64+32)) j-=32;
			*(dest++)=j ;
	}
}
/***************************************************************************/

#ifdef MULTI_LANGUAGE

// To avoid memory fragging, I'm declaring a constant language buffer, and copying into it from a temp-load
#define LANG_MAX_LEN 4096
unsigned char lang_file[LANG_MAX_LEN];

// NB - For non-existant strings, it must return a pointer to an empty string
char *fontFindLangString(int id)
{
	int ptr;
	char *str;
	int sub = (id & 0xff);
	static char dummy_str[]= "";

	id = id >> 8;

	do
	{
		ptr = ((int *)(lang_file))[id];
		if(!ptr)
			return &dummy_str[0];
		str = ADD2POINTER(lang_file,ptr);
		id = (int)str[0];
		sub--;
	}
	while(sub >= 0);
	return(&(str[1]));
}

void loadLangFile(int language)
{
	UBYTE *temp;
	int len;
	static char *fnames[4] =
	{
		"TEST\\GAME_ENG.BIN",
		"TEST\\GAME_FRE.BIN",
		"TEST\\GAME_GER.BIN",
		"TEST\\GAME_ITA.BIN",
	};
	temp = 	(UBYTE *)fileTempLoad(fnames[language], &len);
	ASSERT(len <= LANG_MAX_LEN);
	memcpy(&lang_file[0], temp, len);
	FREE(temp);
// Quick test that it works!
//	printf("string %i = %s\n",1,fontFindLangString(0x100));
}



#endif





