//===========================================================================//
// File:	 gosGml.cpp													 //
// Project:  GameOS					                                         //
// Contents: Precompiled header file - Generates the precompiled header		 //
//---------------------------------------------------------------------------//
// Date      Who    Modification                                             //
// 4/10/00   JR     Created													 //
//---------------------------------------------------------------------------//
// Copyright (C) 2000 Microsoft Corp.						                 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#include "gosGml.hpp"


size_t mstrlen( const char *string )
{
	return _mbsnbcnt((const unsigned char *)string,99999);
}

char* mstrcpy( char *strDestination, const char *strSource )
{
	return (char *)_mbscpy((unsigned char *)strDestination,(const unsigned char *)strSource);
}

int mstrcmp( const char *string1, const char *string2 )
{
	return _mbscmp((const unsigned char *)string1,(const unsigned char *)string2);
}

int mstricmp( const char *string1, const char *string2 )
{
	return _mbsicmp((const unsigned char *)string1,(const unsigned char *)string2);
}

char *mbpinc( const char *current )
{
	return (char*)_mbsinc((const unsigned char *)current);
}

char *mbpdec( const char *current )
{
	return (char*)_mbsdec((const unsigned char *)(current-4),(const unsigned char *)current);
}

char *mbpncpy( char *strDest, const char *strSource, size_t count )
{
	return (char*)_mbsncpy((unsigned char *)strDest, (const unsigned char *)strSource, count);
}


char* AppendStr(const char* First, const char* Second)
{
	if(!First || !Second)
		return NULL;
	char* AS = new char[strlen(First)+strlen(Second)+1];
	strcpy(AS,First);
	strcpy(AS+strlen(First),Second);
	*(AS+strlen(First)+strlen(Second))=0;
	return AS;
}

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

char* MemToStr(const char* In, int Count)
{
	char* Out = new char[Count+1];
	memcpy(Out,In,Count);
	*(Out+Count)=0;
	return Out;
}

char* GetPathFromFFN(const char* FullFilePath);
bool DoesFilePathExist(const char* Path, const char* FileName);
char* DefaultPagePath=NULL;

int _gos_GetPage(const char* FileName, BYTE** MemoryImage, DWORD* Size)	//must use Full File Name!
{
	if(!FileName)
	{
		char* Badness=new char[16];
		mstrcpy(Badness,"<p>Bad Link</p>");
		*MemoryImage=(unsigned char*)Badness;
		*Size=16;
		return 0;
	}
	if(strlen(FileName)>7 && memcmp("http://",FileName,7))
	{
		if(!gos_DoesFileExist(FileName))
		{
			char* Badness=new char[16];
			mstrcpy(Badness,"<p>Bad Link</p>");
			*MemoryImage=(unsigned char*)Badness;
			*Size=16;
			return 0;
		}
		gos_GetFile(FileName,MemoryImage,Size);
		return 1;
	}
	else
	{
		//http file request
		return 2;
	}
}

char* _gos_LocatePage(const char* FileName)	//need to delete what you get out of this
{
	if(!FileName)	//the HELL I say!
		return NULL;
	if((strlen(FileName)>7 && memcmp("http://",FileName,7)) || (strlen(FileName)>2 && memcmp("\\\\",FileName,2))) //if not network
	{
		static char* CurrentPath=0;
		if(CurrentPath && strlen(FileName)>3 && *(FileName+1)!=':')	//if FileName is not ?:\ then use relative path
			if(!DoesFilePathExist(CurrentPath,FileName))
				if(!(DefaultPagePath && DoesFilePathExist(DefaultPagePath,FileName)))
					if(!gos_DoesFileExist(FileName))
						return NULL;
					else
						return DupStr(FileName);
				else
					return AppendStr(DefaultPagePath,FileName);
			else
				return AppendStr(CurrentPath,FileName);
		//absolute path given
		char* FPath=GetPathFromFFN(FileName);
		if(FPath)
			CurrentPath=FPath;
		if(!gos_DoesFileExist(FileName))
			return NULL;
		return DupStr(FileName);
	}
	else //network style
	{
		return NULL;
	}
}

void _gos_SetDefaultPath(const char* Path)
{
	if(DefaultPagePath)
		delete[] DefaultPagePath;
	DefaultPagePath=DupStr(Path);
}

bool DoesFilePathExist(const char* Path, const char* FileName)
{
	char* FFN=AppendStr(Path,FileName);
	bool retval = gos_DoesFileExist(FFN);
	delete[] FFN;
	return retval;
}

char* GetPathFromFFN(const char* FullFilePath)	//full file name desu ne
{
	if(!FullFilePath)
		return 0;
	char* LastSlash=(char*)FullFilePath+strlen(FullFilePath)-1;
	while(*LastSlash!='\\' && *LastSlash!='/' && LastSlash>=FullFilePath)
		LastSlash--;
	if(LastSlash==FullFilePath)
		return 0;
	char* PathOnly=new char[LastSlash-FullFilePath+2];//you'll probably see 1 of these leaked, which is why you're here. 1 will probably leak, but no more than that. I may fix this later, but a few bytes isn't a big deal... just looks bad.
	memcpy(PathOnly, FullFilePath, LastSlash-FullFilePath+1);
	*(PathOnly+(int)(LastSlash-FullFilePath+1))=0;
	return PathOnly;
}

int GetImageHeight(DWORD TexHandle)
{
	if(!TexHandle)
		return 0;
	TEXTUREPTR Tex;
	gos_LockTexture(TexHandle, 0, true, &Tex);
	gos_UnLockTexture( TexHandle );
	return Tex.Height;
}

int GetImageWidth(DWORD TexHandle)
{
	if(!TexHandle)
		return 0;
	TEXTUREPTR Tex;
	gos_LockTexture(TexHandle, 0, true, &Tex);
	gos_UnLockTexture( TexHandle );
	return Tex.Width;
}

inline DWORD LoadTex(char* Text)
{
	DWORD Tex;
	if(!strncmp(Text+strlen(Text)-4,".avi",4))
	{
		HGOSVIDEO HGVTemp=0;
		gosVideo_CreateResourceAsTexture( &HGVTemp, &Tex, Text );
		gosVideo_SetPlayMode( HGVTemp, gosVideo_Loop );
	}
	else
	{
		Tex=gos_NewTextureFromFile( gos_Texture_Detect, Text);
	}
	return Tex;
}

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;
}

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_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 DrawDImage(DWORD Tex, rect* R)
{
	if(!(R->Right>0 && R->Bottom > 0 && R->Left < Environment.screenWidth && R->Top < 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_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	=	(float)R->Left;
	pVertices[0].y	=		(float)R->Top;
	pVertices[1].x	=	(float)R->Left;
	pVertices[1].y	=		(float)R->Bottom;
	pVertices[2].x	=	(float)R->Right;
	pVertices[2].y	=		(float)R->Bottom;
	pVertices[3].x	=	(float)R->Right;
	pVertices[3].y	=		(float)R->Top;
	gos_DrawQuads( pVertices, 4 );
}