/**
 * Simple engine demo (crankshaft, pistons, connecting rods)
 *
 * Brian Paul
 * June 2006
 */

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


#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

#define DEG_TO_RAD(DEG)  ((DEG) * M_PI / 180.0)

#define TEXTURE_FILE "../images/reflect.rgb"

/* Target engine speed: */
const int RPM = 100.0;


/**
 * Engine description.
 */
typedef struct
{
   const char *Name;
   int Pistons;
   int Cranks;
   float V_Angle;
   float PistonRadius;
   float PistonHeight;
   float WristPinRadius;
   float Throw;
   float CrankPlateThickness;
   float CrankPinRadius;
   float CrankJournalRadius;
   float CrankJournalLength;
   float ConnectingRodLength;
   float ConnectingRodThickness;
   /* display list IDs */
   GLuint CrankList;
   GLuint ConnRodList;
   GLuint PistonList;
   GLuint BlockList;
} Engine;


typedef struct
{
   float CurQuat[4];
   float Distance;
   /* When mouse is moving: */
   GLboolean Rotating, Translating;
   GLint StartX, StartY;
   float StartDistance;
} ViewInfo;


typedef enum
{
   LIT,
   WIREFRAME,
   TEXTURED
} RenderMode;


typedef struct
{
   RenderMode Mode;
   GLboolean Anim;
   GLboolean Wireframe;
   GLboolean Blend;
   GLboolean Antialias;
   GLboolean Texture;
   GLboolean UseLists;
   GLboolean DrawBox;
   GLboolean ShowInfo;
   GLboolean ShowBlock;
} RenderInfo;


static GLUquadric *Q;

static GLfloat Theta = 0.0;

static const GLfloat PistonColor[4] = { 1.0, 0.5, 0.5, 1.0 };
static const GLfloat ConnRodColor[4] = { 0.7, 1.0, 0.7, 1.0 };
static const GLfloat CrankshaftColor[4] = { 0.7, 0.7, 1.0, 1.0 };
static const GLfloat BlockColor[4] = {0.8, 0.8, 0.8, 0.75 };

static GLuint TextureObj;
static GLint WinWidth = 800, WinHeight = 500;

static ViewInfo View;
static RenderInfo Render;

#define NUM_ENGINES 3
static Engine Engines[NUM_ENGINES] =
{
   {
      "V-6",
      6,    /* Pistons */
      3,    /* Cranks */
      90.0, /* V_Angle */
      0.5,  /* PistonRadius */
      0.6,  /* PistonHeight */
      0.1,  /* WristPinRadius */
      0.5,  /* Throw */
      0.2,  /* CrankPlateThickness */
      0.25, /* CrankPinRadius */
      0.3,  /* CrankJournalRadius */
      0.4,  /* CrankJournalLength */
      1.5,  /* ConnectingRodLength */
      0.1   /* ConnectingRodThickness */
   },
   {
      "Inline-4",
      4,    /* Pistons */
      4,    /* Cranks */
      0.0,  /* V_Angle */
      0.5,  /* PistonRadius */
      0.6,  /* PistonHeight */
      0.1,  /* WristPinRadius */
      0.5,  /* Throw */
      0.2,  /* CrankPlateThickness */
      0.25, /* CrankPinRadius */
      0.3,  /* CrankJournalRadius */
      0.4,  /* CrankJournalLength */
      1.5,  /* ConnectingRodLength */
      0.1   /* ConnectingRodThickness */
   },
   {
      "Boxer-6",
      6,    /* Pistons */
      3,    /* Cranks */
      180.0,/* V_Angle */
      0.5,  /* PistonRadius */
      0.6,  /* PistonHeight */
      0.1,  /* WristPinRadius */
      0.5,  /* Throw */
      0.2,  /* CrankPlateThickness */
      0.25, /* CrankPinRadius */
      0.3,  /* CrankJournalRadius */
      0.4,  /* CrankJournalLength */
      1.5,  /* ConnectingRodLength */
      0.1   /* ConnectingRodThickness */
   }
};

static int CurEngine = 0;



static void
InitViewInfo(ViewInfo *view)
{
   view->Rotating = GL_FALSE;
   view->Translating = GL_FALSE;
   view->StartX = view->StartY = 0;
   view->Distance = 12.0;
   view->StartDistance = 0.0;
   view->CurQuat[0] = -0.194143;
   view->CurQuat[1] = 0.507848;
   view->CurQuat[2] = 0.115245;
   view->CurQuat[3] = 0.831335;
}


