#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <stdio.h>
#include <time.h>

#define TEZINA 10
#define PI 3.14159265

double xkamere= 10.0,ykamere = -25.0 ,zkamere = 20, kut = 0.0, ubrzanje = 0.1, pomak = 0,pomakUbrzanje = 0, pozicije[TEZINA][3], ilVelicina = 1;
int crash = 0;

float bijelo[] = {1.0f, 1.0f, 1.0f, 1.0f};
float crno[] = {0.0f, 0.0f, 0.0f, 1.0f};
float crveno[] = {0.8f, 0.1f, 0.1f, 1.0f};
float boja[] = {5*17 / 255.0f, 5*21 / 255.0f, 5*9 / 255.0f};

void mreza(double size){
     int i;
     //glColor3d(1.0,0.0,0);

     for (i = -size;i<=size;i++)
         {
                  glBegin(GL_LINES);
                  glVertex3d(i,-size,0);
                  glVertex3d(i,size,0);
                  glEnd();
                  glBegin(GL_LINES);
                  glVertex3d(-size,i,0);
                  glVertex3d(size,i,0);
                  glEnd();
         }
     }

void kugla(double R, int nphi, int ntheta) {
  double t, r, z;
  double theta, step_theta = M_PI / ntheta;
  double r1, r2, z1, z2;
  int i;

  // bliža kapica
  theta = M_PI / 2.0 - step_theta;
  r = R * cos(theta);
  z = R * sin(theta);
  glBegin(GL_TRIANGLE_FAN);
    glNormal3d(0.0, 0.0, 1.0);
    glVertex3d(0.0, 0.0, R);
    t = 0.0;
    for(i = 0; i <= nphi; i++) {
      glNormal3d(r * cos(t) / R, r * sin(t) / R, z / R);      
      glVertex3d(r * cos(t), r * sin(t), z);
      t += 2.0 * M_PI / nphi;
    }
  glEnd();

  // plašt
  for(theta = M_PI / 2.0 - 2.0 * step_theta; theta > -M_PI / 2.0;
      theta -= step_theta) {
    r1 = R * cos(theta); r2 = R * cos(theta + step_theta);
    z1 = R * sin(theta); z2 = R * sin(theta + step_theta);  
 
    glBegin(GL_QUAD_STRIP);
      t = 0.0; 
      for(i = 0; i <= nphi; i++) {
        glNormal3d(r2 * cos(t) / R, r2 * sin(t) / R, z2 / R);
        glVertex3d(r2 * cos(t), r2 * sin(t), z2);
        glNormal3d(r1 * cos(t) / R, r1 * sin(t) / R, z1 / R);
        glVertex3d(r1 * cos(t), r1 * sin(t), z1);
        t += 2.0 * M_PI / nphi;
      }
    glEnd();
  }

  // dalja kapica
  theta = -M_PI / 2.0 + step_theta;
  r = R * cos(theta);
  z = R * sin(theta);
  glBegin(GL_TRIANGLE_FAN);
    glNormal3d(0.0, 0.0, -1.0);
    glVertex3d(0.0, 0.0, -R);
    t = 0.0;
    for(i = 0; i <= nphi; i++) {
      glNormal3d(r * cos(t) / R, r * sin(t) / R, z / R);
      glVertex3d(r * cos(t), r * sin(t), z);
      t -= 2.0 * M_PI / nphi;
    }
  glEnd();
} // kugla


void svjetlo0() {
  float pozicija[] = {0.0f, 0.0f, 0.0f, 1.0f};
  // četvrti parametar postavljen na 1.0f definira "positional light"
  // na poziciji koju određuju prva tri parametra
  
  
  glLightfv(GL_LIGHT0, GL_DIFFUSE, boja);
  glLightfv(GL_LIGHT0, GL_SPECULAR, bijelo);
  glLightfv(GL_LIGHT0, GL_POSITION, pozicija);

} // svjetlo0


