#include "Script.hpp"
//===========================================================================//
// File:	 TextDraw.cpp													 //
// Project:  GOSScript				                                         //
// Contents: Text drawing and caching routine								 //
//---------------------------------------------------------------------------//
// Date      Who    Modification                                             //
// 05/02/00  AG		Created													 //
//---------------------------------------------------------------------------//
// Copyright (C) 2000, Microsoft, Inc.										//
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//


#if DISTRIBUTED_GOSSCRIPT==0
#undef STRICT
#include "..\GameOS\pch.hpp"
#include "..\GameOS\Font3D.hpp"
extern HGOSFONT3D FontHandle;
extern gos_VERTEX FontVertices[128];
extern DWORD FontIndex;
extern DWORD FontClipping;
extern DWORD FontColor;
extern bool FontStartOfLine;
extern bool FontDisableCodes;
extern float FontSize;
extern bool OddSize;
extern bool FontWordWrap;
extern DWORD FontWrapType;
extern bool FontProportional;
extern bool FontBold;
extern bool FontItalic;
extern int FontX,FontY;
extern float FontMinX,FontMinY,FontMaxX,FontMaxY;
extern bool FontNoCache;
void SetupFontRenderstates();
extern void HandleTags(char ** lplpMessage);
#endif



typedef struct _TextCache
{
	_TextCache*	pNext;

	HGOSFONT3D	FontHandle;
	DWORD		FontColor;
	int			FontX;
	int			FontY;
	bool		FontWordWrap;
	DWORD		FontWrapType;
	bool		FontProportional;
	bool		FontBold;
	bool		FontItalic;
	bool		FontDisableCodes;

	float		FontSize;
	float		FontMinX,FontMinY,FontMaxX,FontMaxY;
	DWORD		FontClipping;

	DWORD		NewFontColor;
	int			NewFontX;
	int			NewFontY;

	DWORD		TextureOffset;

	int			Length;				// Length of string
	char*		String;				// Pointer to copy of string

	DWORD		Used;

	DWORD		NumberVertices;
	gos_VERTEX*	Vertices;

} TextCache;


TextCache*	pTextCache=0;






void InitTextCache()
{
	pTextCache=0;
}



void DestroyTextCache()
{
	while( pTextCache )
	{
		TextCache* pNext=pTextCache->pNext;
		gos_Free( pTextCache->String );
		gos_Free( pTextCache->Vertices );
		gos_Free( pTextCache );
		pTextCache=pNext;
	}
}

void EndofFrameTextCache()
{
	TextCache* pThis=pTextCache;
	while( pThis )
	{
		TextCache* pNext=pThis->pNext;
		
		pThis->Used++;
		if( pThis->Used>5 )
		{
			if( pThis==pTextCache )
			{
				pTextCache=pNext;
			}
			else
			{
				TextCache* pLast=pTextCache;
				while( pLast->pNext!=pThis )
					pLast=pLast->pNext;
				pLast->pNext=pThis->pNext;
			}
			gos_Free( pThis->String );
			gos_Free( pThis->Vertices );
			gos_Free( pThis );
		}
		pThis=pNext;
	}
}




