/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///																																  ///
///		FICHIER :	ZooFont.cpp																									  ///
///																																  ///
///		NATURE	:	Management of the font for the 3D scene																		  ///
///																																  ///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



#include	"..\Datas\ZooFont.h"










///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// ZFont Class
///
///		- Class of font display on screen
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////
/// Constructor					 										///
///////////////////////////////////////////////////////////////////////////
ZFont::ZFont() : ZData()
{
	texture = NULL;

	type = FNT_TYPE_ID;
}


///////////////////////////////////////////////////////////////////////////
/// Destructor					 										///
///////////////////////////////////////////////////////////////////////////
ZFont::~ZFont()
{
	if(texture)			texture->DecRef();

	glDeleteLists(baseListID, 256);
}



///////////////////////////////////////////////////////////////////////////
/// Set a texture used by the font										///
///////////////////////////////////////////////////////////////////////////
void ZFont::SetTexture(ZTexture *newTex)
{
	if(texture)			texture->DecRef();

	texture = newTex;
	if(texture)			texture->IncRef();
}



///////////////////////////////////////////////////////////////////////////
///		BuildFont														///
///////////////////////////////////////////////////////////////////////////
void ZFont::BuildFontLists(int nbW, int nbH)
{
	baseListID = glGenLists(256);							// Creating 256 Display Lists

	for(int loop1=0; loop1<256; loop1++)					// Loop Through All 256 Lists
	{
//		float cx=float(loop1%16)/16.0f;						// X Position Of Current Character
//		float cy=float(loop1/16)/16.0f;						// Y Position Of Current Character
		float cx = (float)(loop1 % nbW)/(float)(nbW);
		float cy = (float)(loop1 / nbW)/(float)(nbH);

		glNewList(baseListID+loop1,GL_COMPILE);				// Start Building A List

			glBegin(GL_QUADS);								// Use A Quad For Each Character
				glTexCoord2f(cx,1.0f-cy-0.001f);			// Texture Coord (Top Left)
				glVertex2i(0,0);							// Vertex Coord (Top Left)
				glTexCoord2f(cx,1.0f-cy-0.0625f);			// Texture Coord (Bottom Left)
				glVertex2d(0,16);							// Vertex Coord (Bottom Left)
				glTexCoord2f(cx+0.0625f,1.0f-cy-0.0625f);	// Texture Coord (Bottom Right)
				glVertex2i(16,16);							// Vertex Coord (Bottom Right)
				glTexCoord2f(cx+0.0625f,1.0f-cy-0.001f);	// Texture Coord (Top Right)
				glVertex2i(16,0);							// Vertex Coord (Top Right)
			glEnd();										// Done Building Our Quad (Character)
			glTranslated(14,0,0);							// Move To The Right Of The Character

		glEndList();										// Done Building The Display List
	}														// Loop Until All 256 Are Built
}



///////////////////////////////////////////////////////////////////////////
///		InitFontPrint													///
///////////////////////////////////////////////////////////////////////////
bool ZFont::InitFontPrint(int width, int height, bool blending)
{
	if(!texture)	return false;

	depth = glIsEnabled(GL_DEPTH_TEST);
	light = glIsEnabled(GL_LIGHTING);
	blend = glIsEnabled(GL_BLEND);
	textu = glIsEnabled(GL_TEXTURE_2D);

	if(depth)		glDisable(GL_DEPTH_TEST);
	if(light)		glDisable(GL_LIGHTING);
	if(!blending && blend)		glDisable(GL_BLEND);
	if(blending && !blend)	
	{
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}
	if(!textu)		glEnable(GL_TEXTURE_2D);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity(); 
	glOrtho(0.0f,width,height,0.0f,-1.0f,1.0f);

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	if(userACCEL)	texture->PutGLMultiparams0();							// Select Our Font Texture

	return true;
}



///////////////////////////////////////////////////////////////////////////
///		StopFontPrint													///
///////////////////////////////////////////////////////////////////////////
void ZFont::StopFontPrint()
{
	if(depth)		glEnable(GL_DEPTH_TEST);
	if(light)		glEnable(GL_LIGHTING);
	if(blend)		glEnable(GL_BLEND);
	if(!textu)	glDisable(GL_TEXTURE_2D);

	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
}



///////////////////////////////////////////////////////
///	Print											///
///////////////////////////////////////////////////////
bool ZFont::Print(GLint x, GLint y, int set, const char *fmt, ...)	// Where The Printing Happens
{
	if(!texture)		return false;
	
	char		text[1024];										// Holds Our String
	va_list		ap;													// Pointer To List Of Arguments

	if (fmt == NULL)	return true;				// If There's No Text, do Nothing

	va_start(ap, fmt);										// Parses The String For Variables
	vsprintf(text, fmt, ap);							// And Converts Symbols To Actual Numbers
	va_end(ap);														// Results Are Stored In Text

	if (set>1)		set=1;									// Did User Choose An Invalid Character Set?
																				// If So, Select Set 1 (Italic)

	glLoadIdentity();
	//glScalef(0.8f,0.8f,1.0f);						// Make The Text 2x smaller
	glTranslated(x,y,0);									// Position The Text (0,0 - Top Left)
	glListBase(baseListID-32+(128*set));	// Choose The Font Set (0 or 1)

	glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);		// Write The Text To The Screen

	return true;
}


