
#include <GLUT/glut.h> // Mac OS X implementation
//#include <GL/glut.h> // Classic Mac OS implementation
#include <stdlib.h>
#include <stdio.h>
#include <iostream.h>

// prototypes
void init();
void drawRects(GLenum);
void processHits(GLint, GLuint []);
void pickRects(int, int, int, int);
void display();
void reshape(int, int);

static int global_int = 0;

void init()
{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glEnable(GL_DEPTH_TEST);
	glShadeModel(GL_FLAT);
	glDepthRange(0.0, 1.0); /*default z mapping */
}


void drawRects(GLenum mode)
{
	if (mode == GL_SELECT)
		glLoadName(1);
	
	glBegin(GL_QUADS);
		glColor3f(1.0, 1.0, 0.0);
		glVertex3i(2, 0, 0);
		glVertex3i(2, 6, 0);
		glVertex3i(6, 6, 0);
		glVertex3i(6, 0, 0);
	glEnd();
	
	if (mode == GL_SELECT)
		glLoadName(2);
	
	glBegin(GL_QUADS);
		glColor3f(0.0, 1.0, 1.0);
		glVertex3i(3, 2, -1);
		glVertex3i(3, 8, -1);
		glVertex3i(8, 8, -1);
		glVertex3i(8, 2, -1);
	glEnd();
	
	if (mode == GL_SELECT)
		glLoadName(3);
	
	glBegin(GL_TRIANGLES);
		glColor3f(1.0, 0.0, 1.0);
		glVertex3i(0, 2, -2);
		glVertex3i(0, 7, -2);
		glVertex3i(7, 2, -2);
		//glVertex3i(5, 7, -2);
		//glVertex3i(5, 2, -2);
	glEnd();
}

void processHits(GLint hits, GLuint buffer[])
{
	unsigned int i, j;
	GLuint names, *ptr;
	
	printf("hits = %d\n", hits);
	ptr = (GLuint *)buffer;
	
	for(i = 0; i < hits; i++)
	{
		names = *ptr;
		printf( "number of names for hit = %d\n", names);
		ptr++;
		printf(" z1 is %g;", (float) *ptr/0x7fffffff);
		ptr++;
		printf(" z2 is %g\n", (float) *ptr/0x7fffffff);
		ptr++;
		printf("  the name is ");
		
		for (j = 0; j < names; j++)
		{
			printf("%d ", *ptr);
			ptr++;
		}
		printf("\n");
	}
}

#define BUFSIZE 512

void pickRects(int button, int state, int x, int y)
{
	GLuint selectBuf[BUFSIZE];
	GLint hits;
	GLint viewport[4];
	
	if(button != GLUT_LEFT_BUTTON || state != GLUT_DOWN)
		return;
	glGetIntegerv(GL_VIEWPORT, viewport);
	
	glSelectBuffer(BUFSIZE, selectBuf);
	(void) glRenderMode(GL_SELECT);
	
	glInitNames();
	glPushName(0);
	
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluPickMatrix((GLdouble)x, (GLdouble) (viewport[3] - y), 5.0, 5.0, viewport);
	glOrtho(0.0, 8.0, 0.0, 8.0, -0.5, 2.5);
	drawRects(GL_SELECT);
	glPopMatrix();
	glFlush();
	
	hits = glRenderMode(GL_RENDER);
	processHits(hits, selectBuf);
}

void display()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	drawRects(GL_RENDER);
	glFlush();
}

void reshape(int w, int h)
{
	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0, 8.0, 0.0, 8.0, -0.5, 2.5);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int main(int argc, char**argv)
{
	glutInit(&argc, argv);

	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(200, 200);
	glutInitWindowPosition(100, 100);
	glutCreateWindow(argv[0]);
	init();
	glutMouseFunc(pickRects);
	printf("%d ", global_int);
	global_int++;
	glutReshapeFunc(reshape);
	glutDisplayFunc(display);
	glutMainLoop();

	return 0;
}