void iscrtaj() {
     int i;
  double a = 8.0; // duljina stranice kocke
  double d = 3.0; // odmak od osi
  double spremnikLopte[TEZINA][3];
  
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  //glColor3d(1.0, 1.0, 0.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  gluLookAt(xkamere, ykamere, zkamere, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
  
  glPushMatrix(); // postavljanje izvora svjetlosti
    glTranslated(2.0, -15.0, 2.0);
    svjetlo0();
  glPopMatrix();
  
  
  mreza(15);
  //zle lopte usuda
  for (i = 0;i<TEZINA;i++){
  glPushMatrix();
  glTranslated(pozicije[i][0],pozicije[i][1]-kut,1);
  kugla(pozicije[i][2],32,32);
  glPopMatrix();
}
  //igraceva lopta
  glMaterialfv(GL_FRONT, GL_DIFFUSE, crveno);  
  glPushMatrix();
  glTranslated(pomak,-10,1);
  kugla(ilVelicina,32,32);
  glPopMatrix();
  glMaterialfv(GL_FRONT, GL_DIFFUSE, boja);
  //provjera kolizije
  for (i = 0; i<TEZINA;i++){
      double dx = pozicije[i][0] - pomak;
      double dy = pozicije[i][1] - kut + 10;
      double dz = 1-1; //takozvana nula
      double udaljenost = sqrt(dx*dx + dy*dy + dz*dz);
      if (udaljenost < pozicije[i][2]+ilVelicina) crash = 1;
                     
  }
  
  glutSwapBuffers();  
  
} // iscrtaj

void skaliraj(int w, int h) {
  double xmin = -15.0, xmax = 15.0;
  double xrange = xmax - xmin;
  double yrange = h * xrange / w;

  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glFrustum(xmin, xmax, -yrange / 2.0, yrange / 2.0, 20.0, 50.0);
} // skaliraj

void tipka(unsigned char c, int x, int y) {
  if(c == 'q') exit(0);
  if(c == 's') pomakUbrzanje = 0;
  if(c == 'd') {if (pomakUbrzanje < 0) pomakUbrzanje = 0;
       if(pomakUbrzanje < 0.6)pomakUbrzanje += 0.1;}
  if(c == 'a') {
       if (pomakUbrzanje > 0) pomakUbrzanje = 0;
       if(pomakUbrzanje > -0.6)pomakUbrzanje += -0.1;
       }
  if(c == 'c'){       
       ilVelicina += 0.1;
       }
  if(c == 'x'){
       if (ilVelicina > 0.2) ilVelicina -= 0.1;
       }
} // tipka

void rotiraj(int id) {
     if (crash == 0){
                if (kut > 32) {                        
                     kut = -1;
                     srand(time(NULL));
                    int i;
                    for (i = 0; i<TEZINA;i++){
                        pozicije[i][0] = rand() % 27 - 13;
                        //printf("%f\n", pozicije[i][0]);
                        pozicije[i][1] = rand() % 15 + 3;
                        //printf("%f\n", pozicije[i][1]);
                        pozicije[i][2] = (rand() % 3 + 3)/10.0;        
                        //printf("%f\n", pozicije[i][2]);
                    }
                 
                 }
                 ubrzanje += 0.0001;
               kut += ubrzanje;
               if (pomak < -13 ) {pomakUbrzanje = 0; pomak = -13;}
               if  (pomak > 13) {pomakUbrzanje = 0; pomak = 13;}
               pomak += pomakUbrzanje;               
                }
   glutPostRedisplay();
  // čekaj 50 milisekundi i ponovo pozovi rotirajT
  glutTimerFunc(50, rotiraj, 0);
        
       
} // rotiraj

int main(int argc, char** argv) {
    srand(time(NULL));
    int i;
    for (i = 0; i<TEZINA;i++){
        pozicije[i][0] = rand() % 27 - 13;
        //printf("%f\n", pozicije[i][0]);
        pozicije[i][1] = rand() % 15 + 3;
        //printf("%f\n", pozicije[i][1]);
        pozicije[i][2] = (rand() % 3 + 3)/10.0;        
        //printf("%f\n", pozicije[i][2]);
    }
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
  
  glutInitWindowSize(800, 600);
  glutCreateWindow("sudari");

  glShadeModel(GL_SMOOTH);
  glClearColor(0.0, 0.0, 0.0, 0.0);
  
  glEnable(GL_LIGHTING); // omogućava osvjetljavanje
	glEnable(GL_LIGHT0); // uključuje svjetlo 0

  glutDisplayFunc(iscrtaj);
  glutReshapeFunc(skaliraj);
  glutKeyboardFunc(tipka);  
  glEnable(GL_DEPTH_TEST);
glutTimerFunc(50, rotiraj, 0);
  glutMainLoop();
  return 0;
} // main
