#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "glut.h"
#include "gl.h"


typedef struct {
  float x;
  float y;
  float z;
} TOCKA;


TOCKA     t[8]= { {-0.5,-0.5,-0.8},
                  { 0.5,-0.5,-0.8},
                  { 0.5, 0.5,-0.8},
                  {-0.5, 0.5,-0.8},
                  {-0.5,-0.5, 0.8},
                  { 0.5,-0.5, 0.8},
                  { 0.5, 0.5, 0.8},
                  {-0.5, 0.5, 0.8} };

int p[5][4] = { {0, 3, 2, 1}, {4, 5, 6, 7}, {5, 1, 2, 6},
                {0, 4, 7, 3}, {0, 1, 5, 4} };

TOCKA n[5] = { { 0.0, 0.0,-1.0},
               { 0.0, 0.0, 1.0},
               { 1.0, 0.0, 0.0},
               {-1.0, 0.0, 0.0},
               { 0.0,-1.0, 0.0} };

char ime_objekta[5][13] = { "stranica xy1\0",
                            "stranica xy2\0",
                            "stranica yz1\0",
                            "stranica yz2\0",
                            "stranica spd\0" };

float fi_x = 30.0, fi_y = -30.0;
int stari_x = 0, stari_y=0;

/* ===================================== */
void pretvori_geom_model_v_GL_gradnike()
{
  int i, j;

  glInitNames();
  glPushName(-1);
  for (i=0;i<5;i++) {
    glLoadName(i);
    glBegin(GL_QUADS);
      for(j=0; j<4; j++) {
        glNormal3f(n[i].x, n[i].y, n[i].z);
        glVertex3f(t[p[i][j]].x, t[p[i][j]].y, t[p[i][j]].z);
      }
    glEnd();
  }
  glPopName();
}
/* ===================================== */
void risi()
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glColor3f(1.0, 0.4, 1.0);

  glLoadIdentity();
  glScalef(0.5, 0.5, 0.5);
  glRotatef(fi_x, 1.0, 0.0, 0.0);
  glRotatef(fi_y, 0.0, 1.0, 0.0);

  pretvori_geom_model_v_GL_gradnike();

  glutSwapBuffers();
}
/* ===================================== */
void miska(int x, int y)
{
  if (x > stari_x) fi_y += 1.0;
  if (x < stari_x) fi_y -= 1.0;
  if (y > stari_y) fi_x += 1.0;
  if (y < stari_y) fi_x -= 1.0;

  stari_x = x;
  stari_y = y;

  glutPostRedisplay();

}
/* ===================================== */
void obdelaj_zadetke(GLint nr_hits, GLuint buffer[])
{
    unsigned int i, j;
    GLuint nr_names, *ptr;
    int najvisji_nivo_imena;

    printf ("==== obdelaj zadetke: ======\n");
    printf ("stevilo_zadetkov = %d\n", nr_hits);
    ptr = (GLuint *) buffer;
    for (i = 0; i < nr_hits; i++) {
        nr_names = *ptr;
        printf (" stevilo imen v zadetku = %d\n", nr_names); ptr++;
        printf (" z1 je %g;", (float) *ptr/0x7fffffff); ptr++;
        printf (" z2 je %g\n", (float) *ptr/0x7fffffff); ptr++;
        printf (" imena so: ");
        najvisji_nivo_imena = (int) *ptr;
        for (j = 0; j < nr_names; j++) {
            printf ("%d ", (int) *ptr); ptr++;
        }
        printf ("\n");
        printf("interpretacija imena: %s\n",
          ime_objekta[najvisji_nivo_imena]);
    }
}
/* ===================================== */
void pritisk_na_gumb_miske(int stevilka_gumba, int status, int x, int y)
{

  GLuint selectBuf[512];
  GLint nr_hits;
  GLint viewport[4];

  if (stevilka_gumba == GLUT_MIDDLE_BUTTON && status) {
    glGetIntegerv(GL_VIEWPORT, viewport);
    printf("%d %d %d %d\n",viewport[0],viewport[1],viewport[2],viewport[3]);
    glSelectBuffer(512, selectBuf);
    (void) glRenderMode(GL_SELECT);

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();

    gluPickMatrix((GLdouble) x, (GLdouble) (viewport[3] - y),
                  5.0, 5.0, viewport);
    glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);

    glMatrixMode(GL_MODELVIEW);
    risi();
    glFlush();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    glMatrixMode(GL_MODELVIEW);

    nr_hits = glRenderMode(GL_RENDER);
    printf("nr_hits = %d\n",nr_hits);
    obdelaj_zadetke(nr_hits, selectBuf);
    glutPostRedisplay();
  }
}
/* ===================================== */
void inicializiraj_gl()
{
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_COLOR_MATERIAL);
  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-1.0,1.0, -1.0,1.0, -1.0,1.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}
/* ===================================== */


int main(int argn, char **argc)
{
  int moje_okno;

  glutInit(&argn, argc);
  glutInitWindowSize(500, 500);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
  moje_okno = glutCreateWindow("risi_miska_klik");

  inicializiraj_gl();

  glutDisplayFunc (risi);
  glutMotionFunc (miska);
  glutMouseFunc (pritisk_na_gumb_miske);

  glutMainLoop();

  return 0;
}
