/*
 * Demo of a reflective, texture-mapped surface with OpenGL.
 * Brian Paul   August 14, 1995   This file is in the public domain.
 *
 * Hardware texture mapping is highly recommended!
 *
 * The basic steps are:
 *    1. Render the reflective object (a polygon) from the normal viewpoint,
 *       setting the stencil planes = 1.
 *    2. Render the scene from a special viewpoint:  the viewpoint which
 *       is on the opposite side of the reflective plane.  Only draw where
 *       stencil = 1.  This draws the objects in the reflective surface.
 *    3. Render the scene from the original viewpoint.  This draws the
 *       objects in the normal fashion.  Use blending when drawing
 *       the reflective, textured surface.
 *
 * This is a very crude demo.  It could be much better.
 */
 
/*
 * Authors:
 *   Brian Paul
 *   Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code.
 *   Mark Kilgard (April 1997)
 *   Brian Paul (April 2000 - added keyboard d/s options)
 *   Brian Paul (August 2005 - added multi window feature)
 */


#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "GL/glut.h"
#include "showbuffer.h"
#include "readtex.h"


#define DEG2RAD (3.14159/180.0)
#define TABLE_TEXTURE "../images/tile.rgb"
#define MAX_OBJECTS 2
#define INIT_WIDTH 400
#define INIT_HEIGHT 300

#ifdef _WIN32
#undef CreateWindowA
#endif

struct window {
   int id;               /* returned by glutCreateWindow() */
   int width, height;
   GLboolean anim;
   GLfloat xrot, yrot;
   GLfloat spin;
   GLenum showBuffer;
   GLenum drawBuffer;
   GLuint table_list;
   GLuint objects_list[MAX_OBJECTS];
   double t0;
   struct window *next;
};


static struct window *FirstWindow = NULL;


static void
CreateWindow(void);


static struct window *
CurrentWindow(void)
{
   int id = glutGetWindow();
   struct window *w;
   for (w = FirstWindow; w; w = w->next) {
      if (w->id == id)
         return w;
   }
   return NULL;
}


static GLboolean
AnyAnimating(void)
{
   struct window *w;
   for (w = FirstWindow; w; w = w->next) {
      if (w->anim)
         return 1;
   }
   return 0;
}


static void
KillWindow(struct window *w)
{
   struct window *win, *prev = NULL;
   for (win = FirstWindow; win; win = win->next) {
      if (win == w) {
         if (prev) {
            prev->next = win->next;
         }
         else {
            FirstWindow = win->next;
         }
         glutDestroyWindow(win->id);
         win->next = NULL;
         free(win);
         return;
      }
      prev = win;
   }
}


static void
KillAllWindows(void)
{
   while (FirstWindow)
      KillWindow(FirstWindow);
}


static GLuint
MakeTable(void)
{
   static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
   static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
   GLuint table_list;

   table_list = glGenLists(1);
   glNewList( table_list, GL_COMPILE );

   /* load table's texture */
   glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
   /*glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
   glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
   glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
   
   /* draw textured square for the table */
   glPushMatrix();
   glScalef( 4.0, 4.0, 4.0 );
   glBegin( GL_POLYGON );
   glNormal3f( 0.0, 1.0, 0.0 );
   glTexCoord2f( 0.0, 0.0 );   glVertex3f( -1.0, 0.0,  1.0 );
   glTexCoord2f( 1.0, 0.0 );   glVertex3f(  1.0, 0.0,  1.0 );
   glTexCoord2f( 1.0, 1.0 );   glVertex3f(  1.0, 0.0, -1.0 );
   glTexCoord2f( 0.0, 1.0 );   glVertex3f( -1.0, 0.0, -1.0 );
   glEnd();
   glPopMatrix();

   glDisable( GL_TEXTURE_2D );

   glEndList();
   return table_list;
}


static void
MakeObjects(GLuint *objects_list)
{
   GLUquadricObj *q;

   static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
   static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
   static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };

   q = gluNewQuadric();
   gluQuadricDrawStyle( q, GLU_FILL );
   gluQuadricNormals( q, GLU_SMOOTH );

   objects_list[0] = glGenLists(1);
   glNewList( objects_list[0], GL_COMPILE );
   glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
   glMaterialfv( GL_FRONT, GL_EMISSION, black );
   gluCylinder( q, 0.5, 0.5,  1.0, 15, 1 );
   glEndList();

   objects_list[1] = glGenLists(1);
   glNewList( objects_list[1], GL_COMPILE );
   glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
   glMaterialfv( GL_FRONT, GL_EMISSION, black );
   gluCylinder( q, 1.5, 0.0,  2.5, 15, 1 );
   glEndList();

   gluDeleteQuadric(q);
}


