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

#include <iostream>

float lx = 0.0f, lz = -1.0f;

float x = 0.0f, z = 5.0f, h = 3.0, he = 4.7, het = 1;
static float angle = 0, ang = 0;
static int isAnimate = 0;
static int animationPeriod = 50; 
bool m = 1;
static int spin = 0;
static long font = (long)GLUT_BITMAP_8_BY_13;
void writeBitmapString(void *font, char *string)
{
	char *c;
	for (c = string; *c != '\0'; c++) glutBitmapCharacter(font, *c);
}
void init(void)
{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glShadeModel(GL_SMOOTH);


}

void home() {

	
	glColor3f(0, 0, 0);
	glBegin(GL_POLYGON);
	glVertex3f(-10.0f, 10.0f, -80.0f);
	glVertex3f(-10.0f, 10.0f, -50.0f);
	glVertex3f(10.0f, 10.0f, -50.0f);
	glVertex3f(10.0f, 10.0f, -80.0f);
	glEnd();
	glColor3f(0, 0, 0.3);
	glBegin(GL_QUADS);
	glVertex3f(-10.0f, 0.01f, -80.0f);
	glVertex3f(-10.0f, 10.0f, -80.0f);
	glVertex3f(10.0f, 10.0f, -80.0f);
	glVertex3f(10.0f, 0.01f, -80.0f);

	glVertex3f(-11.0f, 0.01f, -81.0f);
	glVertex3f(-11.0f, 10.0f, -81.0f);
	glVertex3f(11.0f, 10.0f, -81.0f);
	glVertex3f(11.0f, 0.01f, -81.0f);
	glEnd();
	glColor3f(0, 0, 0.2);
	glBegin(GL_QUADS);
	glVertex3f(-10.0f, 0.01f, -80.0f);
	glVertex3f(-10.0f, 10.0f, -80.0f);
	glVertex3f(-10.0f, 10.0f, -50.0f);
	glVertex3f(-10.0f, 0.01f, -50.0f);

	glVertex3f(-11.0f, 0.01f, -81.0f);
	glVertex3f(-11.0f, 10.0f, -81.0f);
	glVertex3f(-11.0f, 10.0f, -49.0f);
	glVertex3f(-11.0f, 0.01f, -49.0f);
	glEnd();
	glBegin(GL_QUADS);
	glVertex3f(10.0f, 0.01f, -80.0f);
	glVertex3f(10.0f, 10.0f, -80.0f);
	glVertex3f(10.0f, 10.0f, -50.0f);
	glVertex3f(10.0f, 0.01f, -50.0f);

	glVertex3f(11.0f, 0.01f, -81.0f);
	glVertex3f(11.0f, 10.0f, -81.0f);
	glVertex3f(11.0f, 10.0f, -49.0f);
	glVertex3f(11.0f, 0.01f, -49.0f);
	glEnd();
	glBegin(GL_QUADS);
	glColor3f(0, 0, 0.2);
	glVertex3f(10.0f, 0.01f, -50.0f);
	glVertex3f(10.0f, 10.0f, -50.0f);
	glVertex3f(2.5f, 10.0f, -50.0f);
	glVertex3f(2.5f, 0.01f, -50.0f);

	glVertex3f(11.0f, 0.01f, -49.0f);
	glVertex3f(11.0f, 10.0f, -49.0f);
	glVertex3f(2.5f, 10.0f, -49.0f);
	glVertex3f(2.5f, 0.01f, -49.0f);
	glEnd();
	glBegin(GL_QUADS);
	glVertex3f(-10.0f, 0.01f, -50.0f);
	glVertex3f(-10.0f, 10.0f, -50.0f);
	glVertex3f(-2.5f, 10.0f, -50.0f);
	glVertex3f(-2.5f, 0.01f, -50.0f);

	glVertex3f(-11.0f, 0.01f, -49.0f);
	glVertex3f(-11.0f, 10.0f, -49.0f);
	glVertex3f(-2.5f, 10.0f, -49.0f);
	glVertex3f(-2.5f, 0.01f, -49.0f);
	glEnd();
	glBegin(GL_QUADS);
	glVertex3f(-2.5f, 10.0f, -50.0f);
	glVertex3f(2.5f, 10.0f, -50.0f);
	glVertex3f(2.5f, 6.0f, -50.0f);
	glVertex3f(-2.5f, 6.0f, -50.0f);

	glVertex3f(-2.5f, 10.0f, -49.0f);
	glVertex3f(2.5f, 10.0f, -49.0f);
	glVertex3f(2.5f, 6.0f, -49.0f);
	glVertex3f(-2.5f, 6.0f, -49.0f);
	glEnd();
	glBegin(GL_QUADS);
	glVertex3f(-2.5f, 0.01f, -50.0f);
	glVertex3f(-2.5f, 0.01, -49.0f);
	glVertex3f(-2.5f, 6.0f, -49.0f);
	glVertex3f(-2.5f, 6.0f, -50.0f);

	glVertex3f(2.5f, 0.01f, -50.0f);
	glVertex3f(2.5f, 0.01, -49.0f);
	glVertex3f(2.5f, 6.0f, -49.0f);
	glVertex3f(2.5f, 6.0f, -50.0f);

	glVertex3f(-2.5f, 6.0f, -50.0f);
	glVertex3f(-2.5f, 6.0f, -49.0f);
	glVertex3f(2.5f, 6.0f, -49.0f);
	glVertex3f(2.5f, 6.0f, -50.0f);
	glEnd();
	glColor3f(1, 0, 0);
	
	glBegin(GL_QUADS);
	glVertex3f(-11.0f, 10.0f, -81.0f);
	glVertex3f(-11.0f, 10.0f, -49.0f);
	glVertex3f(0.0f, 15.0f, -49.0f);
	glVertex3f(0.0f, 15.0f, -81.0f);

	glVertex3f(11.0f, 10.0f, -81.0f);
	glVertex3f(11.0f, 10.0f, -49.0f);
	glVertex3f(0.0f, 15.0f, -49.0f);
	glVertex3f(0.0f, 15.0f, -81.0f);
	glEnd();
	glBegin(GL_POLYGON);
	glVertex3f(11.0f, 10.0f, -81.0f);
	glVertex3f(0.0f, 15.0f, -81.0f);
	glVertex3f(-11.0f, 10.0f, -81.0f);
	glEnd();
	glBegin(GL_POLYGON);
	glVertex3f(-11.0f, 10.0f, -49.0f);
	glVertex3f(0.0f, 15.0f, -49.0f);
	glVertex3f(11.0f, 10.0f, -49.0f);
	glEnd();

}