//
//
//
void gos_CacheTextDraw( char* String, int Length )
{
//
// Default case is draw string normally
//
	#if DISTRIBUTED_GOSSCRIPT==1
		gos_TextDraw( "%s", String );
	#else
//
//
//
	if( Length==-1 )
		Length=strlen(String);
	if( Length==0 )
		return;
//
// Look for tags (Only valid at start of text)
//
	char * Tags = String;
	if( String[0]=='/' )
		HandleTags(&Tags);

//
// Do not cache GDI fonts
//
#ifdef _DEBUG
	if( !FontHandle)
		ScriptError(("Attempt to print text with no font selected"));
#endif
	if( FontHandle->hFontTTF )
	{
		gos_TextDraw( "%s", Tags );
		return;
	}
//
//
//
	DWORD TexelOffset=gos_GetMachineInformation(gos_Info_TextureOffset);
	
	TextCache* pThis=pTextCache;
	while( pThis )
	{
		if( pThis->FontY==FontY &&
			pThis->FontX==FontX &&
			pThis->FontHandle==FontHandle &&
			pThis->FontColor==FontColor &&
			pThis->FontWordWrap==FontWordWrap &&
			pThis->FontWrapType==FontWrapType &&
			pThis->FontProportional==FontProportional &&
			pThis->FontBold==FontBold &&
			pThis->FontItalic==FontItalic &&
			*(DWORD*)&pThis->FontSize==*(DWORD*)&FontSize &&
			*(DWORD*)&pThis->FontMinX==*(DWORD*)&FontMinX &&
			*(DWORD*)&pThis->FontMinY==*(DWORD*)&FontMinY &&
			*(DWORD*)&pThis->FontMaxX==*(DWORD*)&FontMaxX &&
			*(DWORD*)&pThis->FontMaxY==*(DWORD*)&FontMaxY &&
			pThis->TextureOffset==TexelOffset &&
			pThis->Length==Length &&
			0==strcmp( pThis->String, String )
			)
		{
			pThis->Used=1;
			SetupFontRenderstates();
			if( pThis->FontClipping )
				gos_SetRenderState( gos_State_Clipping, 2 );
			gos_DrawQuads( pThis->Vertices, pThis->NumberVertices );

			FontColor=pThis->NewFontColor;
			FontX=pThis->NewFontX;
			FontY=pThis->NewFontY;

			return;
		}
		pThis=pThis->pNext;
	}
//
//
//
	HGOSFONT3D	TempFontHandle=FontHandle;
	DWORD		TempFontColor=FontColor;
	int			TempFontX=FontX;
	int			TempFontY=FontY;
	bool		TempFontWordWrap=FontWordWrap;
	DWORD		TempFontWrapType=FontWrapType;
	bool		TempFontDisableCodes=FontDisableCodes;
	bool		TempFontProportional=FontProportional;
	bool		TempFontBold=FontBold;
	bool		TempFontItalic=FontItalic;
	float		TempFontSize=FontSize;
	float		TempFontMinX=FontMinX;
	float		TempFontMinY=FontMinY;
	float		TempFontMaxX=FontMaxX;
	float		TempFontMaxY=FontMaxY;
	DWORD		TempTexelOffset=TexelOffset;
//
// Did not find in list - draw it
//
	gos_TextDraw( "%s", String );
//
// If less than 128 vertices, add to list.
//
	if( FontIndex>=4 && FontIndex<128 && !FontNoCache &&
		FontHandle==TempFontHandle &&
		FontWordWrap==TempFontWordWrap &&
		FontWrapType==TempFontWrapType &&
		TempFontDisableCodes==FontDisableCodes &&
		FontProportional==TempFontProportional &&
		FontBold==TempFontBold &&
		FontItalic==TempFontItalic &&
		FontSize==TempFontSize &&
		FontMinX==TempFontMinX &&
		FontMinY==TempFontMinY &&
		FontMaxX==TempFontMaxX &&
		FontMaxY==TempFontMaxY )
	{
		TextCache* pThis=(TextCache*)gos_Malloc( sizeof(TextCache) );
		pThis->Vertices=(gos_VERTEX*)gos_Malloc( FontIndex*sizeof(gos_VERTEX) );
		pThis->String=(char*)gos_Malloc( Length+1 );

		memcpy( pThis->String, String, Length+1 );
		memcpy( pThis->Vertices, FontVertices, FontIndex*sizeof(gos_VERTEX) );

		pThis->FontHandle=TempFontHandle;
		pThis->FontColor=TempFontColor;
		pThis->FontX=TempFontX;
		pThis->FontY=TempFontY;
		pThis->FontWordWrap=TempFontWordWrap;
		pThis->FontDisableCodes=TempFontDisableCodes;
		pThis->FontWrapType=TempFontWrapType;
		pThis->FontProportional=TempFontProportional;
		pThis->FontBold=TempFontBold;
		pThis->FontItalic=TempFontItalic;
		pThis->FontSize=TempFontSize;
		pThis->FontMinX=TempFontMinX;
		pThis->FontMinY=TempFontMinY;
		pThis->FontMaxX=TempFontMaxX;
		pThis->FontMaxY=TempFontMaxY;

		pThis->NewFontColor=FontColor;
		pThis->NewFontX=FontX;
		pThis->NewFontY=FontY;

		pThis->FontClipping=FontClipping;

		pThis->TextureOffset=TempTexelOffset;

		pThis->Length=Length;

		pThis->NumberVertices=FontIndex;

		pThis->pNext=pTextCache;

		pThis->Used=1;

		pTextCache=pThis;
	}
	return;

	#endif
}

