/**************************************************************
 *  square.c
 *  This program demonstrates the drawing of a sppinning
 *  square using double-buffering technique
 *
 *  Use left and middle buttons of the mouse to toggle the
 *  spinning on and off.
 *  Use the right botton to exit.
 **************************************************************/
#include << X11/Xlib.h>
#include << math.h>
// for CS Domain
//#include << GL/glut.h>
//#include << GL/gl.h>
// for CALab
#include << GLUT/glut.h>
#include << OpenGL/gl.h>
#include << stdlib.h>
#include << stdio.h>

static GLfloat spin = 0.0;       // degree of spinning

void myInit(void) 
{
   glClearColor (1.0, 1.0, 1.0, 0.0);   // set black background color
   glShadeModel (GL_FLAT);
}

void myDisplay(void)
{
  glClear(GL_COLOR_BUFFER_BIT);        // clear the screen
  glPushMatrix ();
  glRotatef (spin, 0.0, 0.0, 1.0);
  glColor3f (0.0, 0.0, 0.0);           // set the drawing color
  glRectf (-25.0, -25.0, 25.0, 25.0);
  glPopMatrix ();
  glutSwapBuffers ();
}

void spinDisplay(void)
{
  spin = spin + 2.0;
  if (spin > 360.0)
     spin = spin - 360.0;
  glutPostRedisplay();
}

void myReshape ( int w, int h)
{
  glViewport (0, 0, (GLsizei) w, (GLsizei) h);
  glMatrixMode (GL_PROJECTION);       // set "camera shape"
  glLoadIdentity ();                    // clear the matrix
           // viewing transformation 
  glOrtho (-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);
  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity ();
}

void myMouse(int button, int state, int x, int y)
{
  switch (button) {
     case GLUT_LEFT_BUTTON:
        if (state == GLUT_DOWN)
           glutIdleFunc(spinDisplay);
        break;
     case GLUT_MIDDLE_BUTTON:
        if (state == GLUT_DOWN)
           glutIdleFunc(NULL);
        break;
     case GLUT_RIGHT_BUTTON:
        if (state == GLUT_DOWN)
           exit (-1);
        break;
  }
} 
     
/*
 * Request double buffer display mode.
 * Register mouse input callback functions
 */
int main(int argc, char** argv)
{

   glutInit(&argc, argv);                            // initialize the toolkit
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);     // set display mode
//   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);     // set display mode
   glutInitWindowSize (250, 250);                    // set screen window size
   glutInitWindowPosition (100, 100);       // set window position on screen
   glutCreateWindow (argv[0]);              // open the screen window
   myInit ();
   glutDisplayFunc(myDisplay);              // register redraw function
   glutReshapeFunc(myReshape);              // register reshape function
   glutMouseFunc(myMouse);                  // register myMouse function
   glutMainLoop();                          // go into a perpetual loop
   return 0;
}