/*
   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:
      Fire fly particle module.
*/


#include "global.h"

#define FIREFLY_LIFESPAN   1000

/*
   NT:
   Listen to DSP:
*/
void FireFlyListen(edict_t *self, struct winampVisModule *this_mod)
{

}

/*
   NT:
   Fire fly Render routine:
*/
void FireFlyRender(edict_t *self)
{
   // NT: Only switch textures if last texture in pipeline has been modified:
   if (last_texture != self->skin_index)
      {
      glBindTexture (GL_TEXTURE_2D, self->skin_index); 
      last_texture = self->skin_index;
      }
   // Additive blending:
   self->rgba[3] = (self->die - eng.time) / (float)FIREFLY_LIFESPAN;
   self->scale += self->speed;
   glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
   glBegin(GL_TRIANGLE_STRIP);
      glTexCoord2f(0, 1);
      glVertex3f(-5, -5, 0);
      glTexCoord2f(1, 1);
      glVertex3f(5, -5, 0);      
      glTexCoord2f(0, 0);
      glVertex3f(-5, 5, 0);
      glTexCoord2f(1, 0);
      glVertex3f(5, 5, 0);
   glEnd();
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}


/*
   NT:
   Create a new fire fly. Allocate a skin for it, and give it enough information to
   be usefull for this example:
*/
#define FIREFLY_TEXTURE "c:/DiscoStu/gfx/smoke0.tga" // flower2
edict_t *FireFlySpawn(vec3_t origin, float velocity, vec3_t rgba, float alpha)
{
   skin_t *skin = NULL;
   static unsigned int skinned = NOT_FOUND;
   edict_t *ent = tEdictSpawn();  

   // No luck, something went wrong:
   if (!ent)
      {
      return NULL;
      }
   // NT: Only load skins if they are not allocated already:
   if (skinned == NOT_FOUND)
      {
      // NT: Does skin exist in library?
      if ((ent->skin_num = SkinIndex(FIREFLY_TEXTURE)) == NOT_FOUND)
         {
         int ix, iy;
         skin = new skin_t;
         memset(skin, 0, sizeof(*skin));
         ent->skin_num = SkinSpawn(FIREFLY_TEXTURE, skin);
         if (!LoadTGA(FIREFLY_TEXTURE, &skin->tga, skin->width, skin->height))
            EngineError("TGA LOAD: Marble '%s' could not be loaded.\n", FIREFLY_TEXTURE);
         //glGenTextures (1, &ent->skin_index);
         ent->skin_index = eng.skin_index++;
         glBindTexture (GL_TEXTURE_2D, ent->skin_index);
         TGA2GLTexture (skin, 0, 0, ix, iy); //TGA_ABSOLUTE_BLEND
	      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->index = ent->skin_index;
         skinned = ent->skin_index;
         InitGL();      
         }
      else // Just use skin from already loaded list:
         ent->skin_index = g_skins[ent->skin_num]->skin->index;
      }
   else
      ent->skin_index = skinned;

   // State of entity:
   ent->state = ENT_ST_USED | ENT_ST_PHYS | ENT_ST_VISIBLE | ENT_ST_ORTHO;

   // Origin of entity:
   VectorCopy(origin, ent->origin);
   // Velocity:
   ent->velocity[0] = velocity;
   ent->velocity[1] = velocity;
   // Angular velocity (Self Rotate):
   ent->avelocity[ROLL] = -5 + 5 * random();
   // RGBA:
   VectorCopy(rgba, ent->rgba);
   ent->rgba[3] = alpha;
   // Angles/Orientation:
   ent->angle[ROLL] = random() * 360;
   // Mass/Gravity:
   ent->mass = -.015f;
   // Scale of model:
   ent->scale = .18f;
   // Die in 1 second:
   ent->die = eng.time + FIREFLY_LIFESPAN;
   // Rendering routine:
   ent->render = FireFlyRender;
   ent->speed = .04f;
   return ent;
}

