//Quiz 2   7 Aug 2005 ;  
#include <GL/glut.h>
#include <stdlib.h>
//float 	nnear = 3.0;    	/* near clipping plane in eye coords */
//float 	nfar = 7.0;    	/* far clipping plane in eye coords */

float	px,py,pz  = 0.0;
float	sc = 2.0;
int  	ang,rot,rup = 0 ; 
char	autoplay = 0 ; 

void init(void)  {
//	GLfloat mat_specular[] = { 0.8, 0.8, 1.0, 1.0 };
//	GLfloat mat_shininess[] = { 50.0 };
//	GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

	glClearColor (0.0,0.4,0.5,1.0);
	glShadeModel (GL_SMOOTH);

//	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
//	glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
//	glLightfv(GL_LIGHT0, GL_POSITION, light_position);
	/*enable GL capabilities */
//	glEnable(GL_LIGHTING);	//use the current lighting parameters to compute 
//	glEnable(GL_LIGHT0);   //include light i in the evaluation 
//	glEnable(GL_DEPTH_TEST);   //depth comparisons and update the depth buffer
	/*  glFrustum( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far )*/
//	glFrustum(-1.25, 1.25, -1.25, 1.25, nnear, nfar); //force execution of GL commands in finite time 
}

void display(void)	{
   glClear (GL_COLOR_BUFFER_BIT);
   glPushMatrix();
// multiply the current matrix by a translation 
	/* glTranslatef( GLfloat x, GLfloat y, GLfloat z )  */
   glTranslatef (px , py , pz);  // ตำแหน่ง centec รูป  
// multiply the current matrix by a rotation
	/* glRotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z )   */
   glRotatef ((GLfloat) ang, 0.0, 0.0, 1.0); //หมุนรอบแกน  Z
   glRotatef ((GLfloat) rot, 0.0, 1.0, 0.0); //หมุนรอบแกน  Y
   glRotatef ((GLfloat) rup, 1.0, 0.0, 0.0); //หมุนรอบแกน  X
   glTranslatef (0.0, 0.0, 0.0);  //center อ้างอิงเมื่อหมุน
 //  glPushMatrix();
   glScalef (sc, sc, sc);
   glutWireCube (1.0);
 //  glPopMatrix();
   glPopMatrix();
   glutSwapBuffers();
}

void idle(void) {
	unsigned int i,j ;
	if(px!=3) px-=(px-3)/100;
	if(py!=3) py-=(py-3)/100;
	if(pz!=3) pz-=(pz)/100;
	if(sc!=1) sc-=(sc-1)/100;
//sc=1;px=py=3;pz=0;
	if(rot!=0) rot-=rot/100;
	if(rup!=0) rup-=rup/100;
	ang = (ang + 1) % 360;
	for (i=0; i<=0xffff; i++) 	for (j=0; j<=0x2f; j++);
	glutPostRedisplay();
}

void reshape (int w, int h)
{	/*glViewport( GLint x, GLint y, GLsizei width, GLsizei height ) */
   glViewport (0, 0, (GLsizei) w, (GLsizei) h ); 
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
	/* gluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar ) */
   gluPerspective(90.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glTranslatef (0.0, 0.0, -5.0);
}

void keyboard (unsigned char key, int x, int y)  {
	switch (key) {
		case 'c':
			px = py =  0 ;
			glutPostRedisplay();
			break;

		case 'C':
			px = py = ang = 0 ;
			glutPostRedisplay();
			break;

		case 'h':
		case 'H':
		case '5':
			px = py = pz = ang = rot = rup = 0 ;
			sc = 2.0;
			glutIdleFunc(0);
			glutPostRedisplay();
			break;

		case 'u':
		case 'U':
		case '8':
			if (py < 3) py += 0.1;
			glutPostRedisplay();
			break;

		case 'd':
		case 'D':
		case '2':
			if (py > -3) py -= 0.1;
			glutPostRedisplay();
			break;

		case 'r':
		case 'R':
		case '6':
			if (px < 3) px += 0.1;
			glutPostRedisplay();
			break;

		case 'l':
		case 'L':
		case '4':
			if (px > -3) px -= 0.1;
			glutPostRedisplay();
			break;

		case 'n':
		case 'N':
		case '0':
			if (pz < 3) pz += 0.1;
			glutPostRedisplay();
			break;

		case 'f':
		case 'F':
		case '.':
			if (pz > -12) pz -= 0.1;
			glutPostRedisplay();
			break;

		case 's':
		case '-':
			if (sc > -3) sc -= 0.1;
			glutPostRedisplay();
			break;

		case 'S':
		case '+':
			if (sc < 4.2) sc += 0.1;
			glutPostRedisplay();
			break;

		case '7':
		case 'z':
			ang = (ang + 5) % 360;
			glutPostRedisplay();
			break;
		case '9':
		case 'Z':
			ang = (ang - 5) % 360;
			glutPostRedisplay();
			break;

		case '1':
		case 'Y':
			rot = (rot - 5) % 360;
			glutPostRedisplay();
			break;
		case '3':
		case 'y':
			rot = (rot + 5) % 360;
			glutPostRedisplay();
			break;

		case '*':
		case 'X':
			rup = (rup - 5) % 360;
			glutPostRedisplay();
			break;
		case '/':
		case 'x':
			rup = (rup + 5) % 360;
			glutPostRedisplay();
			break;

		case 'm':
			sc *= -1;
			glutPostRedisplay();
			break;

		case ' ':
			if(autoplay==0) { 
				glutIdleFunc(idle);
				autoplay=1;
			}else{
				glutIdleFunc(0);
				autoplay=0;
			}
			break;

		case 27:
			exit(0);
			break;

		default:
			break;

  glutPostRedisplay();
   }
}

void disphelp(){
	printf("  --- Help Menu --- \n");
	printf(" c      - Center Position \n");
	printf(" C      - Center Angle & Position  \n");
	printf(" 5,h    - Home \n");
	printf(" 8,u,U  - Up \n");
	printf(" 2,d,D  - Down \n");
	printf(" 4,l,L  - Left \n");
	printf(" 6,r,R  - Right \n");
	printf(" 0,n,N  - Near \n");
	printf(" .,f,F  - Far \n");
	printf(" +,S    - Scal + \n");
	printf(" -,s    - Scal - \n");
	printf(" m      - Scal miller up\n");
	printf(" 7,z    - Rotate wcc.\n");
	printf(" 9,Z     - Rotate wc.\n");
	printf(" 1,Y    - Rotate left\n");
	printf(" 3,y    - Rotate right\n");
	printf(" /,x    - Rotate down\n");
	printf(" *,X    - Rotate up\n");
	printf(" Spec   - Start/Start 3,3,0RotataZ\n");
	printf("ESC     - Exit\n");
}

int main(int argc, char** argv) {
	disphelp();
	glutInit(&argc, argv);
	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize (500, 500); 
	glutInitWindowPosition (250, 50);
	glutCreateWindow (argv[0]);
	init ();
	glutDisplayFunc(display); 
	glutReshapeFunc(reshape);
	glutKeyboardFunc(keyboard);
	glutMainLoop();
return 0;
}
