#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <GL/glut.h>
#include <GL/gl.h>

int animate = 0;
int order=1;
float xAngle = 0.0;
float yAngle = 0.0;


void drawEverything(void)
	{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0, 1.0, 1.0, 10.0);
	glMatrixMode(GL_MODELVIEW);

	glLoadIdentity();
	glTranslatef(0.0, 0.0, -6.0);
	
	glColor3f(1.0, 1.0, 1.0);

	if (order == 1)
		{
		glRotatef(xAngle, 1.0, 0.0, 0.0);
		glRotatef(yAngle, 0.0, 1.0, 0.0);
		}
	else
		{
		glRotatef(yAngle, 0.0, 1.0, 0.0);
		glRotatef(xAngle, 1.0, 0.0, 0.0);
		}
	glutWireTorus(0.5, 2.0, 6, 12);

	glutSwapBuffers();
	}


static void key(unsigned char k, int x, int y)
	{
	if (k == 27)
		exit(0);
	else if (k == '1')
		{
		animate = 1;
		xAngle = yAngle = 0.0;
		order = 1;
		}
	else if (k == '2')
		{
		animate = 1;
		xAngle = yAngle = 0.0;
		order = 2;
		}
	else if (k == ' ')
		animate = 0;
	glutPostRedisplay();
	}



static int initsec, initusec;

void initClock(void)
	{
	struct timeval t;
	gettimeofday(&t,NULL);
	initsec = t.tv_sec;
	initusec = t.tv_usec;
	}

float clockTime(void)
	{
	struct timeval t;
	gettimeofday(&t,NULL);
	return (t.tv_sec - initsec) +
	 	(t.tv_usec - initusec) / 1000000.0;
	}


void update(void)
	{
	static float lastTime = 0;
	float currentTime = clockTime();
	if (animate)
		{
		float deltaTime = currentTime - lastTime;
		if (order == 1)
			{
			if (xAngle < 45.0)
				xAngle += 30 * deltaTime;
			else if (yAngle < 90.0)
				yAngle += 30 * deltaTime;
			else
				animate = 0;
			}
		else
			{
			if (yAngle < 90.0)
				yAngle += 30 * deltaTime;
			else if (xAngle < 45.0)
				xAngle += 30 * deltaTime;
			else
				animate = 0;
			}
		glutPostRedisplay();
		}
	lastTime = currentTime;
	}


int main(int argc, char *argv[])
	{
	initClock();
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
	glutCreateWindow("example");
	glutDisplayFunc(drawEverything);
	glutKeyboardFunc(key);
	glutIdleFunc(update);
	glutMainLoop();
	return 0;
	}