void door()
{
	glColor3f(0.7, 0.4, 0);
	glBegin(GL_QUADS);
	glVertex3f(-2.5f, 0.01f, -49.75f);
	glVertex3f(-2.5f, 7.0f, -49.75f);
	glVertex3f(2.5f, 7.0f, -49.75f);
	glVertex3f(2.5f, 0.01f, -49.75f);

	glVertex3f(-2.5f, 0.01f, -49.25f);
	glVertex3f(-2.5f, 7.0f, -49.25f);
	glVertex3f(2.5f, 7.0f, -49.25f);
	glVertex3f(2.5f, 0.01f, -49.25f);

	glVertex3f(-2.5f, 0.01f, -49.25f);
	glVertex3f(-2.5f, 0.01f, -49.75f);
	glVertex3f(2.5f, 0.01f, -49.75f);
	glVertex3f(2.5f, 0.01f, -49.25f);

	glVertex3f(-2.5f, 0.01f, -49.25f);
	glVertex3f(-2.5f, 6.0f, -49.25f);
	glVertex3f(-2.5f, 6.0f, -49.75f);
	glVertex3f(-2.5f, 0.01f, -49.75f);

	glVertex3f(2.5f, 0.01f, -49.25f);
	glVertex3f(2.5f, 6.0f, -49.25f);
	glVertex3f(2.5f, 6.0f, -49.75f);
	glVertex3f(2.5f, 0.01f, -49.75f);

	glVertex3f(-2.5f, 6.0f, -49.25f);
	glVertex3f(-2.5f, 6.0f, -49.75f);
	glVertex3f(2.5f, 6.0f, -49.75f);
	glVertex3f(2.5f, 6.0f, -49.25f);
	glEnd();
	glColor3f(0, 0, 0);
	glPushMatrix();
	glTranslatef(-2, 3, -49);
	glutSolidSphere(0.2,20,20);
	glPopMatrix();
	glColor3f(0, 0, 0);
	glRasterPos3f(-2, 5, -49);
	writeBitmapString((void*)font, "Press Enter too open/close  the door");
	glColor3f(0, 0, 0);
	glRasterPos3f(-2, 4, -49);
	writeBitmapString((void*)font, "Press space too off/on  the light");
}
void opendoor()
{
	glColor3f(0.7, 0.4, 0);
	glBegin(GL_QUADS);
	glVertex3f(2.5f, 0.01f, -49.75f);
	glVertex3f(2.5f, 6.0f, -49.75f);
	glVertex3f(2.5f, 6.0f, -44.75f);
	glVertex3f(2.5f, 0.01f, -44.75f);

	glVertex3f(2.2f, 0.01f, -49.75f);
	glVertex3f(2.2f, 6.0f, -49.75f);
	glVertex3f(2.2f, 6.0f, -44.75f);
	glVertex3f(2.2f, 0.01f, -44.75f);

	glVertex3f(2.2f, 0.01f, -49.75f);
	glVertex3f(2.5f, 0.01f, -49.75f);
	glVertex3f(2.5f, 0.01f, -44.75f);
	glVertex3f(2.2f, 0.01f, -44.75f);

	glVertex3f(2.2f, 6.0f, -49.75f);
	glVertex3f(2.5f, 6.0f, -49.75f);
	glVertex3f(2.5f, 6.0f, -44.75f);
	glVertex3f(2.2f, 6.0f, -44.75f);

	glVertex3f(2.2f, 0.01f, -49.75f);
	glVertex3f(2.5f, 0.01f, -49.75f);
	glVertex3f(2.5f, 6.0f, -49.75f);
	glVertex3f(2.2f, 6.0f, -49.75f);

	glVertex3f(2.2f, 0.01f, -44.75f);
	glVertex3f(2.5f, 0.01f, -44.75f);
	glVertex3f(2.5f, 6.0f, -44.75f);
	glVertex3f(2.2f, 6.0f, -44.75f);
	glEnd();
	glColor3f(0, 0, 0);
	glPushMatrix();
	glTranslatef(2.5, 3, -45);
	glutSolidSphere(0.2, 20, 20);
	glPopMatrix();
}