static void
InitRenderInfo(RenderInfo *render)
{
   render->Mode = LIT;
   render->Anim = GL_TRUE;
   render->Wireframe = GL_FALSE;
   render->Blend = GL_FALSE;
   render->Antialias = GL_FALSE;
   render->Texture = GL_FALSE;
   render->DrawBox = GL_FALSE;
   render->ShowInfo = GL_TRUE;
   render->ShowBlock = GL_FALSE;
   render->UseLists = GL_FALSE;
}


/**
 * Set GL for given rendering mode.
 */
static void
SetRenderState(RenderMode mode)
{
   static const GLfloat gray2[4] = { 0.2, 0.2, 0.2, 1.0 };
   static const GLfloat gray4[4] = { 0.4, 0.4, 0.4, 1.0 };

   /* defaults */
   glDisable(GL_LIGHTING);
   glDisable(GL_TEXTURE_2D);
   glDisable(GL_BLEND);
   glDisable(GL_LINE_SMOOTH);
   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
   glDisable(GL_TEXTURE_GEN_S);
   glDisable(GL_TEXTURE_GEN_T);
   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, gray2);

   switch (mode) {
   case LIT:
      glEnable(GL_LIGHTING);
      break;
   case WIREFRAME:
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
      glEnable(GL_LINE_SMOOTH);
      glEnable(GL_BLEND);
      glLineWidth(1.5);
      break;
   case TEXTURED:
      glEnable(GL_LIGHTING);
      glEnable(GL_TEXTURE_2D);
      glEnable(GL_TEXTURE_GEN_S);
      glEnable(GL_TEXTURE_GEN_T);
      glLightModelfv(GL_LIGHT_MODEL_AMBIENT, gray4);
      break;
   default:
      ;
   }
}


/**
 * Animate the engine parts.
 */
static void
Idle(void)
{
   /* convert degrees per millisecond to RPM: */
   const float m = 360.0 / 1000.0 / 60.0;
   GLint t = glutGet(GLUT_ELAPSED_TIME);
   Theta = ((int) (t * RPM * m)) % 360;
   glutPostRedisplay();
}


/**
 * Compute piston's position along its stroke.
 */
static float
PistonStrokePosition(float throwDist, float crankAngle, float connRodLength)
{
   float x = throwDist * cos(DEG_TO_RAD(crankAngle));
   float y = throwDist * sin(DEG_TO_RAD(crankAngle));
   float pos = y + sqrt(connRodLength * connRodLength - x * x);
   return pos;
}


/**
 * Compute position of nth piston along the crankshaft.
 */
static float
PistonShaftPosition(const Engine *eng, int piston)
{
   const int i = piston / (eng->Pistons / eng->Cranks);
   float z;
   assert(piston < eng->Pistons);
   z = 1.5 * eng->CrankJournalLength + eng->CrankPlateThickness
      + i * (2.0 * (eng->CrankJournalLength + eng->CrankPlateThickness));
   if (eng->Pistons > eng->Cranks) {
      if (piston & 1)
         z += eng->ConnectingRodThickness;
      else
         z -= eng->ConnectingRodThickness;
   }
   return z;
}


/**
 * Compute distance between two adjacent pistons
 */
static float
PistonSpacing(const Engine *eng)
{
   const int pistonsPerCrank = eng->Pistons / eng->Cranks;
   const float z0 = PistonShaftPosition(eng, 0);
   const float z1 = PistonShaftPosition(eng, pistonsPerCrank);
   return z1 - z0;
}


/**
 * (x0, y0) = position of big end on crankshaft
 * (x1, y1) = position of small end on piston
 */
static void
ComputeConnectingRodPosition(float throwDist, float crankAngle,
                             float connRodLength,
                             float *x0, float *y0, float *x1, float *y1)
{
   *x0 = throwDist * cos(DEG_TO_RAD(crankAngle));
   *y0 = throwDist * sin(DEG_TO_RAD(crankAngle));
   *x1 = 0.0;
   *y1 = PistonStrokePosition(throwDist, crankAngle, connRodLength);
}


/**
 * Compute total length of the crankshaft.
 */
static float
CrankshaftLength(const Engine *eng)
{
   float len = (eng->Cranks * 2 + 1) * eng->CrankJournalLength
             + 2 * eng->Cranks * eng->CrankPlateThickness;
   return len;
}


/**
 * Draw a piston.
 * Axis of piston = Z axis.  Wrist pin is centered on (0, 0, 0).
 */
