#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
//#include <iostream.h>
/*#include <ostream.h>
#include <fstream.h>*/

static GLuint theGred;

float dd,n,p,l;

/* Izrisi gred */
double gred()
{
 
   int i,k;
   double x,y,z,xn,yn,zn,a,b,c,r,r1,va[3],vb[3],kot,rp,z1,x1,y1,iz,l,ha,hb,nadmera,korak,sf,s,j,t,twopi;
   double zkot; 
    
    printf ("Dobrodosli v programu za 3D izris trapezne navojne gredi   \n");
    printf ("Podaj naslednje podatke za izris gredi\n");
    printf ("Velikost trapeznega navoja (60) =  ");
	scanf("%f",&dd);
    printf ("Dolzina ostalega dela gredi (50) =  ");
 	scanf("%f",&l);
    printf ("Korak trapeznega navoja (15) = ");
	scanf("%f",&p);
    printf ("Stevilo ovojev (30) = ");
	scanf("%f",&n);
	
	nadmera = 25/100; 
    kot= 0.1;
 	ha = 0.5 * p;
    hb = ha + nadmera;
	r = dd/2;
	r1 = r-hb;
	b=26/100*(dd-2*r1)/2;
	a=(p-2*b)/2;
	c=a;
	iz=2*p;
    rp=2; 
      
    printf ("Izbral si: \n\n");
	printf ("Velikost trapeznega navoja je = %f \n", dd);
	printf ("Visina trapeznega navoja h = %f \n", hb+ha);
	printf ("Korak navoja je = %f\n", p);
	printf ("Stevilo ovojev je = %f\n", n);
    printf ("Skupna dolzina gredi = %f\n", l+n*p);
 	printf ("Prosta mera nadmera = %f\n\n\n", nadmera);
	printf ("Tipke za manipulacijo objekta \n\n");

    printf ("(P) povecava \n");
    printf ("(M) pomanjsava \n");
    printf ("(C) rotacija okrog x osi \n");
    printf ("(V) rotacija okrog y osi \n");
    printf ("(Z) rotacija okrog z osi \n");
    printf ("(L,J) translacija  v x osi \n");
	printf ("(U,K) translacija  v y osi \n");
    printf ("(H,N) translacija  v z osi \n");
	printf ("(Q) Izhod\n");
	

//prva vijacnica
	     
    glBegin(GL_QUAD_STRIP);

          for (j = 0; j < (n+4)*3.14*2 ; j=j+kot) {                
           x = r*cos(j);
           y = r*sin(j);
           z = p/(3.14*2)*j+0.01;
           x1 = r*cos(j);
           y1 = r*sin(j);
           z1 = p/(3.14*2)*j-a-0.01;
  		   	   
		   xn=x;
           yn=y;
		   zn=0;
   
           if(z>=n*p){
		   z=n*p;}

          if(z<=0){
		   z=0;}  
         
		  if(z1<=0){
		     z1=0;}
          if(z1>=n*p){
		     z1=n*p;}
           if(z1>=n*p){
		    x=x1;
			y=y1;
			zkot=j;
			j=1000;}

      	   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
           glVertex3f(x,y,z);
		   
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
		   glVertex3f(x1,y1,z1);	  
	      
               
	
		   }

			glEnd(); 

// druga vijacnica			
			glBegin(GL_QUAD_STRIP);
	        for (j = -7; j < (n+3)*3.14*2; j=j+kot) {                
   				
		   x = r*cos(j);
           y = r*sin(j);
           z = p*j/(3.14*2)+b;
           x1 = r1*cos(j);
           y1 = r1*sin(j);
           z1 = p*j/(3.14*2);
	      
          
		   xn=x-x1;
           yn=y-y1;
		   zn=b;
              
	   
		   if(z>=n*p){
		   z=n*p;  }

          if(z<=0){
			  z=0;}
		              
          if(z1<=0){
		     z1=0;}

          if(z1>=n*p){
			  z1=n*p;}

       	  if(j>=zkot){
              x=x1;
			  y=y1;
       		  j=1000;
         

		  	 }


      	   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
           glVertex3f(x,y,z);
		  	   
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
		   glVertex3f(x1,y1,z1);
 
       		 	        
	   }

		glEnd(); 

		
//cetrta vijacnica

		glBegin(GL_QUAD_STRIP);
	     
			for (j = -7; j < (n+3)*3.14*2; j=j+kot) {                
        		   
		   x1 = r1*cos(j);
           y1 = r1*sin(j);
           z1 = p*j/(3.14*2)+b+c+b;
		   x = r*cos(j);
           y = r*sin(j);
           z = p*j/(3.14*2)+b+c;			

           xn=x-x1;
           yn=y-y1;
		   zn=-b;
 
		   if(z>=n*p){
		   z=n*p;
		   	 
		   }
             
        
         if(z<=0){
		   z=0;
		   	   
		   }
             
          if(z1<=0){
		     z1=0;
		   	   
		   }
          if(z1>=n*p){
		     z1=n*p;
        
		   	   
		   }
       
		  if(z1>=p*n){
              x=x1;
			  y=y1;
              j=1000;
		  }
		  
      	   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
           glVertex3f(x,y,z);
		  	   
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
		   glVertex3f(x1,y1,z1);

       
	   }

			glEnd(); 


//tretja vijacnica			
			glBegin(GL_QUAD_STRIP);
	        for (j = -7; j < (n+3)*3.14*2;j=j+kot) {                
         	   
		   x = r1*cos(j);
           y = r1*sin(j);
           z = p/(3.14*2)*j+c+b;
           x1 = r1*cos(j);
           y1 = r1*sin(j);
           z1 = p/(3.14*2)*j+b;
           xn=x;
           yn=y;
		   zn=0;

       if(z>=n*p){
		   z=n*p;
		   	   
		   }
       if(z<=0){
		   z=0;
		   	   
		   }
             
             
          if(z1<=0){
		     z1=0;
		   	   
		   }
          if(z1>=n*p){
		     z1=n*p;
		      
		   }
        
      	   
		  glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
           glVertex3f(x,y,z);
		  	   
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
		   glVertex3f(x1,y1,z1);
  		 		 	        
	   }

			glEnd();


//Posnetje robu			
			glBegin(GL_QUAD_STRIP);
	       for (j = 0; j < (n+1)*3.14*2; j=j+kot) {                
        	   
		   x = r*cos(j);
           y = r*sin(j);
           z = 0;
		   x1 = (r-rp)*cos(j);
           y1 = (r-rp)*sin(j);
           z1 =-rp;
		  
		   xn=x-x1;
           yn=y-y1;
		   zn=-rp;

           glNormal3f(xn,yn,zn);	
           glVertex3f(x,y,z);
		 
		  
		   glNormal3f(xn,yn,zn);
		   glVertex3f(x1,y1,z1);
		   		 		 	        
	   }

			glEnd(); 


 //krog
			
	       glBegin(GL_QUAD_STRIP);
	       for (j = 0; j<=3*3.14*2 ; j=j+kot) {                
           x = (r-rp)*cos(j);
           y = (r-rp)*sin(j);
           z = -rp;
		   
		   x1 = 0;
           y1 = 0;
           z1 = -rp;
		  
		   xn=0;
           yn=0;
		   zn=-p;
		   
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
	       glVertex3f(x,y,z);
	 	  
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
		   glVertex3f(x1,y1,z1);}
         		 		 	        
	  

			glEnd(); 

 //iztek orodja

	       glBegin(GL_QUAD_STRIP);
	       for (j = 0; j<=3*3.14*2 ; j=j+kot) {                
           x = r1*cos(j);
           y = r1*sin(j);
           z = p*n;
		   
		   x1 = x;
           y1 = y;
           z1 = p*n+iz;
		  
		   xn=x;
           yn=y;
		   zn=0;
		   
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
	       glVertex3f(x,y,z);
	 	  
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
		   glVertex3f(x1,y1,z1);}
   	          		 		 	        
	  

		   glEnd();


	    //Posnetje ob izteku
			
	       glBegin(GL_QUAD_STRIP);
	       for (j = 0; j<=3*3.14 ; j=j+kot) {                
           x = r1*cos(j);
           y = r1*sin(j);
           z = p*n+iz;
		   
           x1 = (r+r-r1)*cos(j);
           y1 = (r+r-r1)*sin(j);
           z1 = p*n+iz+(r-r1)*2;
		     
		  
		   xn=x;
           yn=y;
		   zn=-p/2;
		   
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
	       glVertex3f(x,y,z);
	 	  
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
		   glVertex3f(x1,y1,z1);}
   	       glEnd(); 



		   //Nadaljevanje gredi

		   
		   glBegin(GL_QUAD_STRIP);
	       for (j = 0; j<=3*3.14 ; j=j+kot) {                
          
		   x = (r+r-r1)*cos(j);
           y = (r+r-r1)*sin(j);
           z = p*n+iz+(r-r1)*2+l;

           x1 = (r+r-r1)*cos(j);
           y1 = (r+r-r1)*sin(j);
           z1 = p*n+iz+(r-r1)*2;
		     
		  
		   xn=x;
           yn=y;
		   zn=0;
		   
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
	       glVertex3f(x,y,z);
	 	  
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
		   glVertex3f(x1,y1,z1);}
   	       glEnd(); 

		   
//krog zaključek gredi
			
	       glBegin(GL_QUAD_STRIP);
	       for (j = 0; j<=3*3.14 ; j=j+kot) {  
		   x = (r+r-r1)*cos(j);
           y = (r+r-r1)*sin(j);
           z = p*n+iz+(r-r1)*2+l;
	   
		   x1 = 0;
           y1 = 0;
           z1 = p*n+iz+(r-r1)*2+l;
		  
		   xn=0;
           yn=0;
		   zn=p;
		   
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
	       glVertex3f(x,y,z);
	 	  
		   glNormal3f(xn,yn,zn);
		   glColor3f(1.0,0.0,0.0);
		   glVertex3f(x1,y1,z1);
   	          		 		 	        
		   }

			glEnd();
 return (0);
}




