#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <math.h>
#define PI 3.1415926

GLint numero_lati=6,raggio=1,altezza=1,factor=1;
GLushort pattern=0x00FF;
GLfloat viewX=0,viewY=0,viewZ=0;
bool wireframe=false,stipple=false;

void ChangeSize(int w, int h){
    float size=10.0;
	GLfloat lightPos[] = { -50.f, 50.0f, 100.0f, 1.0f };
	if(h==0) h=1;
    glViewport(0,0,w,h);
    float aspect_ratio=float(w)/float(h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if(w>=h)
        glOrtho(-size*aspect_ratio,size*aspect_ratio,-size,size,-size,size);
    else
	    glOrtho(-size,size,-size/aspect_ratio,size/aspect_ratio,-size,size);
	
}

void DrawScene(){
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glClearColor(0.0,0.0,0.0,0.0);
	glClear(GL_COLOR_BUFFER_BIT);
	if(wireframe==true)
		glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
	else
		glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
  
	
	 glRotatef(viewX,1,0,0);
	glRotatef(viewY,0,1,0);
	glRotatef(viewZ,0,0,1);

	glBegin(GL_LINES);
	
	glColor3f(1.0,0.0,0.0);
	 glVertex3f(0.0,0.0,0.0);
	 glVertex3f(10.0,0.0,0.0);

     glColor3f(0.0,1.0,0.0);
	 glVertex3f(0.0,0.0,0.0);
	 glVertex3f(0.0,10.0,0.0);

     glColor3f(0.0,0.0,1.0);
	 glVertex3f(0.0,0.0,0.0);
	 glVertex3f(0.0,0.0,10.0);
	glEnd();
	

	glPushMatrix();
    if(stipple==true)
		glEnable(GL_LINE_STIPPLE);
	glLineStipple(factor,pattern);
	glColor3f(0.0,1.0,0.0);
	glBegin(GL_POLYGON);
	for(int i=0;i<numero_lati;i++)
        glVertex3f(raggio*cos(2*i*PI/numero_lati),0,raggio*sin(2*i*PI/numero_lati));
	glEnd();

	glBegin(GL_QUADS);
	for(i=0;i<numero_lati;i++){
		 glVertex3f(raggio*cos(i*2*PI/numero_lati),0,raggio*sin(i*2*PI/numero_lati));
		 glVertex3f(raggio*cos((i+1)*2*PI/numero_lati),0,raggio*sin((i+1)*2*PI/numero_lati));
		 glVertex3f(raggio*cos((i+1)*2*PI/numero_lati),altezza,raggio*sin((i+1)*2*PI/numero_lati));
		 glVertex3f(raggio*cos(i*2*PI/numero_lati),altezza,raggio*sin(i*2*PI/numero_lati));
	}
	glEnd();
	glPushMatrix();
	glBegin(GL_POLYGON);
	for(i=0;i<numero_lati;i++)
        glVertex3f(raggio*cos(i*2*PI/numero_lati),altezza,raggio*sin(i*2*PI/numero_lati));
	glEnd();
	glPopMatrix();
	 if(stipple==true)
		glDisable(GL_LINE_STIPPLE);
	glPopMatrix();
	glutSwapBuffers();
}
void Keyboard(unsigned char c, int x,int y){
	switch(c){
	case 'q':
        viewX+=5;
		break;
    case 'a':
        viewX-=5;
		break;
    case 'w':
        viewY+=5;
		break;
    case 's':
        viewY-=5;
		break;
    case 'e':
        viewZ+=5;
		break;
    case 'd':
        viewZ-=5;
		break;
	case 'r':
		raggio+=1;
		break;
	case 'f':
		raggio-=1;
		break;
	case 't':
		numero_lati+=1;
		break;
	case 'g':
		numero_lati-=1;
		break;
	case 'y':
		altezza+=1;
		break;
	case 'h':
		altezza-=1;
		break;
	case ' ':
		wireframe=!wireframe;
		break;
	case 'u':
		stipple=!stipple;
		break;
	case 'i':
		factor+=1;
		break;
	case 'k':
		factor-=1;
		break;
	}
	glutPostRedisplay();
}

int main(){
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(640,480);
	glutCreateWindow("esame");
	glutDisplayFunc(DrawScene);
	glutReshapeFunc(ChangeSize);
	glutKeyboardFunc(Keyboard);
	glutMainLoop();
}