static void
DrawPiston(const Engine *eng)
{
   const int slices = 30, stacks = 4, loops = 4;
   const float innerRadius = 0.9 * eng->PistonRadius;
   const float innerHeight = eng->PistonHeight - 0.15;
   const float wristPinLength = 1.8 * eng->PistonRadius;

   assert(Q);

   glPushMatrix();
   glTranslatef(0, 0, -1.1 * eng->WristPinRadius);

   gluQuadricOrientation(Q, GLU_INSIDE);

   /* bottom rim */
   gluDisk(Q, innerRadius, eng->PistonRadius, slices, 1/*loops*/);

   /* inner cylinder */
   gluCylinder(Q, innerRadius, innerRadius, innerHeight, slices, stacks);

   /* inside top */
   glPushMatrix();
   glTranslatef(0, 0, innerHeight);
   gluDisk(Q, 0, innerRadius, slices, loops);
   glPopMatrix();

   gluQuadricOrientation(Q, GLU_OUTSIDE);

   /* outer cylinder */
   gluCylinder(Q, eng->PistonRadius, eng->PistonRadius, eng->PistonHeight,
               slices, stacks);

   /* top */
   glTranslatef(0, 0, eng->PistonHeight);
   gluDisk(Q, 0, eng->PistonRadius, slices, loops);

   glPopMatrix();

   /* wrist pin */
   glPushMatrix();
   glTranslatef(0, 0.5 * wristPinLength, 0.0);
   glRotatef(90, 1, 0, 0);
   gluCylinder(Q, eng->WristPinRadius, eng->WristPinRadius, wristPinLength,
               slices, stacks);
   glPopMatrix();
}


/**
 * Draw piston at particular position.
 */
static void
DrawPositionedPiston(const Engine *eng, float crankAngle)
{
   const float pos = PistonStrokePosition(eng->Throw, crankAngle,
                                          eng->ConnectingRodLength);
   glPushMatrix();
      glRotatef(-90, 1, 0, 0);
      glTranslatef(0, 0, pos);
      if (eng->PistonList)
         glCallList(eng->PistonList);
      else
         DrawPiston(eng);
   glPopMatrix();
}


/**
 * Draw connector plate.  Used for crankshaft and connecting rods.
 */
static void
DrawConnector(float length, float thickness,
              float bigEndRadius, float smallEndRadius)
{
   const float bigRadius = 1.2 * bigEndRadius;
   const float smallRadius = 1.2 * smallEndRadius;
   const float z0 = -0.5 * thickness, z1 = -z0;
   GLfloat points[36][2], normals[36][2];
   int i;

   /* compute vertex locations, normals */
   for (i = 0; i < 36; i++) {
      const int angle = i * 10;
      float x = cos(DEG_TO_RAD(angle));
      float y = sin(DEG_TO_RAD(angle));
      normals[i][0] = x;
      normals[i][1] = y;
      if (angle >= 0 && angle <= 180) {
         x *= smallRadius;
         y = y * smallRadius + length;
      }
      else {
         x *= bigRadius;
         y *= bigRadius;
      }
      points[i][0] = x;
      points[i][1] = y;
   }

   /* front face */
   glNormal3f(0, 0, 1);
   glBegin(GL_POLYGON);
   for (i = 0; i < 36; i++) {
      glVertex3f(points[i][0], points[i][1], z1);
   }
   glEnd();

   /* back face */
   glNormal3f(0, 0, -1);
   glBegin(GL_POLYGON);
   for (i = 0; i < 36; i++) {
      glVertex3f(points[35-i][0], points[35-i][1], z0);
   }
   glEnd();

   /* edge */
   glBegin(GL_QUAD_STRIP);
   for (i = 0; i <= 36; i++) {
      const int j = i % 36;
      glNormal3f(normals[j][0], normals[j][1], 0);
      glVertex3f(points[j][0], points[j][1], z1);
      glVertex3f(points[j][0], points[j][1], z0);
   }
   glEnd();
}


/**
 * Draw a crankshaft.  Shaft lies along +Z axis, starting at zero.
 */
static void
DrawCrankshaft(const Engine *eng)
{
   const int slices = 20, stacks = 2;
   const int n = eng->Cranks * 4 + 1;
   const float phiStep = 360 / eng->Cranks;
   float phi = -90.0;
   int i;
   float z = 0.0;

   for (i = 0; i < n; i++) {
      glPushMatrix();
      glTranslatef(0, 0, z);
      if (i & 1) {
         /* draw a crank plate */
         glRotatef(phi, 0, 0, 1);
         glTranslatef(0, 0, 0.5 * eng->CrankPlateThickness);
         DrawConnector(eng->Throw, eng->CrankPlateThickness,
                       eng->CrankJournalRadius, eng->CrankPinRadius);
         z += 0.2;
         if (i % 4 == 3)
            phi += phiStep;
      }
      else if (i % 4 == 0) {
         /* draw crank journal segment */
         gluCylinder(Q, eng->CrankJournalRadius, eng->CrankJournalRadius,
                     eng->CrankJournalLength, slices, stacks);
         z += eng->CrankJournalLength;
      }
      else if (i % 4 == 2) {
         /* draw crank pin segment */
         glRotatef(phi, 0, 0, 1);
         glTranslatef(0, eng->Throw, 0);
         gluCylinder(Q, eng->CrankPinRadius, eng->CrankPinRadius,
                     eng->CrankJournalLength, slices, stacks);
         z += eng->CrankJournalLength;
      }
      glPopMatrix();
   }
}


