/* 
Jeffrey Grafton <jgrafton at tjhsst dot edu>
10/29/2002

This program is released under the GNU General Public License.
A copy of this license is available online at
http://www.gnu.org/copyleft/gpl.html.
*/

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

#define WINDOW_WIDTH 600
#define WINDOW_HEIGHT 600

GLfloat light_position[] = {0.0, 0.0, 0.0, 1.0};
GLfloat white_light[] = {0.1, 0.1, 0.0, 1.0};
GLfloat spin_val = 0.0;
GLfloat mat_specular[] = {0.5, 0.5, 0.5, 1.0};
GLfloat mat_shininess[]= {50.0};

void init(void)
{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_COLOR_MATERIAL);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	
	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
	glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
}

void display(void)
{
	GLfloat emission[] = {0.5, 0.5, 0.0, 1.0};
	GLfloat black[] = {0.0, 0.0, 0.0, 1.0};
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glPushMatrix();
		glRotated(2.3 * spin_val, 0.0, 0.0, 1.0);
		glTranslated(-1.0, 2.0, 0.0);
		glColor3d(1.0, 1.0, 0.0);
		glMaterialfv(GL_FRONT, GL_EMISSION, emission);
		glutSolidSphere(0.1, 50, 50);
		glLightfv(GL_LIGHT0, GL_POSITION, light_position);
		glLightfv(GL_LIGHT0, GL_AMBIENT, white_light);
	/*	glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
		glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
	*/
	glPopMatrix();

	glPushMatrix();
		glRotated(spin_val, 1.0, 1.0, 0.0);
		glTranslated(1.0, 0.0, 1.0);
		glColor3d(1.0, 0.0, 0.0);
		glMaterialfv(GL_FRONT, GL_EMISSION, black);
		glutSolidCube(1.1);
		glTranslated(1.4 * sin(spin_val / 10.0) - 2.0, 0, -2.0 + 4.0 * cos(spin_val / 100.0));
		glColor3d(1.0, 0.0, 1.0);
		glPushMatrix();
			glRotated(spin_val * 50.0, 3.8, 0.4, 9.4);
			glutSolidCube(0.3);
		glPopMatrix();
	glPopMatrix();
	
	glPushMatrix();
		glRotated(-0.7 * spin_val, 0.0, 1.0, 0.0);
		glColor3d(0.0, 0.0, 1.0);
		glutSolidTorus(0.3, 0.5, 20, 20);
	glPopMatrix();
	
	glPushMatrix();
		glRotated(0.1 * spin_val, 1.0, 0.1, 0.2);
		glColor3d(0.0, 1.0, 0.0);
		glutSolidSphere(0.5, 50, 50);
	glPopMatrix();
	
	glRotated(0.3, 0.2, -0.7, 0.5);
	
	glutSwapBuffers();
}

void reshape(int w, int h)
{
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0.0, 1.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}

void spin(void)
{
	spin_val += 1.0;
	glutPostRedisplay();
}

void keyboard (unsigned char key, int x, int y)
{
	if(key == 'o')
		glRotated(5.0, 0.0, 1.0, 0.0);
	if(key == 'p')
		glRotated(-5.0, 0.0, 1.0, 0.0);
 	glutPostRedisplay();
}

int
main (int argc, char **argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
	glutCreateWindow(argv[0]);
	init();
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutIdleFunc(spin);
	glutKeyboardFunc(keyboard);
	glutMainLoop();
	return 0;
}
