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

#include <SDL/SDL.h>
/* P.K. */
#include "macros.h"
#include "types.h"
#include "common.h"

#include "main.h" // danslemenu !! move to common.c

/* Various languages localization */
#include <locale.h>
#include <libintl.h>


SDL_Rect spr_rect;
Sprite *couleurs;
Sprite *sol, *bloc, *mur, *fleche, *teleport, *tunnel, *bouton, *fontaine;
//Sprite *sol, *bloc, *mur, *fleche, *teleport, *tunnel, *bouton, *hiddenbouton, *fontaine;
Sprite *bombe, *flammes, *bonus, *etoiles;
Sprite *sprit[8], *fauxsprit[MAX_NPERSO];//, *troll, *barbare, *magus, *citrouille;
//xSprite *tous_les_sprites[256];
Sprite *tous_les_sprites[MAX_STRING_LENGTH];
int nsprites;

int decl=0;


/*--Affiche un sprite à l'écran--*/
void blitsprit(Sprite *spr, int anim, int frame, int x, int y)
{
  //x  int i, j, pix, loc = x + y*640;
  //?  int i, j, pix, loc = x + y*window_width;
  int i, j, pix;
  int decal = danslemenu ? 64 : 0;
  Uint8 *framept;
  int local_x_offset = resolution.x_offset+x+decal; // where to move origin?
  int local_y_offset = resolution.y_offset+y;
  int loc = local_x_offset + local_y_offset*resolution.window_width;
  //?  int loc = x_offset+x + (y_offset+y)*window_width;

  if (spr==NULL || 
      anim>=spr->nanims ||
      frame>=spr->anims[anim]->nframes) return;

  framept=spr->anims[anim]->frame[frame];

  VERROUILLE;
  for (i=0; i<32; i++) {
    //x    if (0 <= y+i+decal && y+i < 480)
    //?    if (0 <= y+i+decal && y+i < window_height)
    if (0 <= local_y_offset+i && local_y_offset+i < resolution.window_height)
      for (j=0; j<32; j++) {
	//x	if (0 <= x+j+decal && x+j<640 && framept[i*32+j]) {
	//?	if (0 <= x+j+decal && x+j < window_width && framept[i*32+j]) {
	if (0 <= local_x_offset+j && local_x_offset+j < resolution.window_width && framept[i*32+j]) {
	  //x	  pix=loc+i*640+(j+decal);
	  pix = loc+i*resolution.window_width+j;
	  ((Uint8 *)ecran->pixels)[pix] = framept[i*32+j];
	}
      }
  }
  DEVERROUILLE;
  
  return;
}


animation  * cree_animation(int nb_frames)
{
  int i;
  animation *anim;
  anim = (animation *)malloc(sizeof(animation));
  anim->nframes = nb_frames;
  anim->frame = (Uint8 **)calloc(nb_frames, sizeof *anim->frame);
  for (i=0; i<nb_frames; i++) {
    anim->frame[i] = (Uint8 *)malloc(1024);
    memset(anim->frame[i], 0, 1024); }
  return(anim);
}

Sprite * cree_sprite(int nb_anims, int decal, int nb_coul)
{
  Sprite *spri;
  spri = (Sprite *)malloc(sizeof(Sprite));
  spri->nanims   = nb_anims;
  spri->decalage = decal;
  spri->anims    = (animation **)calloc(nb_anims, sizeof *spri->anims);
  spri->palette  = (SDL_Palette *)malloc(sizeof(SDL_Palette));
  spri->palette->colors  = (SDL_Color *)calloc(50, sizeof spri->palette->colors);
  memset(spri->palette->colors, 0, 30*3);
  spri->palette->ncolors = nb_coul;
  spri->nom      = NULL;
  return spri;
}


void detruit_sprite(Sprite *spr)
{
  int i, j;
  for (i=0; i<spr->nanims; i++)
    {
      for (j=0; j<spr->anims[i]->nframes; j++)
	free(spr->anims[i]->frame[j]);
      free(spr->anims[i]->frame);
      free(spr->anims[i]);
    }
  free(spr->anims);
  free(spr->palette->colors);
  free(spr->palette);
  if (spr->nom) free(spr->nom);
  free(spr);
}


void detruit_sprites(void)
{
  int i;
  for (i=0; i<nsprites; i++)
      detruit_sprite(tous_les_sprites[i]);
  nsprites=0;
  decl=0;
  return;
}