/**
 * Draw crankshaft at a particular rotation.
 * \param crankAngle  current crankshaft rotation, in radians
 */
static void
DrawPositionedCrankshaft(const Engine *eng, float crankAngle)
{
   glPushMatrix();
      glRotatef(crankAngle, 0, 0, 1);
      if (eng->CrankList)
         glCallList(eng->CrankList);
      else
         DrawCrankshaft(eng);
   glPopMatrix();
}


/**
 * Draw a connecting rod at particular position.
 * \param eng  description of connecting rod to draw
 * \param crankAngle  current crankshaft rotation, in radians
 */
static void
DrawPositionedConnectingRod(const Engine *eng, float crankAngle)
{
   float x0, y0, x1, y1;
   float d, phi;

   ComputeConnectingRodPosition(eng->Throw, crankAngle,
                                eng->ConnectingRodLength,
                                &x0, &y0, &x1, &y1);
   d = sqrt(eng->ConnectingRodLength * eng->ConnectingRodLength - x0 * x0);
   phi = atan(x0 / d) * 180.0 / M_PI;

   glPushMatrix();
      glTranslatef(x0, y0, 0);
      glRotatef(phi, 0, 0, 1);
      if (eng->ConnRodList)
         glCallList(eng->ConnRodList);
      else
         DrawConnector(eng->ConnectingRodLength, eng->ConnectingRodThickness,
                       eng->CrankPinRadius, eng->WristPinRadius);
   glPopMatrix();
}


/**
 * Draw a square with a hole in middle.
 */
static void
SquareWithHole(float squareSize, float holeRadius)
{
   int i;
   glBegin(GL_QUAD_STRIP);
   glNormal3f(0, 0, 1);
   for (i = 0; i <= 360; i += 5) {
      const float x1 = holeRadius * cos(DEG_TO_RAD(i));
      const float y1 = holeRadius * sin(DEG_TO_RAD(i));
      float x2 = 0.0F, y2 = 0.0F;
      if (i > 315 || i <= 45) {
         x2 = squareSize;
         y2 = squareSize * tan(DEG_TO_RAD(i));
      }
      else if (i > 45 && i <= 135) {
         x2 = -squareSize * tan(DEG_TO_RAD(i - 90));
         y2 = squareSize;
      }
      else if (i > 135 && i <= 225) {
         x2 = -squareSize;
         y2 = -squareSize * tan(DEG_TO_RAD(i-180));
      }
      else if (i > 225 && i <= 315) {
         x2 = squareSize * tan(DEG_TO_RAD(i - 270));
         y2 = -squareSize;
      }
      glVertex2f(x1, y1); /* inner circle */
      glVertex2f(x2, y2); /* outer square */
   }
   glEnd();
}


/**
 * Draw block with hole through middle.
 * Hole is centered on Z axis.
 * Bottom of block is at z=0, top of block is at z = blockHeight.
 * index is in [0, count - 1] to determine which block faces are drawn.
 */
static void
DrawBlockWithHole(float blockSize, float blockHeight, float holeRadius,
                  int index, int count)
{
   const int slices = 30, stacks = 4;
   const float x = blockSize;
   const float y = blockSize;
   const float z0 = 0;
   const float z1 = blockHeight;

   assert(index < count);
   assert(Q);
   gluQuadricOrientation(Q, GLU_INSIDE);

   glBegin(GL_QUADS);
   /* +X face */
   glNormal3f(1, 0, 0);
   glVertex3f( x, -y, z0);
   glVertex3f( x, y, z0);
   glVertex3f( x, y, z1);
   glVertex3f( x, -y, z1);
   /* -X face */
   glNormal3f(-1, 0, 0);
   glVertex3f(-x, -y, z1);
   glVertex3f(-x, y, z1);
   glVertex3f(-x, y, z0);
   glVertex3f(-x, -y, z0);
   if (index == 0) {
      /* +Y face */
      glNormal3f(0, 1, 0);
      glVertex3f(-x, y, z1);
      glVertex3f( x, y, z1);
      glVertex3f( x, y, z0);
      glVertex3f(-x, y, z0);
   }
   if (index == count - 1) {
      /* -Y face */
      glNormal3f(0, -1, 0);
      glVertex3f(-x, -y, z0);
      glVertex3f( x, -y, z0);
      glVertex3f( x, -y, z1);
      glVertex3f(-x, -y, z1);
   }
   glEnd();

   /* cylinder / hole */
   gluCylinder(Q, holeRadius, holeRadius, blockHeight, slices, stacks);

   /* face at z0 */
   glPushMatrix();
   glRotatef(180, 1, 0, 0);
   SquareWithHole(blockSize, holeRadius);
   glPopMatrix();

   /* face at z1 */
   glTranslatef(0, 0, z1);
   SquareWithHole(blockSize, holeRadius);

   gluQuadricOrientation(Q, GLU_OUTSIDE);
}


