/*
   CMSC 427 - Term Project Candidate
   ---------------------------------

   Beth Weinstein - bweinste@wam.umd.edu
   Ben Stewart - stewartb@wam.umd.edu
   Nawfel Tricha - Topaz@endorproductions.com

   Minimal OpenGL project using Microsoft Visual C++.
   This project is a premilinary candidate for the term 
   project required by CMSC 427.

   ABSTRACT:
      In this project, we will develop several fast 
      rendering and collision routines which would 
      require C/C++ speed and accuracy and then 
      implement a VisualJ++ interface.

   MODULE:
      Text/Font rendering module.
*/

#include "Global.h"

#define SIXTEENTH 1.0f/16.0f
#define FONT_CELL_X_SIZE .10f
#define FONT_CELL_Y_SIZE .16f
#define FONT_CELL_X_SKIP .20f
#define FONT_CELL_Y_SKIP .32f

static skin_t r_font_skin;
static skin_t r_console_skin;
static skin_t r_back_console_skin;

// Compile in debug mode:
#define CMP_DEBUGMODE


/*
   NT:
   Called when initialized. Loads font into model.
*/
void LoadFont(char *filename)
{   
   int ix, iy;
   skin_t *skin = &r_font_skin;
   r_font_skin.index = 0;
   r_font_skin.tga = NULL;
   if (!LoadTGA(filename, &r_font_skin.tga, r_font_skin.width, r_font_skin.height))
      EngineError("TGA LOAD: Font '%s' could not be loaded.\n", filename);


   //glGenTextures (1, &skin->index);
   skin->index = eng.skin_index++;
   glBindTexture (GL_TEXTURE_2D, skin->index);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   TGA2GLTexture (skin, 0, TGA_PROGRESSIVE_BLEND, ix, iy);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexImage2D (GL_TEXTURE_2D, 0, 4, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, skin->glTexture);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_DONT_CARE);	

   skin = &r_console_skin;
   filename = "c:/DiscoStu/gfx/console.tga";
   if (!LoadTGA(filename, &r_console_skin.tga, r_console_skin.width, r_console_skin.height))
      EngineError("TGA LOAD: Console '%s' could not be loaded.\n", filename);

   //glGenTextures (1, &skin->index);
   skin->index = eng.skin_index++;
   glBindTexture (GL_TEXTURE_2D, skin->index);
   TGA2GLTexture (skin, 0, 0, ix, iy);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexImage2D (GL_TEXTURE_2D, 0, 4, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, skin->glTexture);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_DONT_CARE);	

   skin = &r_back_console_skin;
   filename = "c:/DiscoStu/gfx/flower.tga";
   if (!LoadTGA(filename, &r_back_console_skin.tga, r_back_console_skin.width, r_back_console_skin.height))
      EngineError("TGA LOAD: Console-2 '%s' could not be loaded.\n", filename);

   //glGenTextures (1, &skin->index);
   skin->index = eng.skin_index++;
   glBindTexture (GL_TEXTURE_2D, skin->index);
   TGA2GLTexture (skin, 0, TGA_PROGRESSIVE_BLEND, ix, iy);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexImage2D (GL_TEXTURE_2D, 0, 4, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, skin->glTexture);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_DONT_CARE);	


   InitGL();
}

/*
   NT:
   Prints string in (ptr) at vector (t_origin).
   (t_origin) is updated to next raster position, so there is no need to keep
   track of vector parameters:
*/
void FontPrint (float *t_origin, char *ptr, float zoom)
{
   static vec3_t current_origin;
   int real_x, real_y;
   vec3_t origin;
   float old_x;
   float cell_x, cell_y, cell_x_skip, cell_y_skip;

   if (!t_origin)
      t_origin = current_origin;

   old_x = t_origin[0];
   if (zoom != 1)
      {
      cell_x = zoom * FONT_CELL_X_SIZE; 
      cell_y = zoom * FONT_CELL_Y_SIZE;
      cell_x_skip = zoom * FONT_CELL_X_SKIP;
      cell_y_skip = zoom * FONT_CELL_Y_SKIP;
      zoom *= SIXTEENTH;
      }
   else
      {
      cell_x = FONT_CELL_X_SIZE; 
      cell_y = FONT_CELL_Y_SIZE;
      cell_x_skip = FONT_CELL_X_SKIP;
      cell_y_skip = FONT_CELL_Y_SKIP;
      zoom = SIXTEENTH;
      }
   
   VectorCopy(t_origin, origin);

   glBindTexture (GL_TEXTURE_2D, r_font_skin.index);
   glBegin(GL_TRIANGLE_STRIP);
   while (*ptr)
      {
      if (*ptr != '\n')
         {
         real_y = *ptr >> 4;
         real_x = *ptr & 15;
            glTexCoord2f(real_x * SIXTEENTH, (real_y + 1) * SIXTEENTH);
            glVertex3f (origin[0] - cell_x, origin[1] - cell_y, origin[2]);
            glTexCoord2f((real_x + 1) * SIXTEENTH, (real_y + 1) * SIXTEENTH);
            glVertex3f (origin[0] + cell_x, origin[1] - cell_y, origin[2]);
            glTexCoord2f(real_x * SIXTEENTH, real_y * SIXTEENTH);
            glVertex3f (origin[0] - cell_x, origin[1] + cell_y, origin[2]);
            glTexCoord2f((real_x + 1)  * SIXTEENTH, real_y * SIXTEENTH);
            glVertex3f (origin[0] + cell_x, origin[1] + cell_y, origin[2]);
         origin[0] +=  cell_x_skip;
         }
      else
         {
         origin[0] = old_x;
         origin[1] -= cell_y_skip;
         }
      ptr++;
      }
   glEnd();
   VectorCopy(origin, t_origin);
   VectorCopy(origin, current_origin);
}