Sprite * charge_sprite(const char *nom, int decalage)
{
  char chemin[256];
  int i, j, k;
  unsigned int nanims, ncoul;
  unsigned int pix;
  unsigned char lect;
  Uint8  *pal;
  Uint8  *fr;
  Sprite *spr;
  FILE   *spr_fich;
  
  sprintf(chemin, "%s/%s", prefixespr, nom);
  spr_fich = fopen(chemin, "rb");
  if (spr_fich == NULL)
    //x    erreur("Impossible de charger le sprite", chemin);
    errormessage(gettext("Impossible de charger le sprite"), chemin);
  fread(&lect, 1, 1, spr_fich);
  ncoul=lect;
  fread(&lect, 1, 1, spr_fich);
  nanims=lect;

  spr = cree_sprite(nanims, decalage, ncoul);
  fr  = (Uint8 *)malloc(1024);
  pal = (Uint8 *)malloc(3*ncoul);

  spr->nom=strdup(nom);
  strcpy(strstr(spr->nom, ".spr"),"\0");
  //  spr->nom[0]=toupper(spr->nom[0]);

  /* D'abord on lit la palette */

  if (fread(pal, 3, ncoul, spr_fich)!= ncoul)
    //x    erreur("La palette du sprite est corrompue", chemin);
    errormessage(gettext("La palette du sprite est corrompue"), chemin);
  for (i=0; i<ncoul; i++)
    {
      spr->palette->colors[i].r = *(pal+3*i);
      spr->palette->colors[i].g = *(pal+3*i+1);
      spr->palette->colors[i].b = *(pal+3*i+2);
    }
  free(pal);

  /* Puis les anims */
  
  for (i=0; i<nanims; i++)
    {
      int nframes;
      fread(&lect, 1, 1, spr_fich);
      nframes=lect;
      spr->anims[i] = cree_animation(nframes);
      for (j=0; j<nframes; j++)
	{
	  if (fread(fr, 1, 1024, spr_fich)!=1024)
	    //x	    erreur("Le contenu du sprite est corrompu", chemin);
	    errormessage(gettext("Le contenu du sprite est corrompu"), chemin);
	  for (k=0; k<1024; k++)
	    {
	      if (fr[k]) {
		pix = fr[k] + decalage;
		if (pix>255) 
		  //x		  erreur("Le nombre de couleurs allouées par le programme dépasse la palette", chemin); }
		  errormessage(gettext("Le nombre de couleurs allouées par le programme dépasse la palette"), chemin); }
	      else
		pix = 0;
	      spr->anims[i]->frame[j][k] = pix;
	    }
	}
    }
  free(fr);
  fclose(spr_fich);
  SDL_SetColors(ecran, spr->palette->colors, decalage+1, spr->palette->ncolors);
  decl += spr->palette->ncolors;
  tous_les_sprites[nsprites]=spr;
  nsprites++;
  return spr;
}


void charge_graphs(FILE *niveau)
{
  char nom[256];

  //printf("Chargement des décors...");

  if(fscanf(niveau, "sol: %s\n", nom))
    sol      = charge_sprite(nom, decl);
  if(fscanf(niveau, "bloc: %s\n", nom)) 
    bloc     = charge_sprite(nom, decl);
  if(fscanf(niveau, "mur: %s\n", nom))
    mur      = charge_sprite(nom, decl);
  if(fscanf(niveau, "fleche: %s\n", nom)) 
    fleche   = charge_sprite(nom, decl);
  if(fscanf(niveau, "teleport: %s\n", nom)) 
    teleport = charge_sprite(nom, decl);
  if(fscanf(niveau, "tunnel: %s\n", nom))
    tunnel   = charge_sprite(nom, decl);
  if(fscanf(niveau, "bouton: %s\n", nom)) 
    bouton   = charge_sprite(nom, decl);
  if(fscanf(niveau, "fontaine: %s\n", nom)) 
    fontaine = charge_sprite(nom, decl);

  bombe    = charge_sprite("bombe.spr", decl);
  flammes  = charge_sprite("flammes.spr", decl);
  bonus    = charge_sprite("bonus.spr", decl);
  etoiles  = charge_sprite("etoiles.spr", decl);

  //printf("OK. %i couleurs allouées.\n", decl);

  return;
}


void charge_sprites(Sprite **sprites, char **spritliste, int n)
{
  int i;
  for (i=0; i<n; i++)
    {
      sprites[i] = charge_sprite(spritliste[i], decl);
    }
  return;
}