/**
 * Draw the engine block.
 */
static void
DrawEngineBlock(const Engine *eng)
{
   const float blockHeight = eng->Throw + 1.5 * eng->PistonHeight;
   const float cylRadius = 1.01 * eng->PistonRadius;
   const float blockSize = 0.5 * PistonSpacing(eng);
   const int pistonsPerCrank = eng->Pistons / eng->Cranks;
   int i;

   for (i = 0; i < eng->Pistons; i++) {
      const float z = PistonShaftPosition(eng, i);
      const int crank = i / pistonsPerCrank;
      int k;

      glPushMatrix();
         glTranslatef(0, 0, z);

         /* additional rotation for kth piston per crank */
         k = i % pistonsPerCrank;
         glRotatef(k * -eng->V_Angle, 0, 0, 1);

         /* the block */
         glRotatef(-90, 1, 0, 0);
         glTranslatef(0, 0, eng->Throw * 2);
         DrawBlockWithHole(blockSize, blockHeight, cylRadius,
                           crank, eng->Cranks);
      glPopMatrix();
   }
}


/**
 * Generate display lists for engine parts.
 */
static void
GenerateDisplayLists(Engine *eng)
{
   eng->CrankList = glGenLists(1);
   glNewList(eng->CrankList, GL_COMPILE);
   DrawCrankshaft(eng);
   glEndList();

   eng->ConnRodList = glGenLists(1);
   glNewList(eng->ConnRodList, GL_COMPILE);
   DrawConnector(eng->ConnectingRodLength, eng->ConnectingRodThickness,
                 eng->CrankPinRadius, eng->WristPinRadius);
   glEndList();

   eng->PistonList = glGenLists(1);
   glNewList(eng->PistonList, GL_COMPILE);
   DrawPiston(eng);
   glEndList();

   eng->BlockList = glGenLists(1);
   glNewList(eng->BlockList, GL_COMPILE);
   DrawEngineBlock(eng);
   glEndList();
}


/**
 * Free engine display lists (render with immediate mode).
 */
static void
FreeDisplayLists(Engine *eng)
{
   glDeleteLists(eng->CrankList, 1);
   eng->CrankList = 0;
   glDeleteLists(eng->ConnRodList, 1);
   eng->ConnRodList = 0;
   glDeleteLists(eng->PistonList, 1);
   eng->PistonList = 0;
   glDeleteLists(eng->BlockList, 1);
   eng->BlockList = 0;
}


/**
 * Draw complete engine.
 * \param eng  description of engine to draw
 * \param crankAngle  current crankshaft angle, in radians
 */
static void
DrawEngine(const Engine *eng, float crankAngle)
{
   const float crankDelta = 360.0 / eng->Cranks;
   const float crankLen = CrankshaftLength(eng);
   const int pistonsPerCrank = eng->Pistons / eng->Cranks;
   int i;

   glPushMatrix();
   glRotatef(eng->V_Angle * 0.5, 0, 0, 1);
   glTranslatef(0, 0, -0.5 * crankLen);

   /* crankshaft */
   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, CrankshaftColor);
   glColor4fv(CrankshaftColor);
   DrawPositionedCrankshaft(eng, crankAngle);

   for (i = 0; i < eng->Pistons; i++) {
      const float z = PistonShaftPosition(eng, i);
      const int crank = i / pistonsPerCrank;
      float rot = crankAngle + crank * crankDelta;
      int k;

      glPushMatrix();
         glTranslatef(0, 0, z);

         /* additional rotation for kth piston per crank */
         k = i % pistonsPerCrank;
         glRotatef(k * -eng->V_Angle, 0, 0, 1);
         rot += k * eng->V_Angle;

         /* piston */
         glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, PistonColor);
         glColor4fv(PistonColor);
         DrawPositionedPiston(eng, rot);

         /* connecting rod */
         glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ConnRodColor);
         glColor4fv(ConnRodColor);
         DrawPositionedConnectingRod(eng, rot);
      glPopMatrix();
   }

   if (Render.ShowBlock) {
      const GLboolean blend = glIsEnabled(GL_BLEND);

      glDepthMask(GL_FALSE);
      if (!blend) {
         glEnable(GL_BLEND);
      }
      glEnable(GL_CULL_FACE);

      glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, BlockColor);
      glColor4fv(BlockColor);
      if (eng->CrankList)
         glCallList(eng->BlockList);
      else
         DrawEngineBlock(eng);

      glDisable(GL_CULL_FACE);
      glDepthMask(GL_TRUE);
      if (!blend) {
         glDisable(GL_BLEND);
      }
   }

   glPopMatrix();
}


