#include "HF.H"
//#include "RRTest.cpp"


void LoadData();
void UnLoadData();
void HMouse();
void DrawImage(DWORD Tex, int x, int y);
inline DWORD LoadTex(char* Text);
//inline int GetImageHeight(DWORD TexHandle);
//inline int GetImageWidth(DWORD TexHandle);
bool WithinArea(int x, int y, rect* R);
rect* MainArea;
rect* TOCArea;
rect* MainSBArea;
rect* TOCSBArea;
//Scrollbar* MainScroll;
//Scrollbar* TOCScroll;
int MainTH, TOCTH;

char* DupStr(const char* Orig);
DWORD Mouse1;
DWORD Mouse2;
DWORD Roll1;

char* GMLText=0;
char* Contents=0;
char* IndexDat=0;
GML* GDS=0;
Toc* TDS=0;
Index* IDS=0;
char* TextData = NULL;
void _stdcall InitializeGameEngine(){
	//
	//---------------------------
	// Start the Script Processor
	//---------------------------
	//
#ifdef LAB_ONLY
	//HTest();  //test the API's
	//InternalTest(); //test the internal working of GML
#endif

	MainTH=TOCTH=0;
	//TextData = new char[130];
	//strcpy(TextData,"<p>Please navigate using the Table of Contents to the left.</p> ");
	MainArea = new rect;
	MainArea->Left=200;
	MainArea->Top=5;
	MainArea->Right=620;
	MainArea->Bottom=470;
	GDS=new GML("assets\\fonts\\", "assets\\graphics\\", "assets\\scripts\\", MainArea, 15);
	TextData=GDS->LoadPage(GDS->LocateFile("assets\\scripts\\0000.gml"));
	//MainScroll=new Scrollbar(MainArea->Right,MainArea->Top,(MainArea->Bottom-MainArea->Top),MainArea,0,4);
	//MainSBArea=MainScroll->GetSBArea();
	TOCArea = new rect;
	TOCArea->Left=5;
	TOCArea->Top=5;
	TOCArea->Right=190;
	TOCArea->Bottom=470;
	//Contents=GDS->LoadPage(GDS->LocateFile("assets\\scripts\\contents.txt"));
	//TDS=new Toc(Contents, "assets\\fonts\\", "assets\\graphics\\", "assets\\scripts\\", TOCArea, 15);
	IndexDat=GDS->LoadPage(GDS->LocateFile("assets\\scripts\\index.txt"));
	IDS=new Index(IndexDat, "assets\\fonts\\", "assets\\graphics\\", "assets\\scripts\\", TOCArea, 15);
	//TOCScroll=new Scrollbar(TOCArea->Right,TOCArea->Top,(TOCArea->Bottom-TOCArea->Top),TOCArea,0,4);
	//TOCSBArea=TOCScroll->GetSBArea();
	LoadData();

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void _stdcall DoGameLogic()
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void _stdcall UpdateDisplay(){
	//--------------
	// set viewport
	//--------------
	int Temp;
	//gos_EnableSetting(gos_Set_MouseCursor,1);
	gos_SetupViewport(
		false,	//bool FillZ,
		1.0f,		//float ZBuffer,
		true,	//bool FillBG,
		0x00000000,	//DWORD newBGColor,
		1.0f,		//float top,
		1.0f,		//float left,
		0.0f,		//float bottom,
		0.0f		//float right
	);
	//if(TOCTH!=(Temp=TDS->Draw()))
	/*if(TOCTH!=(Temp=IDS->Draw()))
	{
		TOCTH=Temp;
		TOCScroll->ReCalc(TOCTH);
	}
	TOCScroll->Draw();
	if(MainTH!=(Temp=GDS->DisplayGML(TextData)))
	{
		MainTH=Temp;
		MainScroll->ReCalc(MainTH);
	}
	MainScroll->Draw();*/
	HMouse();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void _stdcall TerminateGameEngine(){
	delete GDS;
	delete TDS;
	delete IDS;
	//delete MainScroll;
	//delete TOCScroll;
	if(TextData)
		delete[] TextData;
	if(Contents)
		delete[] Contents;
	delete MainSBArea;
	delete TOCSBArea;

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void _stdcall GetGameOSEnvironment(char* ){
	// make sure the command-line arguments are valid
	Environment.applicationName			= "Test gosGml";
	Environment.screenWidth				= 640;
	Environment.screenHeight			= 480;
	Environment.fullScreen				= 0;
	Environment.bitDepth				= 16;
	Environment.debugLog				= "";
	Environment.spew					= "GameOS_Memory";
	//Environment.spew					= "";
	Environment.memoryTraceLevel		= 5;
	Environment.TimeStampSpew			= 0;
	Environment.UpdateRenderers			= UpdateDisplay;
	Environment.DoGameLogic				= DoGameLogic;
	Environment.InitializeGameEngine	= InitializeGameEngine;
	Environment.TerminateGameEngine		= TerminateGameEngine;
	Environment.soundChannels			= 16;
	Environment.FullScreenDevice		= 0;
	Environment.AntiAlias				= 0;			// true/false - Enable full screen antialiasing
	Environment.Renderer				= 0;
//
// Texture infomation
//
	Environment.Texture_S_256			= 1;
	Environment.Texture_S_128			= 1;
	Environment.Texture_S_64			= 1;
	Environment.Texture_S_32			= 1;
	Environment.Texture_S_16			= 1;
	Environment.Texture_K_256			= 1;
	Environment.Texture_K_128			= 1;
	Environment.Texture_K_64			= 1;
	Environment.Texture_K_32			= 1;
	Environment.Texture_K_16			= 1;
	Environment.Texture_A_256			= 1;
	Environment.Texture_A_128			= 1;
	Environment.Texture_A_64			= 1;
	Environment.Texture_A_32			= 1;
	Environment.Texture_A_16			= 1;
}

void LoadData()
{
	//Mouse1=LoadTex("assets\\graphics\\Mouse Normal.png");
	//Mouse2=LoadTex("assets\\graphics\\Mouse Excited.png");
	Roll1=LoadTex("assets\\graphics\\Mouse Normal.tga");
}

void UnLoadData()
{
	//char* NewD;
}

void HMouse()
{
#pragma warning(disable:4244)
	int useless;
	float Xp,Yp;
	int X,Y;
	static bool WasClicked=false;
	char* Temp;
	DWORD Buttons;
	gos_GetMouseInfo( &Xp, &Yp, &useless, &useless, &useless, &Buttons);
	X=Xp*Environment.screenWidth;
	Y=Yp*Environment.screenHeight;
	//GDS->SetScrollOffset(MainScroll->Mouse(Buttons&1,X,Y));
	//TDS->SetScrollOffset(TOCScroll->Mouse(Buttons&1,X,Y));
	//IDS->SetScrollOffset(TOCScroll->Mouse(Buttons&1,X,Y));
	if(Buttons&1) //if left click
	{
		if(!WasClicked)
		{
			WasClicked=true;
			if(WithinArea(X,Y,MainArea))
			{
				char* T=GDS->Click(X,Y);
				if(T)
				{
					if(TextData)
						delete[] TextData;
					TextData=GDS->LoadPage(Temp=GDS->LocateFile(T));
					delete[] Temp;
					MainTH=0;
					//GDS->SetScrollOffset(0);
				}
			}
			else
				if(WithinArea(X,Y,TOCArea))
				{
					//char* T=TDS->Click(X,Y);
					char* T=IDS->Click(X,Y);
					if(T)
					{
						if(TextData)
							delete[] TextData;
						TextData=GDS->LoadPage(Temp=GDS->LocateFile(T));
						delete[] Temp;
						MainTH=0;
						//GDS->SetScrollOffset(0);
					}
				}
		}
	}
	else
		WasClicked=false;
	DrawImage(Roll1,Xp*Environment.screenWidth,Yp*Environment.screenHeight);
	/*
	rect* L=new rect;
	L->Top=Yp*Environment.screenHeight;
	L->Left=Xp*Environment.screenWidth;
	L->Right=L->Left+1;
	L->Bottom=L->Top+1;
	DrawF(L,0xFF0000FF);
	L->Right++;
	L->Bottom++;
	DrawF(L,0x770000FF);
	L->Right+=2;
	L->Bottom+=2;
	DrawF(L,0x7700FFFF);
	L->Right+=4;
	L->Bottom+=4;
	static int a=0x00FFFFFF;
	a+=0x00800000;
	a&=0x00FFFFFF;
	DrawF(L,a+0x66000000);
	delete L;*/
#pragma warning(default:4244)
}


void DrawImage(DWORD Tex, int x, int y)
{
	if(!(x+GetImageWidth(Tex)>0 && y+GetImageHeight(Tex) > 0 && x < Environment.screenWidth && y < Environment.screenHeight))
		return;
	gos_VERTEX pVertices[4];
	pVertices[0].z		=	0.0f;
	pVertices[1].z		=	0.0f;
	pVertices[2].z		=	0.0f;
	pVertices[3].z		=	0.0f;

	pVertices[0].rhw	=	1.0f;
	pVertices[1].rhw	=	1.0f;
	pVertices[2].rhw	=	1.0f;
	pVertices[3].rhw	=	1.0f;

	pVertices[0].argb	=	0xffffffff;
	pVertices[1].argb	=	0xffffffff;
	pVertices[2].argb	=	0xffffffff;
	pVertices[3].argb	=	0xffffffff;

	pVertices[0].frgb	=	0;
	pVertices[1].frgb	=	0;
	pVertices[2].frgb	=	0;
	pVertices[3].frgb	=	0;

	pVertices[0].u		= 0.0f;
	pVertices[0].v		= 0.0f;
	pVertices[1].u		= 0.0f;
	pVertices[1].v		= 1.0f;
	pVertices[2].u		= 1.0f;
	pVertices[2].v		= 1.0f;
	pVertices[3].u		= 1.0f;
	pVertices[3].v		= 0.0f;

	gos_SetRenderState( gos_State_AlphaTest, 1 );
	gos_SetRenderState( gos_State_Perspective, 0 );
	gos_SetRenderState( gos_State_Specular, 0 );
	gos_SetRenderState( gos_State_Dither, 0 );
	gos_SetRenderState( gos_State_Filter, gos_FilterNone );
	gos_SetRenderState( gos_State_Clipping, 0 );
	gos_SetRenderState( gos_State_ZWrite, 0 );
	gos_SetRenderState( gos_State_ZCompare, 0 );
	gos_SetRenderState( gos_State_WireframeMode, 0 );
	gos_SetRenderState( gos_State_ShadeMode, gos_ShadeFlat );
	gos_SetRenderState( gos_State_Fog, 0 );
	gos_SetRenderState( gos_State_Texture, Tex );
	gos_SetRenderState( gos_State_Clipping, 2 );

	gos_SetViewport(0,0,Environment.screenWidth,Environment.screenHeight);
	pVertices[0].x	=	x>0 ? (float)x : 0;
	pVertices[0].y	=		y>0 ? (float)y : 0;
	pVertices[1].x	=	x>0 ? (float)x : 0;
	pVertices[1].y	=		y+GetImageHeight(Tex)<Environment.screenHeight ? (float)y+GetImageHeight(Tex) : Environment.screenHeight;
	pVertices[2].x	=	x+GetImageWidth(Tex)<Environment.screenWidth ? (float)x+GetImageWidth(Tex) : Environment.screenWidth;
	pVertices[2].y	=		y+GetImageHeight(Tex)<Environment.screenHeight ? (float)y+GetImageHeight(Tex) : Environment.screenHeight;
	pVertices[3].x	=	x+GetImageWidth(Tex)<Environment.screenWidth ? (float)x+GetImageWidth(Tex) : Environment.screenWidth;
	pVertices[3].y	=		y>0 ? (float)y : 0;
	gos_DrawQuads( pVertices, 4 );
}

void DrawF(rect* Area, DWORD color)
{
	if (Area->Left < 0) Area->Left = 0;
	if (Area->Right < 0) Area->Right = 0;
	if (Area->Top < 0) Area->Top = 0;
	if (Area->Bottom < 0) Area->Bottom = 0;
	if (Area->Left > Environment.screenWidth) Area->Left = Environment.screenWidth;
	if (Area->Right > Environment.screenWidth) Area->Right = Environment.screenWidth;
	if (Area->Top > Environment.screenHeight) Area->Top = Environment.screenHeight;
	if (Area->Bottom > Environment.screenHeight) Area->Bottom = Environment.screenHeight;
	if (Area->Left == Area->Right || Area->Top == Area->Bottom) return;
	gos_VERTEX pVertices[4];

	memset( pVertices, 0, sizeof(pVertices) );
	pVertices[0].rhw	= 1.0;
	pVertices[1].rhw	= 1.0;
	pVertices[2].rhw	= 1.0;
	pVertices[3].rhw	= 1.0;

	pVertices[0].x		= (float)Area->Left;
	pVertices[0].y		= (float)Area->Top;
	pVertices[0].argb	= color;

	pVertices[1].x		= (float)Area->Left;
	pVertices[1].y		= (float)Area->Bottom;
	pVertices[1].argb	= color;

	pVertices[2].x		= (float)Area->Right;
	pVertices[2].y		= (float)Area->Bottom;
	pVertices[2].argb	= color;

	pVertices[3].x		= (float)Area->Right;
	pVertices[3].y		= (float)Area->Top;
	pVertices[3].argb	= color;

	gos_PushRenderStates();
	gos_SetRenderState( gos_State_Texture, 0 );
	gos_SetRenderState( gos_State_Filter, gos_FilterNone );
	gos_SetRenderState( gos_State_ZCompare, 0 );
	gos_SetRenderState( gos_State_ZWrite, 0 );
	gos_SetRenderState( gos_State_AlphaTest, 0 );
	gos_SetRenderState( gos_State_Perspective, 0 );
	gos_SetRenderState( gos_State_Specular, 0 );
	gos_SetRenderState( gos_State_Dither, 0 );
	gos_SetRenderState( gos_State_Clipping, 0 );
	gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendModulate );
	gos_SetRenderState( gos_State_ShadeMode, gos_ShadeFlat );
	gos_SetRenderState( gos_State_MonoEnable, 0 );
	if( (color&0xff000000)==0xff000000 )
		gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_OneZero );
	else
		gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_AlphaInvAlpha );

	gos_DrawQuads( pVertices, 4 );
	gos_PopRenderStates();

}


bool WithinArea(int x, int y, rect* R)
{
	if(x<R->Left || x>R->Right || y<R->Top || y>R->Bottom)
		return false;
	return true;
}

char* DupStr(const char* Orig)
{
	char* N = new char[strlen(Orig)+1];
	strcpy(N,Orig);
	return N;
}