/* rubbergl.c   basic rubber band                    */
/* Draw rectangle. left mouse down=first point       */
/* Drag to second point. left mouse up=final point   */

#include <GL/glut.h>

static int winWidth = 500;
static int winHeight = 500;
static int tracking = 0; /* left button down, sense motion */
static int startX = 0;
static int startY = 0;
static int currentX = 0;
static int currentY = 0;

void rubberRect(int x0, int y0, int x1 , int y1)
{ /* can apply to all figures */
  /* draw a rubber rectangle, mouse down, tracks mouse */
  glLineStipple(1,0xF00F);
  glEnable(GL_LINE_STIPPLE);
  glLineWidth(1.0);
  glColor3f(0.0,0.0,0.0);
  glBegin(GL_LINE_LOOP); 
    glVertex2f(x0, y0);
    glVertex2f(x0, y1);
    glVertex2f(x1, y1);
    glVertex2f(x1, y0);
  glEnd();
  glDisable(GL_LINE_STIPPLE);
}

void mouseMotion(int x, int yn)
{
  int y; /* invert via winHeight */
  if(tracking)
  {
    y = winHeight-yn;
    currentX = x;
    currentY = y;
  } 
  glutPostRedisplay();
}

void startMotion(int x, int y)
{
  tracking = 1;
  startX = x;
  startY = y;
  currentX = x;
  currentY = y; /* start zero size, may choose to ignore later */
  glutPostRedisplay();
}

void stopMotion(int x, int y)
{
  tracking = 0; /* no more rubber_rect */

  /* save final figure data for 'display' to draw */
  currentX = x;
  currentY = y;
  glutPostRedisplay();
}

void mouseButton(int button, int state, int x, int yn)
{
  int y; /* inverted by winHeight */

  y=winHeight-yn;
  
  if(button==GLUT_LEFT_BUTTON)
  {
    if(state==GLUT_DOWN) startMotion(x, y);
    if(state==GLUT_UP)   stopMotion (x, y);
  }
}

void reshape(int w, int h)
{
  glViewport(0, 0, w, h);
  winWidth = w;
  winHeight = h;
  glutPostRedisplay();
}

void display(void)
{
  int i;
  
  glClear(GL_COLOR_BUFFER_BIT);
  if(tracking) rubberRect(startX, startY, currentX, currentY);

  /* draw figures per list */

  glFlush();  
}

int main(int argc, char *argv[])
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGB);
  glutInitWindowSize(winWidth, winHeight);
  glutInitWindowPosition(100,100); 
  glutCreateWindow(argv[0]);
  glutReshapeFunc(reshape);
  glutDisplayFunc(display);
  glutMouseFunc(mouseButton);
  glutMotionFunc(mouseMotion);
  gluOrtho2D(0.0, (GLfloat)winWidth, 0.0, (GLfloat)winHeight);
  glClearColor(1.0, 1.0, 1.0, 0.0);
  glutMainLoop();
  return 0;
}