static void
DrawBox(void)
{
   const float xmin = -3.0, xmax = 3.0;
   const float ymin = -1.0, ymax = 3.0;
   const float zmin = -4.0, zmax = 4.0;
   const float step = 0.5;
   const float d = 0.01;
   float x, y, z;
   GLboolean lit = glIsEnabled(GL_LIGHTING);
   GLboolean tex = glIsEnabled(GL_TEXTURE_2D);

   glDisable(GL_LIGHTING);
   glDisable(GL_TEXTURE_2D);

   glColor3f(1, 1, 1);

   /* Z min */
   glBegin(GL_LINES);
   for (x = xmin; x <= xmax; x += step) {
      glVertex3f(x, ymin, zmin);
      glVertex3f(x, ymax, zmin);
   }
   glEnd();
   glBegin(GL_LINES);
   for (y = ymin; y <= ymax; y += step) {
      glVertex3f(xmin, y, zmin);
      glVertex3f(xmax, y, zmin);
   }
   glEnd();

   /* Y min */
   glBegin(GL_LINES);
   for (x = xmin; x <= xmax; x += step) {
      glVertex3f(x, ymin, zmin);
      glVertex3f(x, ymin, zmax);
   }
   glEnd();
   glBegin(GL_LINES);
   for (z = zmin; z <= zmax; z += step) {
      glVertex3f(xmin, ymin, z);
      glVertex3f(xmax, ymin, z);
   }
   glEnd();

   /* X min */
   glBegin(GL_LINES);
   for (y = ymin; y <= ymax; y += step) {
      glVertex3f(xmin, y, zmin);
      glVertex3f(xmin, y, zmax);
   }
   glEnd();
   glBegin(GL_LINES);
   for (z = zmin; z <= zmax; z += step) {
      glVertex3f(xmin, ymin, z);
      glVertex3f(xmin, ymax, z);
   }
   glEnd();

   glColor3f(0.4, 0.4, 0.6);
   glBegin(GL_QUADS);
   /* xmin */
   glVertex3f(xmin-d, ymin, zmin);
   glVertex3f(xmin-d, ymax, zmin);
   glVertex3f(xmin-d, ymax, zmax);
   glVertex3f(xmin-d, ymin, zmax);
   /* ymin */
   glVertex3f(xmin, ymin-d, zmin);
   glVertex3f(xmax, ymin-d, zmin);
   glVertex3f(xmax, ymin-d, zmax);
   glVertex3f(xmin, ymin-d, zmax);
   /* zmin */
   glVertex3f(xmin, ymin, zmin-d);
   glVertex3f(xmax, ymin, zmin-d);
   glVertex3f(xmax, ymax, zmin-d);
   glVertex3f(xmin, ymax, zmin-d);
   glEnd();

   if (lit)
      glEnable(GL_LIGHTING);
   if (tex)
      glEnable(GL_TEXTURE_2D);
}


static void
PrintString(const char *s)
{
   while (*s) {
      glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
      s++;
   }
}


static int
ComputeFPS(void)
{
   static double t0 = -1.0;
   static int frames = 0;
   double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
   static int fps = 0;

   frames++;

   if (t0 < 0.0) {
      t0 = t;
      fps = 0;
   }
   else if (t - t0 >= 1.0) {
      fps = (int) (frames / (t - t0) + 0.5);
      t0 = t;
      frames = 0;
   }

   return fps;
}


