#include <stdlib.h>
#include "glut.h"
#include <math.h>
#include <iostream>
using namespace std;

void init(void);
void display(void);
void drawHouse(void);
int theta;
void init(void)
{
	glClearColor(0.5,0.5,0.5,0.0);
    glShadeModel(GL_FLAT);   //uses GL_SMOOTH or GL_FLAT
	glutInitDisplayMode(GLUT_DEPTH);

  GLfloat mat_specular[] = { 0.256777, 0.137622, 0.086014, 1.0 };
  GLfloat mat_diffuse[] = { 1.7083, 0.27048, 0.0828, 1.0 };
  GLfloat mat_ambient[] = { 0.19125, 0.0735, 0.0225, 1.0 };
  GLfloat mat_shininess[] = { 12.8 };
  GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
   glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
   glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
   glLightfv(GL_LIGHT0, GL_POSITION, light_position);

   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0); 


 	glEnable(GL_DEPTH_TEST);

}
void drawHouse(void)
{
//Description:
//This routine draws the house from OGL primitives
//Note all polygon windings are counter clockwise
//If you look at the front of a polygon its vertices are
//listed so that the polygon is drawn in counterclockwise manner.
//glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
//  glPolygonMode(GL_BACK,GL_FILL); //uses also GL_FRONT_AND_BACK; GL_FILL, GL_POINT, GL_LINE  
//  glPolygonMode(GL_FRONT,GL_FILL);// to spec. whether poly's. front and back are drawn filled
									// as lines or points

//  glCullFace(GL_BACK);//discards front or back facing polygons
//  glEnable(GL_CULL_FACE);  

    
	  
	glBegin(GL_QUADS);
  
    glNormal3f(0.0,0.0,1.0);     
    glVertex3f(0.0,0.0,0.0);//front norm is (0,0,1)
    glVertex3f(0.0,-2.0,0.0); 
    glVertex3f(1.0,-2.0,0.0); 
    glVertex3f(1.0,0.0,0.0); 
 
    glNormal3f(1.0,0.0,0.0);     
    glVertex3f(1.0,0.0,0.0);//right (1,0,0)
    glVertex3f(1.0,-2.0,0.0); 
    glVertex3f(1.0,-2.0,-1.0); 
    glVertex3f(1.0,0.0,-1.0); 
  
    glNormal3f(-1.0,0.0,0.0);     
    glVertex3f(0.0,0.0,0.0);//left (-1,0,0)
    glVertex3f(0.0,0.0,-1.0); 
    glVertex3f(0.0,-2.0,-1.0); 
    glVertex3f(0.0,-2.0,0.0); 

    glNormal3f(0.0,-1.0,0.0);     
    glVertex3f(0.0,-2.0,0.0); //bottom (0,-1,0)
    glVertex3f(0.0,-2.0,-1.0); 
    glVertex3f(1.0,-2.0,-1.0); 
    glVertex3f(1.0,-2.0,0.0); 

    glNormal3f(0.0,0.0,-1.0);     
    glVertex3f(0.0,0.0,-1.0);//back (0,0,-1)
    glVertex3f(1.0,0.0,-1.0); 
    glVertex3f(1.0,-2.0,-1.0); 
    glVertex3f(0.0,-2.0,-1.0); 
 glEnd();
  glBegin(GL_TRIANGLES);
    glNormal3f(0.0,0.0,1.0);     
    glVertex3f(0.0,0.0,0.0);//front gable (0,0,1)
    glVertex3f(1.0,0.0,0.0); 
    glVertex3f(0.5,1.25,0.0); 

    glNormal3f(0.0,0.0,-1.0);     
    glVertex3f(0.0,0.0,-1.0);//back gable (0,0,-1)
    glVertex3f(0.5,1.25,-1.0); 
    glVertex3f(1.0,0.0,-1.0); 
 glEnd(); 
  glBegin(GL_QUADS);
    glNormal3f(-0.9385,0.3714,0.0); 
    glVertex3f(0.0,0.0,0.0);//left roof (-0.9385,0.3714,0.0) 
    glVertex3f(0.5,1.25,0.0); 
    glVertex3f(0.5,1.25,-1.0); 
    glVertex3f(0.0,0.0,-1.0);  

    glNormal3f(0.9385,0.3714,0.0); 
    glVertex3f(0.5,1.25,0.0);//right roof (0.9385,0.3714,0.0)
    glVertex3f(1.0,0.0,0.0); 
    glVertex3f(1.0,0.0,-1.0); 
    glVertex3f(0.5,1.25,-1.0); 
  glEnd();

}
void display(void)
{
//select clearing background colour
//if you don't do this then OGL will display
//whatever was last drawn in the buffer
//make it black
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
	glColor3f(0.0,1.0,1.0);
   glLoadIdentity();//reset transformation (of modelview matrix)

   gluLookAt(5.0*sin(float(theta)*0.0175), 5.0, 5.0*cos(float(theta)*0.0175), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);  
   //  place camera - it rotates about the origin, on y = 5.0 plane,
   // with a radius of 5.0; 0,0,0 - aim lens towards 0,0,0; 
   //  0,1,0 - the up vector defines an unique orientation.
    drawHouse();
  glTranslatef(1.0,0.0,0.0);
	glColor3f(0.0,1.0,0.0);
   drawHouse();
  glTranslatef(2.0,0.0,-1.0);
   glRotatef(90.0,0.0,1.0,0.0);
	glColor3f(0.0,0.0,1.0);
   drawHouse();
    glTranslatef(1.0,0.0,0.0);
	glColor3f(1.0,0.0,0.0);
   drawHouse();

	//glutWireCube(1.0);
	glFlush();
}
void reshape(int w, int h)
{
	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-1.0,1.0,-1.0,1.0,1.5,20.0); 
//             l,r,bot,top,near,far

	glMatrixMode(GL_MODELVIEW);
}
   
void keyboardread(unsigned char key, int x,int y)
{
	switch (key) {
	case 'r':
			theta = (theta + 10)% 360;
			glutPostRedisplay();
			cout<<theta<<endl;
			break;
	case 'l':
			theta = (theta - 10)% 360;
			glutPostRedisplay();
			break;
	}
}

int main(int argc, char** argv)
{
	  glutInit(&argc,argv);
	  glutInitDisplayMode(GLUT_SINGLE |GLUT_RGB);
	  glutInitWindowSize(250,250);
	  glutInitWindowPosition(100,100);
	  glutCreateWindow("3D house");
	  init();
	  glutKeyboardFunc(keyboardread); 
	  glutReshapeFunc(reshape);
	  glutDisplayFunc(display);
	  glutMainLoop();
	  return 0;
}
