/*
 *  Raster Graphics:  Writing a Bitmap
 *  and erasing it with consecutive xor.
 */

#include <GL/gl.h>
#include <GL/glut.h>

#include <cstdlib>
#include <iostream>
using namespace std;


GLubyte wb[2] = {0x00,0xff};
GLubyte check[512]; // 512 * 8 = 4096 bits
// 64 * 64 is 1096 bits.

bool mousepressed = false;
int mousex;
int mousey;
int reshapeheight;


inline void glerrordisplay()
{
  GLenum errval = glGetError();
  if (errval != GL_NO_ERROR)
     cout << gluErrorString( errval ) << endl;
}


void mouse(int btn, int state, int x, int y)
{
  if ((btn==GLUT_LEFT_BUTTON) && (state==GLUT_DOWN))
  {
    mousepressed=true;
    mousex = x;
    mousey = reshapeheight - y;

    glutPostRedisplay();
  }
}


void keyboard
(
  unsigned char key,
  int x,
  int y
)
{
  switch (key)
  {
    case 27: exit(0);
  }
}

void reshape(int w, int h)
{
  glViewport(0,0,w,h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0,w,0,h,-1.0,1.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

glerrordisplay();

  reshapeheight = h;
}


void display()
{
  glClear(GL_COLOR_BUFFER_BIT);

  //glRasterPos2f(0.0,0.0);

  glBitmap
  (
    64,64,
    0.0,0.0,
    0.0,0.0,
    check
  );


  if (mousepressed)
  {
    mousepressed=false;

    glBitmap
    (
      64,64,
      0.0,0.0,
      0.0,0.0,
      check
    );

    glRasterPos2i(mousex,mousey);

    glBitmap
    (
      64,64,
      0.0,0.0,
      0.0,0.0,
      check
    );

  }

  glFlush();
}


int main(int argc, char** argv)
{
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
  glutInitWindowSize(200,150);
  glutCreateWindow("");
  glutDisplayFunc(display);
  glutKeyboardFunc(keyboard);
  glutMouseFunc(mouse);
  glutReshapeFunc(reshape);

  // Generate check pattern.
  for (unsigned int i=0,k; i<64; ++i)
  {
    for (k=0; k<64; ++k)
      check[i*8+k] = wb[(i/8+k)%2];
  }

  glEnable(GL_COLOR_LOGIC_OP);
  glLogicOp(GL_XOR);

  // Problem that color not initially applied.
  glColor3f(1.0,0.0,0.0);


  glutMainLoop();
  return 0;
}