static void
Draw(void)
{
   int fps;
   GLfloat rot[4][4];

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glPushMatrix();

      glTranslatef(0.0, 0.0, -View.Distance);
      build_rotmatrix(rot, View.CurQuat);
      glMultMatrixf(&rot[0][0]);

      glPushMatrix();
         glTranslatef(0, -0.75, 0);
         if (Render.DrawBox)
            DrawBox();
         DrawEngine(Engines + CurEngine, Theta);
      glPopMatrix();

   glPopMatrix();

   fps = ComputeFPS();
   if (Render.ShowInfo) {
      GLboolean lit = glIsEnabled(GL_LIGHTING);
      GLboolean tex = glIsEnabled(GL_TEXTURE_2D);
      char s[100];
      sprintf(s, "%s  %d FPS  %s", Engines[CurEngine].Name, fps,
              Render.UseLists ? "Display Lists" : "Immediate mode");
      glDisable(GL_LIGHTING);
      glDisable(GL_TEXTURE_2D);
      glColor3f(1, 1 , 1);
      glWindowPos2iARB(10, 10);
      PrintString(s);
      if (lit)
	 glEnable(GL_LIGHTING);
      if (tex)
	 glEnable(GL_TEXTURE_2D);
   }

   /* also print out a periodic fps to stdout.  useful for trying to
    * figure out the performance impact of rendering the string above
    * with glBitmap.
    */
   {
      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 %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps);
         fflush(stdout);
         T0 = t;
         Frames = 0;
      }
   }


   glutSwapBuffers();
}


/**
 * Handle window resize.
 */
static void
Reshape(int width, int height)
{
   float ar = (float) width / height;
   float s = 0.5;
   glViewport(0, 0, width, height);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glFrustum(-ar * s, ar * s, -s, s, 2.0, 50.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   WinWidth = width;
   WinHeight = height;
}


/**
 * Handle mouse button.
 */
static void
Mouse(int button, int state, int x, int y)
{
   if (button == GLUT_LEFT_BUTTON) {
      if (state == GLUT_DOWN) {
         View.StartX = x;
         View.StartY = y;
         View.Rotating = GL_TRUE;
      }
      else if (state == GLUT_UP) {
         View.Rotating = GL_FALSE;
      }
   }
   else if (button == GLUT_MIDDLE_BUTTON) {
      if (state == GLUT_DOWN) {
         View.StartX = x;
         View.StartY = y;
         View.StartDistance = View.Distance;
         View.Translating = GL_TRUE;
      }
      else if (state == GLUT_UP) {
         View.Translating = GL_FALSE;
      }
   }
}


/**
 * Handle mouse motion
 */
static void
Motion(int x, int y)
{
   int i;
   if (View.Rotating) {
      float x0 = (2.0 * View.StartX - WinWidth) / WinWidth;
      float y0 = (WinHeight - 2.0 * View.StartY) / WinHeight;
      float x1 = (2.0 * x - WinWidth) / WinWidth;
      float y1 = (WinHeight - 2.0 * y) / WinHeight;
      float q[4];

      trackball(q, x0, y0, x1, y1);
      View.StartX = x;
      View.StartY = y;
      for (i = 0; i < 1; i++)
         add_quats(q, View.CurQuat, View.CurQuat);

      glutPostRedisplay();
   }
   else if (View.Translating) {
      float dz = 0.01 * (y - View.StartY);
      View.Distance = View.StartDistance + dz;
      glutPostRedisplay();
   }
}


/**
 ** Menu Callbacks
 **/

static void
OptAnimation(void)
{
   Render.Anim = !Render.Anim;
   if (Render.Anim)
      glutIdleFunc(Idle);
   else
      glutIdleFunc(NULL);
}

static void
OptChangeEngine(void)
{
   CurEngine = (CurEngine + 1) % NUM_ENGINES;
}

static void
OptRenderMode(void)
{
   Render.Mode++;
   if (Render.Mode > TEXTURED)
      Render.Mode = 0;
   SetRenderState(Render.Mode);
}

static void
OptDisplayLists(void)
{
   int i;
   Render.UseLists = !Render.UseLists;
   if (Render.UseLists) {
      for (i = 0; i < NUM_ENGINES; i++) {
         GenerateDisplayLists(Engines + i);
      }
   }
   else {
      for (i = 0; i < NUM_ENGINES; i++) {
         FreeDisplayLists(Engines + i);
      }
   }
}

static void
OptShowBlock(void)
{
   Render.ShowBlock = !Render.ShowBlock;
}

static void
OptShowInfo(void)
{
   Render.ShowInfo = !Render.ShowInfo;
}

static void
OptShowBox(void)
{
   Render.DrawBox = !Render.DrawBox;
}

static void
OptRotate(void)
{
   Theta += 5.0;
}

static void
OptExit(void)
{
   exit(0);
}


/**
 * Define menu entries (w/ keyboard shortcuts)
 */

typedef struct
{
   const char *Text;
   const char Key;
   void (*Function)(void);
} MenuInfo;

static const MenuInfo MenuItems[] = {
   { "Animation", 'a', OptAnimation },
   { "Change Engine", 'e', OptChangeEngine },
   { "Rendering Style", 'm', OptRenderMode },
   { "Display Lists", 'd', OptDisplayLists },
   { "Show Block", 'b', OptShowBlock },
   { "Show Info", 'i', OptShowInfo },
   { "Show Box", 'x', OptShowBox },
   { "Exit", 27, OptExit },
   { NULL, 'r', OptRotate },
   { NULL, 0, NULL }
};


/**
 * Handle menu selection.
 */
static void
MenuHandler(int entry)
{
   MenuItems[entry].Function();
   glutPostRedisplay();
}


/**
 * Make pop-up menu.
 */
static void
MakeMenu(void)
{
   int i;
   glutCreateMenu(MenuHandler);
   for (i = 0; MenuItems[i].Text; i++) {
      glutAddMenuEntry(MenuItems[i].Text, i);
   }
   glutAttachMenu(GLUT_RIGHT_BUTTON);
}


/**
 * Handle keyboard event.
 */
static void
Key(unsigned char key, int x, int y)
{
   int i;
   (void) x; (void) y;
   for (i = 0; MenuItems[i].Key; i++) {
      if (MenuItems[i].Key == key) {
         MenuItems[i].Function();
         glutPostRedisplay();
         break;
      }
   }
}


static
void LoadTexture(void)
{
   GLboolean convolve = GL_FALSE;

   glGenTextures(1, &TextureObj);
   glBindTexture(GL_TEXTURE_2D, TextureObj);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);

   if (convolve) {
#define FILTER_SIZE 7
      /* use convolution to blur the texture to simulate a dull finish
       * on the object.
       */
      GLubyte *img;
      GLenum format;
      GLint w, h;
      GLfloat filter[FILTER_SIZE][FILTER_SIZE][4];

      for (h = 0; h < FILTER_SIZE; h++) {
         for (w = 0; w < FILTER_SIZE; w++) {
            const GLfloat k = 1.0 / (FILTER_SIZE * FILTER_SIZE);
            filter[h][w][0] = k;
            filter[h][w][1] = k;
            filter[h][w][2] = k;
            filter[h][w][3] = k;
         }
      }

      glEnable(GL_CONVOLUTION_2D);
      glConvolutionParameteri(GL_CONVOLUTION_2D,
                              GL_CONVOLUTION_BORDER_MODE, GL_CONSTANT_BORDER);
      glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_RGBA,
                            FILTER_SIZE, FILTER_SIZE,
                            GL_RGBA, GL_FLOAT, filter);

      img = LoadRGBImage(TEXTURE_FILE, &w, &h, &format);
      if (!img) {
         printf("Error: couldn't load texture image file %s\n", TEXTURE_FILE);
         exit(1);
      }

      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
                   format, GL_UNSIGNED_BYTE, img);
      free(img);
   }
   else {
      if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
         printf("Error: couldn't load texture image file %s\n", TEXTURE_FILE);
         exit(1);
      }
   }
}


