/* Auteur: Nicolas JANEY              */
/* nicolas.janey@univ-fcomte.fr       */
/* Avril 2010                         */
/* Un manipulateur souris et clavier  */

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

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

#include "ModuleFly.h"

#define UNREFERENCED_PARAMETER(P) (P)

static float *px;
static float *py;
static float *pz;
static float *dir;
static float *vitesse;
static int modifier;
static int button;
static int mpx;
static int mpy;
static int mouvement;

static fonctionVoid fonctionUpdate = NULL;

static int getModifier() {
  int modif = 0;
  if ( ( (glutGetModifiers() & GLUT_ACTIVE_CTRL) != 0 ) && ( (glutGetModifiers() & GLUT_ACTIVE_ALT) != 0 ) )
    return(5);
  if ( (glutGetModifiers() & GLUT_ACTIVE_SHIFT) != 0 ) {
    if ( (glutGetModifiers() & GLUT_ACTIVE_CTRL) != 0 )
      modif = 2;
      else
      modif = 1; }
    else
    if ( (glutGetModifiers() & GLUT_ACTIVE_CTRL) != 0 )
      modif = 3;
      else
      if ( (glutGetModifiers() & GLUT_ACTIVE_ALT) != 0 )
        modif = 4;
  return(modif);
}

void mouseFly(int bouton,int etat,int x,int y) {
  button = bouton;
  if ( bouton == GLUT_LEFT_BUTTON ) {
    modifier = getModifier();
    if ( modifier ) {
      mpx = x ;
      mpy = y ; 
      if ( etat == GLUT_DOWN ) {
        mouvement = 1 ;}
      if ( etat == GLUT_UP ) {
        mouvement = 0 ; } } }
}

void motionFly(int x,int y) {
  switch ( button ) {
    case GLUT_LEFT_BUTTON : 
      if ( mouvement == 1 ) {
        switch ( modifier ) {
          case 1 :
           *dir += (mpx-x)/3.0F;
           *px += *vitesse*cos((*dir-90.0)*3.14159/180.0)*(mpy-y);
           *py += *vitesse*sin((*dir-90.0)*3.14159/180.0)*(mpy-y);
            mpx = x; 
            mpy = y;
            if ( fonctionUpdate )
              fonctionUpdate();
            break; } } }
}

void keyboardFly(unsigned char key,int x,int y) {
  UNREFERENCED_PARAMETER(x);
  UNREFERENCED_PARAMETER(y);
  modifier = getModifier();
  if ( modifier == 1 ) {
    switch (key) {
      case 'x' :
        *px += *vitesse*cos((*dir-90.0)*3.14159/180.0);
        *py += *vitesse*sin((*dir-90.0)*3.14159/180.0);
        if ( fonctionUpdate )
          fonctionUpdate();
        break;
      case 'X' : 
        *px -= *vitesse*cos((*dir-90.0)*3.14159/180.0);
        *py -= *vitesse*sin((*dir-90.0)*3.14159/180.0);
        if ( fonctionUpdate )
          fonctionUpdate();
        break;
      case 'y' : 
        *dir -= 1.0F;
        if ( fonctionUpdate )
          fonctionUpdate();
        break;
      case 'Y' :
        *dir += 1.0F;
        if ( fonctionUpdate )
          fonctionUpdate();
        break; } }
}

void specialFly(int k, int x, int y) {
  UNREFERENCED_PARAMETER(x);
  UNREFERENCED_PARAMETER(y);
  modifier = getModifier();
  if ( modifier == 1 ) {
    switch (k) {
      case GLUT_KEY_UP :
        *px += *vitesse*cos((*dir-90.0)*3.14159/180.0);
        *py += *vitesse*sin((*dir-90.0)*3.14159/180.0);
        if ( fonctionUpdate )
          fonctionUpdate();
        break;
      case GLUT_KEY_DOWN : 
        *px -= *vitesse*cos((*dir-90.0)*3.14159/180.0);
        *py -= *vitesse*sin((*dir-90.0)*3.14159/180.0);
        if ( fonctionUpdate )
          fonctionUpdate();
        break;
      case GLUT_KEY_LEFT : 
        *dir -= 1.0F;
        if ( fonctionUpdate )
          fonctionUpdate();
        break;
      case GLUT_KEY_RIGHT :
        *dir += 1.0F;
        if ( fonctionUpdate )
          fonctionUpdate();
        break; } }
}

void setPositionsFly(float *pxFly,float *pyFly,float *pzFly) {
  px = pxFly;
  py = pyFly;
  pz = pzFly;
}

void setVitesseFly(float *vitesseFly) {
  vitesse = vitesseFly;
}

void setDirectionFly(float *dirFly) {
  dir = dirFly;
}

void setFonctionUpdate(fonctionVoid fonction) {
  fonctionUpdate = fonction;
}
