/*
	cube_tournant.c

	Cube qui tourne sur lui même

	Auteur : Florent Kaisser

	Université de Cergy-Pontoise
*/

#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>

#define SCREEN_W 800
#define SCREEN_H 600


#define ROTATE_X 1
#define ROTATE_Y 2
#define ROTATE_Z 3 


int axe_rotate=ROTATE_X;

int rect=0;


void toggle_fullscreen(void)
{
   SDL_Surface *S; 
   S = SDL_GetVideoSurface(); 

   SDL_WM_ToggleFullScreen(S);
}

void draw_cube(){


	//place le cube au millieu
	glTranslatef(-0.5,-0.5,-0.5);


	
	glBegin(GL_QUADS);

	//dessine une face
	glVertex3f(0.0,0.0,0.0);
	glVertex3f(0.0,1.0,0.0);
	glVertex3f(1.0,1.0,0.0);
	glVertex3f(1.0,0.0,0.0);


	//une autre face
	glVertex3f(0.0,0.0,1.0);
	glVertex3f(0.0,1.0,1.0);
	glVertex3f(1.0,1.0,1.0);
	glVertex3f(1.0,0.0,1.0);

	//ect...
	glVertex3f(0.0,0.0,0.0);
	glVertex3f(0.0,0.0,1.0);
	glVertex3f(0.0,1.0,1.0);
	glVertex3f(0.0,1.0,0.0);


	glVertex3f(1.0,0.0,0.0);
	glVertex3f(1.0,0.0,1.0);
	glVertex3f(1.0,1.0,1.0);
	glVertex3f(1.0,1.0,0.0);



	glVertex3f(0.0,0.0,0.0);
	glVertex3f(0.0,0.0,1.0);
	glVertex3f(1.0,0.0,1.0);
	glVertex3f(1.0,0.0,0.0);

	//et de 6 !
	glVertex3f(0.0,1.0,0.0);
	glVertex3f(0.0,1.0,1.0);
	glVertex3f(1.0,1.0,1.0);
	glVertex3f(1.0,1.0,0.0);

	glEnd();




}

void draw_pyramide(){

	glBegin(GL_TRIANGLE_STRIP);

	glVertex3f(0.4,0.1,0.0);
	glVertex3f(0.6,0.1,0.0);
	glVertex3f(0.5,0.1,0.2);
	glVertex3f(0.5,0.5,0.1);
	glVertex3f(0.4,0.1,0.0);


	glEnd();

}

/*Dessine la scene*/
void draw_scene(int t){

	GLUquadric *q;

	/*restore la matrice initiale*/
	glPopMatrix();
	glPushMatrix();

	/*efface l'écran*/
	glClear(GL_COLOR_BUFFER_BIT);
	

	switch(axe_rotate){
		case ROTATE_X:
			/*fait pivoter le cube autour de l'axe des X*/
			glRotatef((float)(t%360),1.0,0.0,0.0);
		break;
		case ROTATE_Y:
			/*fait pivoter le cube autour de l'axe des X*/
			glRotatef((float)(t%360),0.0,1.0,0.0);
		break;
		case ROTATE_Z:
			/*fait pivoter le cube autour de l'axe des X*/
			glRotatef((float)(t%360),0.0,0.0,1.0);
		break;
	}

	if(rect)
		/*En faite c'est un rectangle lol*/
		glScalef(2.0,1.0,1.0);

	draw_cube();
	
	SDL_GL_SwapBuffers( );


	return;


}

/*adapte la visualisation à la taille de la fenetre*/
void reshape(int screen_w,int screen_h){



	glViewport(0,0, screen_w,screen_h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0,
	                (float)screen_w/ (float)screen_h,
	                1.0,20.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
 

	

}

/*Initialise les varaibles d'états d'OpenGL*/
void init_gl(){
	/*fond de la fenetre en noir*/
	glClearColor(0.0, 0.0, 0.0, 1.0);  

	/*Par defaut on se met en mode "fil de fer"*/
	glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

	/*On recule de 3*/
	glTranslatef(0.0,0.0,-3);

	/*Sauvegarde la transformation initiale*/
	glPushMatrix();     
}

/*Traite un évenement*/
void process_event(SDL_Event *event){

		switch (event->type) {

		case SDL_VIDEORESIZE:
			SDL_SetVideoMode(event->resize.w,event->resize.h, 24, SDL_OPENGL|SDL_RESIZABLE);
			reshape(event->resize.w,event->resize.h);
			break;		

		case SDL_KEYDOWN:


			switch(event->key.keysym.sym){

// 			//On quite si on appuye sur Echap
			case SDLK_ESCAPE:
				printf("Bye bye...\n");
				exit(0);	
				break;

			case SDLK_SPACE:
				toggle_fullscreen();
				break;

			case 'x':
				axe_rotate=ROTATE_X;
				break;
			case 'y':
				axe_rotate=ROTATE_Y;
				break;

			case 'z':
				axe_rotate=ROTATE_Z;
				break;

			case 'r':

				rect=!rect;

				//evite les repetitions
				SDL_Delay(100);
				break;

			case 'f':
				glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
				SDL_GL_SwapBuffers( );
				break;
			case 'l':
				glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
				SDL_GL_SwapBuffers( );
				break;
			case 'p':
				glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
				SDL_GL_SwapBuffers( );
				break;

			}


		break;


            case SDL_QUIT: {
                printf("Quit requested, quitting.\n");
                exit(0);
            }
            break;
        }
  

}

int main(){

	SDL_Surface *screen;
	SDL_Event event;
	int step=0;

	/* Initialise la libraire SDL */
	if( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0 ) {
		fprintf(stderr,
		"Couldn't initialize SDL: %s\n", SDL_GetError());
		exit(1);
	}
	
	/* netoye au moment où le programme quitte*/
	atexit(SDL_Quit);
	
	/* Initialise l'affichage */
	screen = SDL_SetVideoMode(SCREEN_W , SCREEN_H, 24, SDL_OPENGL|SDL_RESIZABLE);

	if ( screen == NULL ) {
		fprintf(stderr, "Couldn't set  video mode: %s\n",
			SDL_GetError());
		exit(1);
	}

	/* Adapte la visualisation à la fenetre*/
	reshape(SCREEN_W,SCREEN_H);
		
	/* Initialisation des parametres OpenGl*/
	init_gl();

	/*Boucle infinie*/
	while ( 1 ) {
		step+=2;
		/*dessine la scene*/
		draw_scene(step);

		/*Recupere les evenements (si y'en a un)*/
		while(SDL_PollEvent( &event ))
			/*Traite l'evenement*/
			process_event(&event);


		/*Attends 50 ms (~20 image/s)*/
		SDL_Delay(50);
	}
	

  	return 0;
}