static void
Init(void)
{
   const GLfloat lightColor[4] = { 0.7, 0.7, 0.7, 1.0 };
   const GLfloat specular[4] = { 0.8, 0.8, 0.8, 1.0 };
   const GLfloat backColor[4] = { 1, 1, 0, 0 };

   Q = gluNewQuadric();
   gluQuadricNormals(Q, GLU_SMOOTH);

   LoadTexture();

   glClearColor(0.3, 0.3, 0.3, 0.0);
   glEnable(GL_DEPTH_TEST);
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
   glMaterialf(GL_FRONT, GL_SHININESS, 40);
   glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
   glEnable(GL_NORMALIZE);

   glMaterialfv(GL_BACK, GL_DIFFUSE, backColor);
#if 0
   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
#endif
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

   InitViewInfo(&View);
   InitRenderInfo(&Render);
}


int
main(int argc, char *argv[])
{
   glutInitWindowSize(WinWidth, WinHeight);
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
   glutCreateWindow("OpenGL Engine Demo");
   glewInit();
   glutReshapeFunc(Reshape);
   glutMouseFunc(Mouse);
   glutMotionFunc(Motion);
   glutKeyboardFunc(Key);
   glutDisplayFunc(Draw);
   MakeMenu();
   Init();
   if (Render.Anim)
      glutIdleFunc(Idle);
   glutMainLoop();
   return 0;
}
