#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <stdlib.h>
#include <stdio.h>

GLfloat rotx=0.0;
GLfloat roty=0.0;
GLfloat light0_position[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat	light1_position[] = { -5.0f, -30.0f, 5.0f, 1.0f };

void init (void)
{
   GLfloat  ambientLight[] = { 0.1f, 0.1f, 0.1f, 1.0f};

   GLfloat light0_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
   GLfloat light0_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
   GLfloat light0_specular[] = { 1.0, 1.0, 1.0, 1.0 };
   //GLfloat light0_position[] = { 1.0, 1.0, 1.0, 0.0 };
   
   GLfloat  light1_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f};
   GLfloat  light1_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
   GLfloat  light1_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f};
   //GLfloat	light1_position[] = { -5.0f, -30.0f, 5.0f, 1.0f };
   GLfloat  specref[] =  { 0.6f, 0.6f, 0.6f, 1.0f };

   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

   glLightfv (GL_LIGHT0, GL_AMBIENT, light0_ambient);
   glLightfv (GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
   glLightfv (GL_LIGHT0, GL_SPECULAR, light0_specular);
   glLightfv (GL_LIGHT0, GL_POSITION, light0_position);
   glEnable(GL_LIGHT0);

   glLightfv (GL_LIGHT1, GL_AMBIENT, light1_ambient);
   glLightfv(GL_LIGHT1,GL_DIFFUSE,light1_diffuse);
   glLightfv(GL_LIGHT1,GL_SPECULAR,light1_specular);
   glLightfv(GL_LIGHT1,GL_POSITION,light1_position);
   //glEnable(GL_LIGHT1);

   
   glEnable(GL_COLOR_MATERIAL);
   glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
   glMaterialfv(GL_FRONT, GL_SPECULAR,specref);
   glMateriali(GL_FRONT, GL_SHININESS,30);
   
   glEnable (GL_LIGHTING);
   glEnable (GL_LIGHT0);
   //glEnable(GL_CULL_FACE);
   glEnable(GL_DEPTH_TEST);   

   glShadeModel(GL_SMOOTH);
}

void display (void)
{
   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glPushMatrix ();
    glTranslatef (0.0, 0.0, -5.0); 
    glRotatef (roty, 0.0, 1.0, 0.0);
    glLightfv(GL_LIGHT0,GL_POSITION,light0_position);
    glLightfv(GL_LIGHT1,GL_POSITION,light1_position);
    glRotatef (20.0, 1.0, 0.0, 0.0);

    glPushMatrix ();
     glTranslatef (-0.75, 0.0, 0.0); 
     glRotatef (rotx, 1.0, 0.0, 0.0);
     glColor3f(1.0,0.0,0.0);
     glPushMatrix ();
      glTranslatef (0.0, 0.5, 0.0); 
      glRotatef (90.0, 1.0, 0.0, 0.0);
      glutSolidTorus (0.275, 0.85, 50, 50);
     glPopMatrix ();

     glColor3f(0.0,1.0,0.0);
     glPushMatrix ();
      glTranslatef (0.0, -0.5, 0.0);  
      glRotatef (-90.0, 1.0, 0.0, 0.0);
      glutSolidCone (1.0, 2.0, 50, 50);
     glPopMatrix ();
    glPopMatrix ();

    glColor3f(0.0,0.0,1.0);
    glPushMatrix ();
     glTranslatef (0.75, 0.0, -1.0); 
     glutSolidSphere (1.0, 50, 50);
    glPopMatrix ();
   glPopMatrix ();

   glutSwapBuffers();
}

void reshape(int w, int h)
{
   // Prevent a divide by zero
	if(h == 0)
		h = 1;

	// Set Viewport to window dimensions
    glViewport(0, 0, w, h);

	// Calculate aspect ratio of the window
	float fAspect = (GLfloat)w/(GLfloat)h;

	// Set the perspective coordinate system
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);

   glMatrixMode (GL_MODELVIEW);
   glLoadIdentity ();

}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
         break;
      case 'a':
         rotx+=5.0;
         break;
      case 's':
         rotx-=5.0;
         break;
	  case 'z':
         roty+=5.0;
         break;
      case 'x':
         roty-=5.0;
         break;
   }
   glutPostRedisplay();
}


int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
   glutInitWindowSize (500, 500);
   glutCreateWindow (argv[0]);
   init ();
   glutReshapeFunc (reshape);
   glutDisplayFunc(display);
   glutKeyboardFunc (keyboard);
   glutMainLoop();
   return 0; 
}