/*
   NT:
   Prints string in (ptr) at vector (t_origin).
   (t_origin) is updated to next raster position, so there is no need to keep
   track of vector parameters:
*/
void FontPrintv(float *origin, char *format, ...)
{
	va_list		argptr;
	static char		string[1024];
   va_start (argptr, format);
	vsprintf (string, format, argptr);
	va_end (argptr);
   FontPrint (origin, string);
}


/*
   NT: 
   Display the background (without Z-Buffering):
*/
void DisplayConsole(float scale_scene)
{
   static float x_scroll = 0;
   glLoadIdentity();

   glDisable(GL_DEPTH_TEST);
   glEnable(GL_TEXTURE_2D);
   glBindTexture (GL_TEXTURE_2D, r_console_skin.index);
   glDisable(GL_BLEND);
   // Draw first layer:
   glColor3f(.2f, .2f, .2f);
   glBegin(GL_TRIANGLE_STRIP);
      glTexCoord2f(0, 1);
      glVertex3f(-5.2, -4, -4);
      glTexCoord2f(1, 1);
      glVertex3f(5.2, -4, -4);
      glTexCoord2f(0, 0);
      glVertex3f(-5.2, 4, -4);
      glTexCoord2f(1, 0);
      glVertex3f(5.2, 4, -4);
   glEnd();

   // Draw second layer:
   glBindTexture (GL_TEXTURE_2D, r_back_console_skin.index);
   glEnable(GL_BLEND);
   glColor4f(.7f, .7f, .7f, .4f);
   glRotatef(x_scroll + scale_scene * 36, 0, 0, 1);
   glScalef(scale_scene, scale_scene, 1);
   glBegin(GL_TRIANGLE_STRIP);
      glTexCoord2f(0, 1);
      glVertex3f(-5.2, -4, -4);
      glTexCoord2f(1, 1);
      glVertex3f(5.2, -4, -4);
      glTexCoord2f(0, 0);
      glVertex3f(-5.2, 4, -4);
      glTexCoord2f(1, 0);
      glVertex3f(5.2, 4, -4);
   glEnd();
   x_scroll += 1;
 }


/*
   NT: 
   Draws Head Up Display (Overlay without Z-Buffering):
*/
void DisplayHUD(float scale_scene)
{
   vec3_t origin = {-5.1, -3.55, -4};   
   glLoadIdentity();
   glDisable(GL_DEPTH_TEST);
   glEnable(GL_TEXTURE_2D);
   glEnable(GL_BLEND);
// Only if compiled with DEBUGMODE ON
#ifdef CMP_DEBUGMODE
   glColor3f(.6, .4, 1);
   FontPrint (origin, "[DEBUG]\n");
   FontPrintv (origin, "Num Edicts: %i - Next Stanza: -%u sec\n", eng.num_edicts, (eng.next_stanza - eng.time) / 1000);
#endif 

   VectorSet(origin, -5.1, 3.7, -4);
   glColor3f(.8f, .6f, 0);
   FontPrint (origin, "Disco Stu: Version 1.0a\n");
   FontPrint (origin, "CMSC 427 - Spring 2000\n");
}

void DisplayHELP()
{
   vec3_t origin = {-5.1, 2.5, -5};
   glColor3f(0, 1, 0);   
   FontPrint (origin, "Commands:\n");
   FontPrint (origin, "F1: Help\n"
                    "F2: Toggle spectrum analyzer ON/OFF\n"
                    "F3: Toggle wave rendering ON/OFF\n"
                    "F4: Toggle Console ON/OFF\n"
                    "F5: Toggle HUD ON/OFF\n"
                    "F6: Toggle Flush ON/OFF\n"
                    "F7: Toggle Global DSP Lighting ON/OFF\n"
                    "F8: Toggle Skeletal Model Overlay ON/OFF\n");
}
