/* color_scale.c color scale */
#include <stdlib.h>
#include <GL/glut.h>

static GLfloat vertices[][3] = {{-1.0, 1.00, 0.0}, { 1.0, 1.00, 0.0},  /* 0,1 */
                                { 1.0, 0.85,-1.0}, {-1.0, 0.85, 0.0}}; /* 2,3 */
/* 12 colors hand coded */
GLfloat colors[][3] = {{1.0,0.0,0.0},{1.0,0.5,0.0},{1.0,0.8,0.0},
                       {1.0,1.0,0.0},{0.8,0.9,0.0},{0.5,0.9,0.0},
                       {0.0,1.0,0.0},{0.0,1.0,0.6},
                       {0.0,1.0,1.0},{0.0,0.8,1.0},{0.0,0.5,1.0},
                       {0.0,0.0,1.0}};
/* 12 hand coded values, could be computed */
GLfloat values[] = {2.5, 2.3, 2.0, 1.5, 1.1, 1.0, 0.95, 0.93, 0.92, 0.91, 0.90, 0.89};
static GLfloat cscale = 0.0;
static int ncolor = 12;
static GLfloat offset = 0.0;


/* fixed font text, does not move with main image, fonts may be
 * GLUT_BITMAP_TIMES_ROMAN_24 GLUT_BITMAP_TIMES_ROMAN_10
 * GLUT_BITMAP_HELVETICA_10   GLUT_BITMAP_HELVETICA_12
 * GLUT_BITMAP_HELVETICA_18
 */
static void printstring(float x, float y, void *font, char *string)
{
   int len, i;

   glRasterPos2f(x, y);
   len = (int) strlen(string);
   for (i = 0; i < len; i++)
      glutBitmapCharacter(font, string[i]);
} /* end printstring */


/* a,b,c,d are coordinates, e modifies color using cscale via mouse */
void polygon(int a, int b, int c , int d, int e)
{
  GLfloat acolor[3];
  int i;
  
  for(i=0; i<3; i++) /* loop through R, G, B  polygon drawn with  acolor */
  {
    acolor[i] = colors[e][i];
    if((e==4 || e==5)&&(i==0)) acolor[i] = acolor[i]+cscale;
    if((e==7 || e==8)&&(i==2)) acolor[i] = acolor[i]+cscale;
    if((e==1 || e==2 || e==10 || e==11)&&(i==1)) acolor[i] = acolor[i]+cscale;
  }
  
  /* draw a polygon via list of vertices */
  glBegin(GL_POLYGON);
  glColor3fv(acolor);
  glVertex3f(vertices[a][0], vertices[a][1]-offset, vertices[a][2]);
  glVertex3f(vertices[b][0], vertices[b][1]-offset, vertices[b][2]);
  glVertex3f(vertices[c][0], vertices[c][1]-offset, vertices[c][2]);
  glVertex3f(vertices[d][0], vertices[d][1]-offset, vertices[d][2]);
 glEnd();
}

void color_scale(void)
{
  int i;
  char cvalue[6]="     ";
  
  offset = 0.0;
  for(i=0; i<ncolor; i++)
  {
    polygon(0, 1, 2, 3, i);
    glColor3f(0.0, 0.0, 0.0);
    sprintf(cvalue, "%5.2f", values[i]);
    printstring(1.1, 0.9-offset, GLUT_BITMAP_HELVETICA_10, cvalue);
    offset = offset + 0.15;
  }
}

void display(void)
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();
  glColor3f(0.0, 0.0, 0.0);
  printstring(-0.9, 1.2 , GLUT_BITMAP_HELVETICA_18,
              "Use color to indicate values");

  color_scale();
  glFlush();
  glutSwapBuffers();
}

void mouse(int btn, int state, int x, int y)
{
  /* mouse callback, changes cscale */
  if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) cscale = cscale+0.1;
  if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) cscale = cscale-0.1;
  glutPostRedisplay();
}

void myReshape(int w, int h)
{
  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  if(w <= h)
      glOrtho(-1.5, 1.5, -1.5 * (GLfloat)h / (GLfloat)w,
              1.5 * (GLfloat)h / (GLfloat)w, -10.0, 10.0);
  else
      glOrtho(-1.5 * (GLfloat)w / (GLfloat)h,
              1.5 * (GLfloat)w / (GLfloat)h, -1.5, 1.5, -10.0, 10.0);
  glMatrixMode(GL_MODELVIEW);
  glClearColor(1.0, 1.0, 1.0, 1.0); 
}

int main(int argc, char *argv[])
{
  glutInit(&argc, argv);
  /* ready for 3D, yet not used here */
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(400, 400);
  glutCreateWindow(argv[0]);
  glutReshapeFunc(myReshape);
  glutDisplayFunc(display);
  glutMouseFunc(mouse);
  glEnable(GL_DEPTH_TEST);
  glutMainLoop();
  return 0;
}