/* Create display list with Gred and initialize state */
 
double init() 
{

  GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
  GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  GLfloat mat_shininess[] = { 100.0 };
  
  glClearColor (0.0, 0.0, 1.0, 0.0);
  glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
  glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
  glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
  
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_AUTO_NORMAL);
  glEnable(GL_NORMALIZE);
  
  theGred = glGenLists (1);
  glNewList(theGred, GL_COMPILE);
  gred();
  glEndList();

return(0);
}


/* Clear window and draw Gred */

void display(void)
{
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glPushMatrix ();
  glCallList(theGred);
  glPopMatrix ();
  glFlush();
}


void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(30, (GLfloat) w/(GLfloat) h, 1.0, 100.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   gluLookAt(-1, 1, -1,0, 0, 0, 0, 1, 0);
   glScalef(1/(1.5*(l+n*p+dd)),1/(1.5*(l+n*p+dd)),1/(1.5*(l+p*n+dd)));
   glTranslatef(0,0,-n*p/2);
   glutPostRedisplay();
}

/*Transformacije*/

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
   case 'c':
   case 'C':
      glRotatef(10.,1.0,0.0,0.0);
      glutPostRedisplay();
      break;
   case 'v':
   case 'V':
      glRotatef(10.,0.0,1.0,0.0);
      glutPostRedisplay();
      break;
   case 'z':
   case 'Z':
      glRotatef(10.,0.0,0.0,1.0);
      glutPostRedisplay();
      break;
   case 'p':
   case 'P':
      glScalef(1.1,1.1,1.1);
      glutPostRedisplay();
      break;
   case 'm':
   case 'M':
      glScalef(0.9,0.9,0.9);
      glutPostRedisplay();
      break;

   case 'l':
   case 'L':
      glTranslatef(1,0,0);
      glutPostRedisplay();
      break;

   case 'j':
   case 'J':
      glTranslatef(-1,0,0);
      glutPostRedisplay();
      break;

   case 'u':
   case 'U':
      glTranslatef(0,1,0);
      glutPostRedisplay();
      break;

   case 'k':
   case 'K':
      glTranslatef(0,-1,0);
      glutPostRedisplay();
      break;

   case 'h':
   case 'H':
      glTranslatef(0,0,1);
      glutPostRedisplay();
      break;

   case 'n':
   case 'N':
      glTranslatef(0,0,-1);
      glutPostRedisplay();
      break;
   case 'q':
	 exit(0);
	 break;
	 
  
  
   }
}

int   main(int argc, char **argv)
{
   glutInitWindowSize(500, 500);
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE| GLUT_RGB | GLUT_DEPTH);
   glutCreateWindow("Navojna gred");
   init();
   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);
   glutDisplayFunc(display);
   glutMainLoop();
   return 0;
}
