/*
 * This program is under the GNU GPL.
 * Use at your own risk.
 *
 * written by David Bucciarelli (humanware@plus.it)
 *            Humanware s.r.l.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <GL/glut.h>
#ifndef M_PI
#define M_PI 3.14159265
#endif

#include "particles.h"
extern "C" {
#include "readtex.h"
}

#ifdef _WIN32
#include <windows.h>
#include <mmsystem.h>
#endif

#ifdef XMESA
#include "GL/xmesa.h"
static int fullscreen=1;
#endif

static int WIDTH=640;
static int HEIGHT=480;
static int NUMPART=7500;

#define FRAME 50

static float fogcolor[4]={1.0,1.0,1.0,1.0};

#define DIMP 40.0
#define DIMTP 32.0

static float q[4][3]={
  {-DIMP,0.0,-DIMP},
  {DIMP,0.0,-DIMP},
  {DIMP,0.0,DIMP},
  {-DIMP,0.0,DIMP}
};

static float qt[4][2]={
  {-DIMTP,-DIMTP},
  {DIMTP,-DIMTP},
  {DIMTP,DIMTP},
  {-DIMTP,DIMTP}
};

static int win=0;

static int fog=1;
static int help=1;

static GLuint groundid;

static float obs[3]={2.0,1.0,0.0};
static float dir[3];
static float v=0.0;
static float alpha=-90.0;
static float beta=90.0;

static particleSystem *ps;

static float gettime()
{
  static clock_t told=0;
  clock_t tnew,ris;

  tnew=clock();

  ris=tnew-told;

  told=tnew;

  return(ris/(float)CLOCKS_PER_SEC);
}

static float gettimerain()
{
  static clock_t told=0;
  clock_t tnew,ris;

  tnew=clock();

  ris=tnew-told;

  told=tnew;

  return(ris/(float)CLOCKS_PER_SEC);
}

static void calcposobs(void)
{
  dir[0]=sin(alpha*M_PI/180.0);
  dir[2]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0);
  dir[1]=cos(beta*M_PI/180.0);

  obs[0]+=v*dir[0];
  obs[1]+=v*dir[1];
  obs[2]+=v*dir[2];

  rainParticle::setRainingArea(obs[0]-7.0f,-0.2f,obs[2]-7.0f,obs[0]+7.0f,8.0f,obs[2]+7.0f);
}

static void printstring(void *font, const char *string)
{
  int len,i;

  len=(int)strlen(string);
  for(i=0;i<len;i++)
    glutBitmapCharacter(font,string[i]);
}

static void reshape(int width, int height)
{
  WIDTH=width;
  HEIGHT=height;
  glViewport(0,0,(GLint)width,(GLint)height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(70.0,width/(float)height,0.1,30.0);

  glMatrixMode(GL_MODELVIEW);
}

static void printhelp(void)
{
  glEnable(GL_BLEND);
  glColor4f(0.0,0.0,0.0,0.5);
  glRecti(40,40,600,440);
  glDisable(GL_BLEND);

  glColor3f(1.0,0.0,0.0);
  glRasterPos2i(300,420);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Help");

  glRasterPos2i(60,390);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"h - Toggle Help");

  glRasterPos2i(60,360);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"f - Toggle Fog");
  glRasterPos2i(60,330);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Arrow Keys - Rotate");
  glRasterPos2i(60,300);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"a - Increase velocity");
  glRasterPos2i(60,270);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"z - Decrease velocity");
  glRasterPos2i(60,240);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"l - Increase rain length");
  glRasterPos2i(60,210);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"k - Increase rain length");
}

static void drawrain(void)
{
  static int count=0;
  static char frbuf[80];
  float fr;

  glEnable(GL_DEPTH_TEST);

  if(fog)
    glEnable(GL_FOG);
  else
    glDisable(GL_FOG);

  glDepthMask(GL_TRUE);
  glClearColor(1.0,1.0,1.0,1.0);
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

  glPushMatrix();
  calcposobs();
  gluLookAt(obs[0],obs[1],obs[2],
	    obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2],
	    0.0,1.0,0.0);

  glColor4f(1.0,1.0,1.0,1.0);

  glEnable(GL_TEXTURE_2D);

  glBindTexture(GL_TEXTURE_2D,groundid);
  glBegin(GL_QUADS);
  glTexCoord2fv(qt[0]);
  glVertex3fv(q[0]);
  glTexCoord2fv(qt[1]);
  glVertex3fv(q[1]);
  glTexCoord2fv(qt[2]);
  glVertex3fv(q[2]);
  glTexCoord2fv(qt[3]);
  glVertex3fv(q[3]);
  glEnd();

  // Particle System

  glDisable(GL_TEXTURE_2D);
  glShadeModel(GL_SMOOTH);
  glEnable(GL_BLEND);

  ps->draw();
  ps->addTime(gettimerain());
  
  glShadeModel(GL_FLAT);
 

  if((count % FRAME)==0) {
    fr=gettime();
    sprintf(frbuf,"Frame rate: %f",FRAME/fr);
  }

  glDisable(GL_TEXTURE_2D);
  glDisable(GL_DEPTH_TEST);
  glDisable(GL_FOG);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glColor3f(1.0,0.0,0.0);
  glRasterPos2i(10,10);
  printstring(GLUT_BITMAP_HELVETICA_18,frbuf);
  glRasterPos2i(350,470);
  printstring(GLUT_BITMAP_HELVETICA_10,"Rain V1.0 Written by David Bucciarelli (humanware@plus.it)");

  if(help)
    printhelp();

  reshape(WIDTH,HEIGHT);
  glPopMatrix();

  glutSwapBuffers();

  count++;
}


static void special(int key, int x, int y)
{
  switch (key) {
  case GLUT_KEY_LEFT:
    alpha+=2.0;
    break;
  case GLUT_KEY_RIGHT:
    alpha-=2.0;
    break;
  case GLUT_KEY_DOWN:
    beta-=2.0;
    break;
  case GLUT_KEY_UP:
    beta+=2.0;
    break;
  }
}

static void key(unsigned char key, int x, int y)
{
  switch (key) {
  case 27:
    exit(0);
    break;

  case 'a':
    v+=0.01;
    break;
  case 'z':
    v-=0.01;
    break;

  case 'l':
    rainParticle::setLength(rainParticle::getLength()+0.025f);
    break;
  case 'k':
    rainParticle::setLength(rainParticle::getLength()-0.025f);
    break;

  case 'h':
    help=(!help);
    break;
  case 'f':
    fog=(!fog);
    break;
#ifdef XMESA
  case ' ':
    XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
    fullscreen=(!fullscreen);
    break;
#endif
  }
}

static void inittextures(void)
{
  GLubyte *img;
  GLint width,height;
  GLenum format;
  GLenum gluerr;

  glGenTextures(1,&groundid);
  glBindTexture(GL_TEXTURE_2D,groundid);

  if(!(img=LoadRGBImage("../images/s128.rgb",&width,&height,&format))){
  	fprintf(stderr,"Error reading a texture.\n");
  	exit(-1);
  }
  glPixelStorei(GL_UNPACK_ALIGNMENT,4);
  if((gluerr=(GLenum)gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGB,
			       GL_UNSIGNED_BYTE, (GLvoid *)(img)))) {
    fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr));
    exit(-1);
  }

  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

  glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
}

static void initparticle(void)
{
  ps=new particleSystem;

  rainParticle::setRainingArea(-7.0f,-0.2f,-7.0f,7.0f,8.0f,7.0f);

  for(int i=0;i<NUMPART;i++) {
    rainParticle *p=new rainParticle;
    p->randomHeight();

    ps->addParticle((particle *)p);
  }
}

int main(int ac,char **av)
{
  fprintf(stderr,"Rain V1.0\nWritten by David Bucciarelli (humanware@plus.it)\n");

  /* Default settings */

  WIDTH=640;
  HEIGHT=480;

  glutInitWindowPosition(0,0);
  glutInitWindowSize(WIDTH,HEIGHT);
  glutInit(&ac,av);

  glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE);

  if(!(win=glutCreateWindow("Rain"))) {
    fprintf(stderr,"Error opening a window.\n");
    exit(-1);
  }
  
  reshape(WIDTH,HEIGHT);

  inittextures();

  glShadeModel(GL_FLAT);
  glEnable(GL_DEPTH_TEST);

  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

  glEnable(GL_FOG);
  glFogi(GL_FOG_MODE,GL_EXP);
  glFogfv(GL_FOG_COLOR,fogcolor);
  glFogf(GL_FOG_DENSITY,0.1);
#ifdef FX
  glHint(GL_FOG_HINT,GL_NICEST);
#endif

  initparticle();

  glutKeyboardFunc(key);
  glutSpecialFunc(special);
  glutDisplayFunc(drawrain);
  glutIdleFunc(drawrain);
  glutReshapeFunc(reshape);
  glutMainLoop();

  return(0);
}