void renderScene(void) {

	
	glClearColor(0.8, 0.8, 1.0, 1);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	
	glLoadIdentity();
	//  camera
	gluLookAt(x, h, z,
		x + lx, h, z + lz,
		0.0f, 1.0f, 0.0f);


	glPushMatrix();
//	glTranslatef(0, 0, -5);
	init();
	
	home();
	
	
	if (m)

		door();
	else
		opendoor();
	glPopMatrix();
	
	glutSwapBuffers();
}

void changeSize(int w, int h)
{

	
	
	if (h == 0)
		h = 1;
	float ratio = w * 1.0 / h;


	glMatrixMode(GL_PROJECTION);


	glLoadIdentity();


	glViewport(0, 0, w, h);

	
	gluPerspective(45.0f, ratio, 0.1f, 100.0f);

	
	glMatrixMode(GL_MODELVIEW);
}
void animate(int value)
{
	if (isAnimate)
	{
		ang += 5;
		glutPostRedisplay();
		glutTimerFunc(animationPeriod, animate, 1);
	}
}

void processNormalKeys(unsigned char key, int x, int y)
{

	if (key == 27)
		exit(0);
	if (key == 13)
	{
		if (m)
			m = 0;
		else
			m = 1;
		glutPostRedisplay();
	}
	if (key == 's')
	{
		h -= 1;
		glutPostRedisplay();
	}
	if (key == 'w')
	{
		h += 1;
		glutPostRedisplay();
	}
	if (key == 't')
	{
		if (isAnimate) isAnimate = 0;
		else
		{
			isAnimate = 1;
			animate(1);
		}
		
	}
	if (key == ' ')
	{
		if (spin)
		{
		
			spin = 0;
		}
		else
		{
			
			spin = 1;
		}


		glutPostRedisplay();
	}
}



void processSpecialKeys(int key, int xx, int yy) {

	float fraction = 0.1f;

	switch (key) {
		

	case GLUT_KEY_LEFT:
		angle -= 0.01f;
		lx = sin(angle);
		lz = -cos(angle);
		break;
	case GLUT_KEY_RIGHT:
		angle += 0.01f;
		lx = sin(angle);
		lz = -cos(angle);
		break;
	case GLUT_KEY_UP:
		x += 10 * lx * fraction;
		z += 10 * lz * fraction;
		break;
	case GLUT_KEY_DOWN:
		x -= 10 * lx * fraction;
		z -= 10 * lz * fraction;
		break;
	}
}

int main(int argc, char **argv) {

	

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(500, 500);
	glutCreateWindow("3D_room");

\
	glutDisplayFunc(renderScene);
	glutReshapeFunc(changeSize);
	glutIdleFunc(renderScene);
	glutKeyboardFunc(processNormalKeys);
	glutSpecialFunc(processSpecialKeys);
	\
	

	glEnable(GL_DEPTH_TEST);
	
	glutMainLoop();
	return 0;
}
