/*!\file window.c
 *
 * \brief Démo GL4D
 *
 * \author Farès BELHADJ, amsi@up8.edu
 * \date May 15, 2024
 */
#include <stdlib.h>
#include <GL4D/gl4du.h>
#include <GL4D/gl4dh.h>
#include <GL4D/gl4duw_SDL2.h>
#include "animations.h"
#include "audioHelper.h"

/* Prototypes des fonctions statiques contenues dans ce fichier C. */
static void init(void);
static void quit(void);
static void resize(int w, int h);
static void keydown(int keycode);

/* Dans unzip/miniunz.c */
extern int muExtrFile1();
extern int muExtrFile2();

/*!\brief tableau contenant les animations sous la forme de timeline,
 * ce tableau se termine toujours par l'élémént {0, NULL, NULL,
 * NULL} */
static GL4DHanime _animations[] = {
  /* INTRO */
  { 1000, noir, NULL, NULL },
  { 9000, noir, huit, fondu },
  {11040, huit, NULL, NULL },
  { 4500, rouge, NULL, NULL },
  {  200, rouge, vert, fondu },
  {   20, vert, NULL, NULL },

  {16000, beep, NULL, NULL },
  { 8000, beep, spi, fondu },
  {10000, spi, NULL, NULL },
  { 2000, spi, beebegin, fondu },
  /* FIN INTRO */
  {27000, beebegin, NULL, NULL },
  { 500, beebegin, bee2, fondu },

  { 3000, bee2, NULL, NULL },
  { 1000, bee2, bee3, fondu },
  { 3000, bee3, NULL, NULL },
  { 1000, bee3, bee2, fondu },
  { 2000, bee2, NULL, NULL },
  { 1000, bee2, bee3, fondu },
  { 2500, bee3, NULL, NULL },
  /* {    0, NULL, NULL, NULL }, */

  {  500, bee3, bee4, fondu },
  /* //{5000, bee3, NULL, NULL }, */
  {12000, bee4, NULL, NULL },
  { 3000, bee4, bee5, fondu },
  { 7000, bee5, NULL, NULL },
  { 3000, bee5, bee6, fondu },
  { 2000, bee6, NULL, NULL },
  { 3000, bee6, bee7, fondu },
  { 4000, bee7, NULL, NULL },
  { 5000, bee6, credits, fondu },
  { 6200, credits, NULL, NULL },
  {    0, NULL, NULL, NULL } /* Toujours laisser à la fin */
};

/*!\brief dimensions initiales de la fenêtre */
static GLfloat _dim[] = {1920, 1080};

/*!\brief fonction principale : initialise la fenêtre, OpenGL, audio
 * et lance la boucle principale (infinie).
 */
int main(int argc, char ** argv) {
  muExtrFile1();
  muExtrFile2();
  if(!gl4duwCreateWindow(argc, argv, "bee2be", 
			 GL4DW_POS_UNDEFINED, GL4DW_POS_UNDEFINED, 
			 _dim[0], _dim[1],
			 GL4DW_RESIZABLE | GL4DW_SHOWN | GL4DW_FULLSCREEN_DESKTOP))
    return 1;
  SDL_GL_SetSwapInterval(1);
  SDL_ShowCursor(SDL_DISABLE);
  init();
  atexit(quit);
  gl4duwResizeFunc(resize);
  gl4duwKeyDownFunc(keydown);
  gl4duwDisplayFunc(gl4dhDraw);

  ahInitAudio("audio/dreamer_dream.mod");
  gl4duwMainLoop();
  return 0;
}

/*!\brief Cette fonction initialise les paramètres et éléments OpenGL
 * ainsi que les divers données et fonctionnalités liées à la gestion
 * des animations.
 */
static void init(void) {
  glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
  gl4dhInit(_animations, _dim[0], _dim[1], animationsInit);
  resize(_dim[0], _dim[1]);
}

/*!\brief paramétre la vue (viewPort) OpenGL en fonction des
 * dimensions de la fenêtre.
 * \param w largeur de la fenêtre.
 * \param w hauteur de la fenêtre.
 */
static void resize(int w, int h) {
  _dim[0] = w; _dim[1] = h;
  glViewport(0, 0, _dim[0], _dim[1]);
}

/*!\brief permet de gérer les évènements clavier-down.
 * \param keycode code de la touche pressée.
 */
static void keydown(int keycode) {
  switch(keycode) {
  case SDLK_ESCAPE:
  case 'q':
    exit(0);
  default: break;
  }
}

/*!\brief appelée à la sortie du programme (atexit).
 */
static void quit(void) {
 ahClean(1000);
 SDL_ShowCursor(SDL_ENABLE);
 gl4duClean(GL4DU_ALL);
}
