#include <cstdlib>

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

int Width = 500;
int Height = 500;
float density = 0.1;

void Display()
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45, (double)Width / Height, 3, 10);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glClearColor(0, 0, 0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	float fog_color[] = {0.5, 0.5, 0.5, 1};
	glFogi(GL_FOG_MODE, GL_EXP);
	glFogf(GL_FOG_DENSITY, density);
	glFogfv(GL_FOG_COLOR, fog_color);

	gluLookAt(4, 0, 0,
                  0, 0, 0,
                  0, 0, 1);

	GLfloat light0_diffuse[] = {0.4, 0.2, 0.7};
	GLfloat light0_direction[] = {1.0, 0.0, 1.0, 1.0};

	glEnable(GL_LIGHT0);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
	glLightfv(GL_LIGHT0, GL_POSITION, light0_direction);

	GLfloat ambient1[] = {0.2, 0.2, 0.2, 1.0};
	GLfloat diffuse1[] = {0.8, 0.8, 0.8, 1.0};
	GLfloat specular1[] = {0.6, 0.6, 0.6, 1.0};
	glMaterialfv(GL_FRONT, GL_AMBIENT, ambient1);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse1);
	glMaterialfv(GL_FRONT, GL_SPECULAR, specular1);
	glMaterialf(GL_FRONT, GL_SHININESS, 0.7 * 128);
	glPushMatrix();
		glTranslatef(0, 0.8, 0);
		glutSolidSphere(0.7, 200, 200);
	glPopMatrix();

	GLfloat ambient2[] = {0.2, 0.2, 0.2, 1.0};
	GLfloat diffuse2[] = {0.8, 0.8, 0.8, 1.0};
	GLfloat specular2[] = {0.0, 0.0, 0.0, 1.0};
	glMaterialfv(GL_FRONT, GL_AMBIENT, ambient2);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse2);
	glMaterialfv(GL_FRONT, GL_SPECULAR, specular2);
	glMaterialf(GL_FRONT, GL_SHININESS, 0);
	glPushMatrix();
		glTranslatef(0, -0.8, 0);
		glutSolidSphere(0.7, 200, 200);
	glPopMatrix();

	glBegin(GL_QUADS);
                        glVertex3f(-2, -10, 10);
                        glVertex3f(-2, -10, -10);
                        glVertex3f(-2, 10, -10);
                        glVertex3f(-2, 10, 10);
	glEnd();
	glutSwapBuffers();
}

void Reshape(int w, int h)
{
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_LIGHTING);
	glEnable(GL_NORMALIZE);

	glEnable(GL_FOG);
	Width = w;
	Height = h;
	glViewport(0, 0, w, h);

}

void Keyboard(unsigned char key, int x, int y)
{
	const char ESCAPE = '\033';
	if (key == ESCAPE)
		exit(0);
	else if (key == '+')
		density += 0.1;
	else if (key == '-')
		density -= 0.1;
	glutPostRedisplay();
}

int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(Width, Height);
	glutCreateWindow("Fog Example");

	glutDisplayFunc(Display);
	glutReshapeFunc(Reshape);
	glutKeyboardFunc(Keyboard);

	glutMainLoop();
	return 0;
}