static void
InitWindow(struct window *w)
{
   GLint imgWidth, imgHeight;
   GLenum imgFormat;
   GLubyte *image = NULL;

   w->table_list = MakeTable();
   MakeObjects(w->objects_list);

   image = LoadRGBImage( TABLE_TEXTURE, &imgWidth, &imgHeight, &imgFormat );
   if (!image) {
      printf("Couldn't read %s\n", TABLE_TEXTURE);
      exit(0);
   }

   gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imgWidth, imgHeight,
                     imgFormat, GL_UNSIGNED_BYTE, image);
   free(image);

   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

   glShadeModel( GL_FLAT );
   
   glEnable( GL_LIGHT0 );
   glEnable( GL_LIGHTING );

   glClearColor( 0.5, 0.5, 0.9, 0.0 );

   glEnable( GL_NORMALIZE );
}


static void
Reshape(int width, int height)
{
   struct window *w = CurrentWindow();
   GLfloat yAspect = 2.5;
   GLfloat xAspect = yAspect * (float) width / (float) height;
   w->width = width;
   w->height = height;
   glViewport(0, 0, width, height);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glFrustum( -xAspect, xAspect, -yAspect, yAspect, 10.0, 30.0 );
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}


static void
DrawObjects(struct window *w, GLfloat eyex, GLfloat eyey, GLfloat eyez)
{
   (void) eyex;
   (void) eyey;
   (void) eyez;
#ifndef USE_ZBUFFER
   if (eyex<0.5) {
#endif
      glPushMatrix();
      glTranslatef( 1.0, 1.5, 0.0 );
      glRotatef( w->spin, 1.0, 0.5, 0.0 );
      glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 );
      glCallList( w->objects_list[0] );
      glPopMatrix();
      
      glPushMatrix();
      glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*w->spin) ), 0.0 );
      glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 );
      glRotatef( w->spin, 1.0, 0.5, 0.0 );
      glScalef( 0.5, 0.5, 0.5 );
      glCallList( w->objects_list[1] );
      glPopMatrix();
#ifndef USE_ZBUFFER
   }
   else {	
      glPushMatrix();
      glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*w->spin) ), 0.0 );
      glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 );
      glRotatef( w->spin, 1.0, 0.5, 0.0 );
      glScalef( 0.5, 0.5, 0.5 );
      glCallList( w->objects_list[1] );
      glPopMatrix();

      glPushMatrix();
      glTranslatef( 1.0, 1.5, 0.0 );
      glRotatef( w->spin, 1.0, 0.5, 0.0 );
      glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 );
      glCallList( w->objects_list[0] );
      glPopMatrix();
   }
#endif
}


static void
DrawTable(struct window *w)
{
   glCallList(w->table_list);
}


static void
DrawWindow(void)
{
   struct window *w = CurrentWindow();
   static GLfloat light_pos[] = { 0.0, 20.0, 0.0, 1.0 };
   GLfloat dist = 20.0;
   GLfloat eyex, eyey, eyez;

   if (w->drawBuffer == GL_NONE) {
      glDrawBuffer(GL_BACK);
      glReadBuffer(GL_BACK);
   }
   else {
      glDrawBuffer(w->drawBuffer);
      glReadBuffer(w->drawBuffer);
   }

   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

   if (w->drawBuffer == GL_NONE) {
      glDrawBuffer(GL_NONE);
   }

   eyex = dist  *  cos(w->yrot * DEG2RAD)  *  cos(w->xrot * DEG2RAD);
   eyez = dist  *  sin(w->yrot * DEG2RAD)  *  cos(w->xrot * DEG2RAD);
   eyey = dist  *  sin(w->xrot * DEG2RAD);

   /* view from top */
   glPushMatrix();
   gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );

   glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
 
   /* draw table into stencil planes */
   glDisable( GL_DEPTH_TEST );
   glEnable( GL_STENCIL_TEST );
   glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
   glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
   glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
   DrawTable(w);
   glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );

   glEnable( GL_DEPTH_TEST );

   /* render view from below (reflected viewport) */
   /* only draw where stencil==1 */
   if (eyey>0.0) {
      glPushMatrix();
 
      glStencilFunc( GL_EQUAL, 1, 0xffffffff );  /* draw if ==1 */
      glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
      glScalef( 1.0, -1.0, 1.0 );

      /* Reposition light in reflected space. */
      glLightfv(GL_LIGHT0, GL_POSITION, light_pos);

      DrawObjects(w, eyex, eyey, eyez);
      glPopMatrix();

      /* Restore light's original unreflected position. */
      glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
   }

   glDisable( GL_STENCIL_TEST );

   glEnable( GL_BLEND );
   glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

   glEnable( GL_TEXTURE_2D );
   DrawTable(w);
   glDisable( GL_TEXTURE_2D );
   glDisable( GL_BLEND );

   /* view from top */
   glPushMatrix();

   DrawObjects(w, eyex, eyey, eyez);

   glPopMatrix();

   glPopMatrix();

   if (w->showBuffer == GL_DEPTH) {
      ShowDepthBuffer(w->width, w->height, 1.0, 0.0);
   }
   else if (w->showBuffer == GL_STENCIL) {
      ShowStencilBuffer(w->width, w->height, 255.0, 0.0);
   }
   else if (w->showBuffer == GL_ALPHA) {
      ShowAlphaBuffer(w->width, w->height);
   }

   if (w->drawBuffer == GL_FRONT)
      glFinish();
   else
      glutSwapBuffers();

   /* calc/show frame rate */
   {
      static GLint t0 = 0;
      static GLint frames = 0;
      GLint t = glutGet(GLUT_ELAPSED_TIME);
      frames++;
      if (t - t0 >= 5000) {
         GLfloat seconds = (t - t0) / 1000.0;
         GLfloat fps = frames / seconds;
         printf("%d frames in %g seconds = %g FPS\n", frames, seconds, fps);
         fflush(stdout);
         t0 = t;
         frames = 0;
      }
   }
}


