#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include "types.h"
#include "globj.h"
#include "vecmath.h"
#include "icosa.h"

static globj_t icosa = 
{ icosa_draw, icosa_delete, NULL, "icosa", NULL } ;

globj_class_t globj_class_icosa = 
{ icosa_init, icosa_factory, "icosa", NULL } ;

void icosa_init (void) {}

globj_t* icosa_factory ()
{
  return &icosa ;
}

void icosa_delete (globj_t* icosa) { } /* do nothing (static allocation) */

// The strange numbers X and Z are chosen so that the distance from the origin to any of the vertices of the icosahedron is 1.0.
#define X .525731112119133606 
#define Z .850650808352039932

// vertices of the icosahedron
static vector vdata[12] = {    
   {-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z},    
   {0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X},    
   {Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0} 
};

// how to link the vertices
static GLint tindices[20][3] = { 
   {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},    
   {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},    
   {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6}, 
   {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };

void icosa_draw (globj_t* dummy, glcam_t* dummy2) {
  GLfloat ico[4]=  { 1.0f, 0.0f, 0.0f, 0.7f };
  int i ;

  glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,ico);
  for (i = 0; i < 20; i++) {    
    
    /* those normals are orthogonal to faces*/
    vector n ;
    vector_computenormal 
      (&n,vdata[tindices[i][0]],vdata[tindices[i][1]],vdata[tindices[i][2]]) ;
    glNormal3dv((GLdouble*)&n);
    
    glBegin(GL_TRIANGLES);    
    glVertex3dv((GLdouble*)&vdata[tindices[i][0]]); 
    glVertex3dv((GLdouble*)&vdata[tindices[i][1]]); 
    glVertex3dv((GLdouble*)&vdata[tindices[i][2]]);    
    glEnd(); 
  }
}
