/* Modelisation OpenGL d'une scene              */
/* composee de spheres et de cylindres          */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Septembre 2012                               */

#include <stdio.h>
#include <math.h>

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include "Modules/ModuleCylindres.h"
#include "Modules/ModuleAxes.h"

/* Constantes globales                          */

const static float blanc[] = { 1.0F,1.0F,1.0F,1.0F };
const static float rouge[] = { 1.0F,0.0F,0.0F,1.0F };
const static float vert[] = { 0.0F,1.0F,0.0F,1.0F };
const static float bleu[] = { 0.0F,0.0F,1.0F,1.0F };
const static float magenta[] = { 1.0F,0.0F,1.0F,1.0F };
const static float grisMoyen[] = { 0.5F,0.5F,0.5F,1.0F };
const static float blancTransparent[] = { 1.0F,1.0F,1.0F,0.5F };
const static float rougeTransparent[] = { 1.0F,0.0F,0.0F,0.5F };
const static float vertTransparent[] = { 0.0F,1.0F,0.0F,0.5F };
const static float bleuTransparent[] = { 0.0F,0.0F,1.0F,0.5F };
const static float magentaTransparent[] = { 1.0F,0.0F,1.0F,0.5F };
const static float jauneTransparent[] = { 1.0F,1.0F,0.0F,0.25F };

/* Scene dessinee                               */

static void wireElement(void) {
  glPushMatrix();
  glTranslatef(4.5F,0.0F,4.5F);
  wireCylindre(0.8F,5.3F,10,5);
  for ( int i = 0 ; i < 2 ; i++ ) {
    glTranslatef(0.0F,4.5F,0.0F);
    glPushMatrix();
    glRotatef(60.0F,-1.0F,1.0F,1.0F);
    glutWireSphere(2.0,16,8);
    glPopMatrix();
    glRotatef(90.0F,0.0F,0.0F,1.0F);
    glTranslatef(0.0F,4.5F,0.0F);
    wireCylindre(0.8F,5.3F,10,5); }
  glPopMatrix();
  glColor4fv(magenta);
  glPushMatrix();
  glTranslatef(7.8F,0.0F,0.0F);
  glutWireSphere(2.0,10,10);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(-7.8F,0.0F,0.0F);
  glutWireSphere(2.0,10,10);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(0.0F,7.8F,0.0F);
  glutWireSphere(2.0,10,10);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(0.0F,-7.8F,0.0F);
  glutWireSphere(2.0,10,10);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(0.0F,0.0F,7.8F);
  glutWireSphere(2.0,10,10);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(0.0F,0.0F,-7.8F);
  glutWireSphere(2.0,10,10);
  glPopMatrix();
}

static void solidElement(void) {
  glPushMatrix();
  glTranslatef(4.5F,0.0F,4.5F);
  solidCylindre(0.8F,5.3F,36,36);
  for ( int i = 0 ; i < 2 ; i++ ) {
    glTranslatef(0.0F,4.5F,0.0F);
    glutSolidSphere(2.0,36,36);
    glRotatef(90.0F,0.0F,0.0F,1.0F);
    glTranslatef(0.0F,4.5F,0.0F);
    solidCylindre(0.8F,5.3F,36,36); }
  glPopMatrix();
  glMaterialfv(GL_FRONT,GL_DIFFUSE,magentaTransparent);
  glPushMatrix();
  glTranslatef(7.8F,0.0F,0.0F);
  glutSolidSphere(2.0,36,36);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(-7.8F,0.0F,0.0F);
  glutSolidSphere(2.0,36,36);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(0.0F,7.8F,0.0F);
  glutSolidSphere(2.0,36,36);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(0.0F,-7.8F,0.0F);
  glutSolidSphere(2.0,36,36);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(0.0F,0.0F,7.8F);
  glutSolidSphere(2.0,36,36);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(0.0F,0.0F,-7.8F);
  glutSolidSphere(2.0,36,36);
  glPopMatrix();
}

static void wireScene(void) {
  glPushMatrix();
  glDisable(GL_LIGHTING);
  glColor4fv(rouge);
  wireElement();
  for ( int i = 1 ; i < 4 ; i++ ) {
    glPushMatrix();
    glRotatef(90.0F*i,1.0F,0.0F,0.0F);
    switch (i) {
      case 1 : glColor4fv(vert);
               break;
      case 2 : glColor4fv(blanc);
               break;
      case 3 : glColor4fv(bleu);
               break; }
    wireElement();
    glPopMatrix(); }
  glPopMatrix();
}

static void solidScene(void) {
  glEnable(GL_CULL_FACE);
  glEnable(GL_LIGHTING);
  glPushMatrix();
  glMaterialfv(GL_FRONT,GL_DIFFUSE,rougeTransparent);
  solidElement();
  for ( int i = 1 ; i < 4 ; i++ ) {
    glPushMatrix();
    glRotatef(90.0F*i,1.0F,0.0F,0.0F);
    switch (i) {
      case 1 : glMaterialfv(GL_FRONT,GL_DIFFUSE,vertTransparent);
               break;
      case 2 : glMaterialfv(GL_FRONT,GL_DIFFUSE,blancTransparent);
               break;
      case 3 : glMaterialfv(GL_FRONT,GL_DIFFUSE,bleuTransparent);
               break; }
    solidElement();
    glPopMatrix(); }
  glMaterialfv(GL_FRONT,GL_DIFFUSE,jauneTransparent);
  glutSolidSphere(10.0,72,72);
  glPopMatrix();
  glDisable(GL_CULL_FACE);
}

void scene(void) {
  glPushMatrix();
  dessinAxes();
  glRotatef(90.0F,0.0F,0.0F,1.0F);
  wireScene();
  solidScene();
  glPopMatrix();
}