static void
Idle(void)
{
   double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
   struct window *w;
   for (w = FirstWindow; w; w = w->next) {
      if (w->anim) {
         double dt;
         if (w->t0 < 0.0)
            w->t0 = t;
         dt = t - w->t0;
         w->t0 = t;
         w->spin += 60.0 * dt;
         w->yrot += 90.0 * dt;
         assert(w->id);
         glutSetWindow(w->id);
         glutPostRedisplay();
      }
   }
}


static void
UpdateIdleFunc(void)
{
   if (AnyAnimating())
      glutIdleFunc(Idle);
   else
      glutIdleFunc(NULL);
}

static void
Key(unsigned char key, int x, int y)
{
   struct window *w = CurrentWindow();
   (void) x;
   (void) y;

   switch (key) {
   case 'd':
      w->showBuffer = GL_DEPTH;
      glutPostRedisplay();
      break;
   case 's':
      w->showBuffer = GL_STENCIL;
      glutPostRedisplay();
      break;
   case 'a':
      w->showBuffer = GL_ALPHA;
      glutPostRedisplay();
      break;
   case 'c':
      w->showBuffer = GL_NONE;
      glutPostRedisplay();
      break;
   case 'f':
      if (w->drawBuffer == GL_FRONT)
         w->drawBuffer = GL_BACK;
      else
         w->drawBuffer = GL_FRONT;
      glutPostRedisplay();
      break;
   case '0':
      w->drawBuffer = GL_NONE;
      glutPostRedisplay();
      break;
   case ' ':
      w->anim = !w->anim;
      w->t0 = -1;
      UpdateIdleFunc();
      glutPostRedisplay();
      break;
   case 'n':
      CreateWindow();
      UpdateIdleFunc();
      break;
   case 'k':
      KillWindow(w);
      if (FirstWindow == NULL)
         exit(0);
      break;
   case 27:
      KillAllWindows();
      exit(0);
      break;
   default:
      ;
   }
}


static void
SpecialKey(int key, int x, int y)
{
   struct window *w = CurrentWindow();
   (void) x;
   (void) y;
   switch (key) {
      case GLUT_KEY_UP:
         w->xrot += 3.0;
         if (w->xrot > 85)
            w->xrot = 85;
         break;
      case GLUT_KEY_DOWN:
         w->xrot -= 3.0;
         if (w->xrot < 5)
            w->xrot = 5;
         break;
      case GLUT_KEY_LEFT:
         w->yrot += 3.0;
         break;
      case GLUT_KEY_RIGHT:
         w->yrot -= 3.0;
         break;
   }
   glutPostRedisplay();
}


static void
CreateWindow(void)
{
   char title[1000];
   struct window *w = (struct window *) calloc(1, sizeof(struct window));
   
   glutInitWindowSize(INIT_WIDTH, INIT_HEIGHT);
   w->id = glutCreateWindow("foo");
   sprintf(title, "reflect window %d", w->id);
   glutSetWindowTitle(title);
   assert(w->id);
   w->width = INIT_WIDTH;
   w->height = INIT_HEIGHT;
   w->anim = GL_TRUE;
   w->xrot = 30.0;
   w->yrot = 50.0;
   w->spin = 0.0;
   w->showBuffer = GL_NONE;
   w->drawBuffer = GL_BACK;

   InitWindow(w);

   glutReshapeFunc(Reshape);
   glutDisplayFunc(DrawWindow);
   glutKeyboardFunc(Key);
   glutSpecialFunc(SpecialKey);

   /* insert at head of list */
   w->next = FirstWindow;
   FirstWindow = w;
}


static void
Usage(void)
{
   printf("Keys:\n");
   printf("  a      - show alpha buffer\n");
   printf("  d      - show depth buffer\n");
   printf("  s      - show stencil buffer\n");
   printf("  c      - show color buffer\n");
   printf("  f      - toggle rendering to front/back color buffer\n");
   printf("  n      - create new window\n");
   printf("  k      - kill window\n");
   printf("  SPACE  - toggle animation\n");
   printf("  ARROWS - rotate scene\n");
}


int
main(int argc, char *argv[])
{
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH |
                       GLUT_STENCIL | GLUT_ALPHA);
   CreateWindow();
   glutIdleFunc(Idle);
   Usage();
   glutMainLoop();
   return 0;
}
