/*-----------------------------------------------------------------------------
Bibliotheque minimaliste de manipulation d'une image
Public vise : etudiants de 1ere annee universitaire
Christian Nguyen - 2011
-----------------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <gd.h>
#include "utv_gd.h"

static gdImagePtr image; /* l'image principale */
static int imw, imh;     /* sa taille w x h */
static int cas;          /* la taille de chaque case (1 pour 1 pixel) */

static int couleur[NBCOUL];

/* les sprites utilises dans le programme (max 20) */
#define NBSPRITE 20
static gdImagePtr sprite[NBSPRITE];
static int spn = 0;

/*---------------------------------------------------------------------------*/
/* affiche l'image suivante (version 1) */
void utv_gd_image_suivante_bis(void)
{
  /* int errsys; */
  FILE* out = fopen("imtmp.png", "wb"); /* fichier binaire de sortie */

  /* ecriture d'une image au format PNG */
  gdImagePng(image, out);
  /* fermeture du fichier */
  fclose(out);
  /* tentative de "synchronisation" avec "display -update 1" */
  (void) sleep(1);
}

/*---------------------------------------------------------------------------*/
/* affiche l'image suivante (version 2) */
void utv_gd_image_suivante(void)
{
  static int nim = 10; /* indice image */
  char nb[3];
  char nomfic[18] = "/tmp/imtmp";
  FILE* out;
  
  /* conversion d'un nombre en chaine de caractere */
  sprintf(nb, "%d", nim);
  strcat(nomfic, nb);
  strcat(nomfic, ".png");

  /* indice de la prochaine image */
  nim++;

  /* ecriture dans un fichier de l'image creee */
  out = fopen(nomfic, "wb");
  gdImagePng(image, out);
  fclose(out);
}

/*---------------------------------------------------------------------------*/
/* cree une case de couleur pc, de taille cas x cas, en (px, py) */
void utv_gd_case_couleur(int px, int py, int pc)
{
  gdImageFilledRectangle(image, px*cas, py*cas, px*cas+cas, py*cas+cas, pc);
}

/*---------------------------------------------------------------------------*/
/* retourne la couleur du centre d'une case, de taille cas x cas, en (px, py) */
int utv_gd_case_quelle_couleur(int px, int py)
{
  if (px<0 || px>=imw || py<0 || py>=imh) {
    fprintf(stderr, "Coordonnee hors dimension\n");
    return -1;
  }
  /* correspond aux coordonnees (30, 30) pour une case de 60 de cote */
  return gdImageGetPixel(image, px*cas+cas/2, py*cas+cas/2);
}

/*---------------------------------------------------------------------------*/
/* ajoute un objet graphique decrit dans un fichier de nom pnom */
void utv_gd_ajouter_objet(int i, const char* pnom)
{
  FILE* in;

  if (i<0 || i>=NBSPRITE) {
    fprintf(stderr, "Objet non ajoute (depassement de capacite)\n");
  } else {
    ++spn;
    in = fopen(pnom, "rb");
    sprite[i] = gdImageCreateFromPng(in);
    fclose(in);
  }
}

/*---------------------------------------------------------------------------*/
/* creer un objet graphique de taille cas x cas en (x, y) */
void utv_gd_case_objet(int px, int py, int ps)
{
  if (sprite[ps] == NULL || ps > spn) {
    fprintf(stderr, "Objet non affiche dans la case (%d, %d)\n", px, py);
  } else {
    gdImageSetTile(image, sprite[ps]);
    gdImageFilledRectangle(image, px*cas, py*cas, px*cas+cas, py*cas+cas, gdTiled);
  }
}

/*---------------------------------------------------------------------------*/
/* retourne la couleur d'un pixel */
int utv_gd_quelle_couleur(int px, int py)
{
  return gdImageGetPixel(image, px, py);
}

/*---------------------------------------------------------------------------*/
/* ajoute une couleur a la volee a la palette des couleurs */
/* -1 en cas d'echec */
int utv_gd_ajouter_couleur(int r, int v, int b)
{
  return gdImageColorAllocate(image, r, v, b);
}

/*---------------------------------------------------------------------------*/
/* initialisation du systeme graphique */
void utv_gd_initialisation(int pw, int ph, int pt)
{
  int i;
  /* int sysret; */

  /* image de wxh pixels */
  imw = pw;
  imh = ph;
  image = gdImageCreate(pw, ph);

  /* taille de chaque case (1 possible pour 1 pixel) */
  cas = pt;

  /* allocation de la palette des couleurs */
  /* couleur d'arriere plan car 1ere couleur */
  couleur[blanc] = gdImageColorAllocate(image, 255, 255, 255);
  /* les autres couleurs */
  couleur[noir] = gdImageColorAllocate(image, 0, 0, 0);
  couleur[gris] = gdImageColorAllocate(image, 127, 127, 127);
  couleur[rouge] = gdImageColorAllocate(image, 255, 0, 0);
  couleur[orange] = gdImageColorAllocate(image, 255, 165, 0);
  couleur[jaune] = gdImageColorAllocate(image, 255, 255, 0);
  couleur[vert] = gdImageColorAllocate(image, 0, 255, 0);
  couleur[bleu] = gdImageColorAllocate(image, 0, 0, 255);
  couleur[indigo] = gdImageColorAllocate(image, 121, 28, 248);
  couleur[violet] = gdImageColorAllocate(image, 160, 32, 240);

  /* initialisation a NULL du tableau de sprites */
  for (i = 0 ; i < 20 ; ++i)
    sprite[i] = NULL;

  /* reset de l'image */
  /* utv_gd_image_suivante(); */
  /* sysret = system("/usr/bin/display -update 1 imtmp.png&"); */
  /* if (sysret == -1) { */
  /*   fprintf(stderr, "probleme a l'affichage de la fenetre graphique\n"); */
  /*   exit(1); */
  /* } */
}

/*---------------------------------------------------------------------------*/
/* avant de quitter le programme */
void utv_gd_quitter()
{
  int errsys;

  gdImageDestroy(image);
  errsys = system("/usr/bin/animate -delay 50 /tmp/imtmp*.png");
  errsys = system("/bin/rm /tmp/imtmp*.png");
  if (errsys == -1) {
    fprintf(stderr, "Fatal system error\n");
    fprintf(stderr, "Exit program\n");
    exit(1);
  }
}
