/***
 *  PROJECT     :  Generation of Anatomical Models for Surgical Simulators (GAMSS)
 *  AUTHOR      :  Raimundo Sierra
 *  CONTACT     :  http://www.rsierra.com/?main=contact
 *  CREATED     :  21.03.2002
 *  CHANGED     :  
 *  DESCRIPTION :  Read arbitrary image files and display them with OpenGl in GLUT
 *
 *                 gamma correction might be needed if colors look different
 *                 then in other applications, try a value of 0.5
 *
 *  TODO        :    
 */

#include <glut.h>
#include <iostream.h>
#include "readImages.h"

void drawPixels(const float *pixels, const int width, const int height)
{
  glNewList(1, GL_COMPILE_AND_EXECUTE);
    glPushMatrix();
    glLoadIdentity();
    glRasterPos3f(0.0, 0.0, 0.0);
    glDrawPixels(width, height, GL_RGB,   GL_FLOAT, pixels);
    glPopMatrix();
  glEndList();
}

void displayFunction(void){
  glClear(GL_COLOR_BUFFER_BIT);

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glCallList(1);
  glPopMatrix();
  
  glutSwapBuffers();

  glGetError();
}

void reshapeFunction(int w, int h){
  /* this function includes the viewport and projection section, since both projection 
     (the width to height  aspect ratio of the projection viewing volume) and applying 
     the viewport relate directly to the screen, and specifically to the size or aspect 
     ratio of the window on the screen. 

     Common sequence:
     glViewPort         
     glMatrixMode(Projection)
     glLoadIdentity
     glFrustum || gluPerspective || glOrtho
     glMatrixMode(Modelview)                     to set back the matrix mode to Modelview

     glViewPort       indicates the shape of the available 
                      screen area into which the scene is mapped
	(x0, y0,      the lower left corner of the viewport
	 w, h)        are the size of the viewport rectangle


     Additionaly the aspect ratio is modified so that the whole scene fits into the new window
  */
  
  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  
  gluOrtho2D(0.0, (GLfloat)w, 0.0, (GLfloat)h);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

void keyboardFunction(unsigned char key, int x, int y){

  switch(key){
  case 'q':                                      // quit window
  case 'Q':
  case 'e':
  case 'E':
  case 27:
    exit(0);
    break;
  }
}


int main(int argc, char **argv){
  cout <<"\nStart testing of reading different image formats\n";

  int rows    = 0;
  int columns = 0;
  char * file = new char[256];
  float *image= NULL;
  float gamma = 1.0;
  
  cout <<"Enter file: ";
  cin >> file;
  cout <<"Enter gamma correction (try 1.0 or 0.5): ";
  cin >> gamma;
  
  image = readColorImage(file, rows, columns, image, gamma);
  
  /***** set up glut ******/
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  glutInitWindowSize(columns, rows);
  glutInitWindowPosition(0, 0);
  glutCreateWindow("Display Images");
  
  /***** initialize OpenGL *****/
  glClearColor( 0.0, 0.0, 0.0, 0.0);

  /***** define glut functions *****/
  glutDisplayFunc(displayFunction);
  glutReshapeFunc(reshapeFunction);
  glutKeyboardFunc(keyboardFunction);
  
  /***** create displaylist with image *****/
  drawPixels(image, columns, rows);

  glutMainLoop();
  
  delete[] image;
  delete[] file;

  
  cout <<"\nEnd of test\n\n";
}
