#include <GL/glut.h>
#include <libio.h>
#include <math.h>
#include <stdlib.h>
static void draw(void);

typedef struct 
{
  float x;
  float y;
  float deltax;
  float deltay;
} pointm;

typedef struct
{
  pointm point1;
  pointm point2;
} lignem;
int cptLignes=0;
lignem* lesLignes;


// Initialisation du tableau de lignes

void init_lesLignes(void)
{
  lignem l;
  pointm p1,p2;
  /* Initialisation de la ligne */
  p1.x=0.0;
  p1.y=0.0;
  p1.deltax=0.0001;
  p1.deltay=-0.0003;
  p2.x=0.2;
  p2.y=0.5;
  p2.deltax=0.0005;
  p2.deltay=0.0002;
  l.point1=p1;
  l.point2=p2;
  lesLignes=(lignem*)malloc(sizeof(lignem));
  lesLignes[0]=l;
  cptLignes++;
}

void ajouterLigne(void)
{
  int i;
  lignem l;
  pointm p1,p2;
    /* Initialisation de la ligne */
  p1.x=0.0;
  p1.y=0.0;
  p1.deltax=0.0001;
  p1.deltay=-0.0003;
  p2.x=0.2;
  p2.y=0.5;
  p2.deltax=0.0005;
  p2.deltay=0.0002;
  l.point1=p1;
  l.point2=p2;
  // on cree un tableau de taille i+1
  cptLignes++; 
  lignem* lesLignesTemp=(lignem*)calloc(cptLignes,sizeof(lignem));
  for (i=0;i<cptLignes-1;i++) lesLignesTemp[i]=lesLignes[i];
  lesLignesTemp[cptLignes-1]=l;
  free(lesLignes);
  //lesLignes=(lignem*)malloc(sizeof(lignem));//(lignem*)calloc(cptLignes,sizeof(lignem));
  lesLignes=(lignem*)calloc(cptLignes,sizeof(lignem));
  lesLignes=lesLignesTemp;
}

void retirerLigne(void)
{
  if (cptLignes>1) cptLignes--;
}


static void key(unsigned char touche, int x, int y)
{
/* Fonction appelée lorsque l'utilisateur presse une touche "normale" */
  printf("touche %d appuyee\n",touche);
	switch (touche) {  
	case 27:	/* touche escape */
	  exit(0);break;
	case 43:
	     ajouterLigne();
	     break;
	case 45:
	  retirerLigne();
	  break;
	}
}

static void specialKey(int touche, int x, int y)
{
/* Fonction correspondant aux touches spécial (Up, Down, Left, Right, Page_Up, ...) */
}



void bouge(void)
{
  int i;
  //printf("bouge\n");
  for (i=0;i<cptLignes;i++)
    {
      lesLignes[i].point1.x+=lesLignes[i].point1.deltax;
      lesLignes[i].point1.y+=lesLignes[i].point1.deltay;
      lesLignes[i].point2.x+=lesLignes[i].point2.deltax;
      lesLignes[i].point2.y+=lesLignes[i].point2.deltay;
      if ( (lesLignes[i].point1.x<=-1) || (lesLignes[i].point1.x>=1) ) lesLignes[i].point1.deltax=-lesLignes[i].point1.deltax;  
      if ( (lesLignes[i].point1.y<=-1) || (lesLignes[i].point1.y>=1) ) lesLignes[i].point1.deltay=-lesLignes[i].point1.deltay; 
      if ( (lesLignes[i].point2.x<=-1) || (lesLignes[i].point2.x>=1) ) lesLignes[i].point2.deltax=-lesLignes[i].point2.deltax;  
      if ( (lesLignes[i].point2.y<=-1) || (lesLignes[i].point2.y>=1) ) lesLignes[i].point2.deltay=-lesLignes[i].point2.deltay; 
      //printf("jai bouge %d",i);
    }
  glutPostRedisplay();
  
}

static void draw(void)
{
  int i;
  //while(1)
   // {
      glClear(GL_COLOR_BUFFER_BIT);
            /* Fonction d'affichage */
      /* Ici intervient le code decrivant l'affichage */
      glColor3f(1.0,1.0,1.0);
      glLineWidth(3.5);
      for (i=0;i<cptLignes;i++)
	{
	  //printf("je dessine la ligne %d \n",i);
	  glBegin(GL_LINES);
	  glVertex2f(lesLignes[i].point1.x,lesLignes[i].point1.y);
	  glVertex2f(lesLignes[i].point2.x,lesLignes[i].point2.y);
	  glEnd();
	}
      glFlush();
    //}
}

static void idle(void)
{
  //printf("idle\n");
}

static void visible(int vis)
{
	if (vis == GLUT_VISIBLE)
		glutIdleFunc(bouge);
	else
		glutIdleFunc(NULL);
}

static void mouseFunc(int button, int state, int x, int y)
{
/* Fonction appelée lorsque l'une des touches de la souris change d'état:
 * Touche possible : GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON & GLUT_RIGHT_BUTTON.
 * Etat possible : GLUT_DOWN & GLUT_UP.
 * x et y correspondent aux coordonnées x et y de la souris.
 */
}

static void MotionFunc(int x, int y)
{
/* Fonction appelée lorsque l'utilisateur bouge la souris alors qu'une de ses touche est appuyée */
}

int main(int argc, char *argv[])
{
/* Initialisation de glut */
	glutInit(&argc, argv);
/* definition de la position de la fenetre */
	glutInitWindowPosition(0, 0);
	glutInitWindowSize(600, 600);
/* Creation du contexte OpenGL en mode indexé et simple buffer à l'interieur de la fenetre */
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
/* Affichage de la fenetre */
	glutCreateWindow("Squelette");
/* Affichage plein ecran */
//	glutFullScreen();
/* Initialisation des differentes fonctions de callbacks */
	glutDisplayFunc(draw);
	glutVisibilityFunc(visible);
	glutKeyboardFunc(key);
	glutSpecialFunc(specialKey);
	glutMouseFunc(mouseFunc);
	glutMotionFunc(MotionFunc);

/* Initialisation de differents paramètres OpenGL */
	glDrawBuffer(GL_FRONT);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
	glMatrixMode(GL_MODELVIEW);


/* Lancement de la boucle principale de traitement d'OpenGL. */
	init_lesLignes();
	glutMainLoop();
/* Le return n'est jamais appele, car la glutMainLoop ne retourne jamais !
 * Sa presence permet cependant d'éviter que le compilateur n'affiche un warning ...
 */
	return 0;
}
