/**************************************************************
 *  drawmouse.cpp
 *  This program demonstrates the drawing of polylines
 *  entered with the mouse.
 *
 *  Use left button to input vertices of polylines, use
 *  middle button to clear rectangles, and use right button
 *  to exit.
 *
 *  See what would happen if you hold down the 'p' key
 *  and move the mouse around
 **************************************************************/
#include << X11/Xlib.h>
#include << fstream.h>
#include << math.h>
#include << GLUT/glut.h>
#include << OpenGL/gl.h>
#include << stdlib.h>
#include << stdio.h>

#define NUM  20
const int screenWidth = 640;
const int screenHeight = 480;        
class GLintPoint {
  public:
  GLint x, y;
};
int last = -1;            // last index used so far 
GLintPoint List[NUM];

void drawDot(GLint x, GLint y)
{ // draw dot at integer point (x,y)
  glBegin(GL_POINTS);
  glVertex2i(x, y);
  glEnd();
}

void myInit(void) 
{
   glClearColor (1.0, 1.0, 1.0, 0.0);   // set black background color
   glColor3f (0.0f, 0.0f, 0.0f);       // set the drawing color
   glPointSize (2.0);                  // set dot size 2 x 2
   glMatrixMode (GL_PROJECTION);       // set "camera shape"
   glLoadIdentity ();                    // clear the matrix
           // viewing transformation 
   gluOrtho2D (0.0, (GLdouble)screenWidth, 0.0, (GLdouble)screenHeight);
           // set the Worlk Window
}

void myDisplay(void)
{
  glClear(GL_COLOR_BUFFER_BIT);     // clear the screen
}

void myKeyboard(unsigned char theKey, int mouseX, int mouseY)
{
  GLint x = mouseX; 
  GLint y = screenHeight - mouseY; // flip the y value as always
  switch(theKey)
  {
    case 'p':
        drawDot(x, y);            // draw a dot at the mouse position
        break;
    case GLUT_KEY_LEFT:           // left arrow key
        List[++last].x = x;       // add a point, but does no drawing
        List[  last].y = y;
        break;
    case 'E':
        exit(-1);               // terminate the program         
    default:
        break;                  // do nothing
   }
}

void myMouse(int button, int state, int x, int y)
{
  switch (button) {
     case GLUT_LEFT_BUTTON:
        if (state == GLUT_DOWN && last < NUM -1)  
        {
            List[++last].x = x;            // add new point to list
            List[  last].y = screenHeight - y;  // window height is 480
            glClear(GL_COLOR_BUFFER_BIT);       // clear the screen 
            glBegin(GL_LINE_STRIP);             // redraw the polyline
            for(int i = 0; i <= last; i++)
                glVertex2i(List[i].x, List[i].y);
            glEnd();
            glFlush();
        }
        break;
     case GLUT_MIDDLE_BUTTON:
        if (state == GLUT_DOWN)
            last = -1;               // reset the list to empty
        break;
     case GLUT_RIGHT_BUTTON:
        if (state == GLUT_DOWN)
           exit (-1);
        break;
     default:
        break;
  }
}

int main(int argc, char** argv)
{

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