#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>

#include "../src/types.h"

#define MAPDIR "map/"
#define MAPNAME "mt_map"

#define FBUF_SIZE 1024*256

char *filebuf;

char filesig[] = 
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<map version=\"1.8\" tiledversion=\"1.8.2\" orientation=\"orthogonal\" renderorder=\"right-down\" width=\"256\" height=\"256\" tilewidth=\"32\" tileheight=\"32\" infinite=\"0\" nextlayerid=\"3\" nextobjectid=\"1\">\n"
" <tileset firstgid=\"1\" source=\"mt_tileset.tsx\"/>\n"
" <tileset firstgid=\"3\" source=\"mt_coll_tileset.tsx\"/>\n"
" <layer id=\"1\" name=\"Tiles\" width=\"256\" height=\"256\">\n"
"  <data encoding=\"csv\">";

char filesig2[] = 
"</data>\n"
" </layer>\n"
" <layer id=\"2\" name=\"Collision\" width=\"256\" height=\"256\">\n"
"  <data encoding=\"csv\">";

char tmpname[256];

int import_map(FILE *mapfile, FILE *outfile){
  int32_t fbuf_pos = 0;
  fread(filebuf, 1, FBUF_SIZE, mapfile);

  if(strncmp(filebuf, filesig, sizeof(filesig)-1)){
    printf("Error: Invalid file header.\n");
    return 1;
  }
  fbuf_pos += sizeof(filesig)-1;
  fprintf(outfile, "uint8_t %s_lyr0[256*256] = {", tmpname);
  int32_t datlen = strcspn(&filebuf[fbuf_pos], "<");
  fwrite(&filebuf[fbuf_pos], 1, datlen, outfile);
  fprintf(outfile, "\n};\n");
  fbuf_pos += datlen;

  if(strncmp(&filebuf[fbuf_pos], filesig2, sizeof(filesig2)-1)){
    printf("Error: Invalid file header.\n");
    return 1;
  }
  fbuf_pos += sizeof(filesig2)-1;
  fprintf(outfile, "uint8_t %s_lyr1[256*256] = {", tmpname);
  datlen = strcspn(&filebuf[fbuf_pos], "<");
  fwrite(&filebuf[fbuf_pos], 1, datlen, outfile);
  fprintf(outfile, "\n};\n");

  fprintf(outfile, "Map %s = {{%s_lyr0, %s_lyr1}, 256, 256,"
                   "{0, 0, NULL}, {0, NULL}};\n",
                    tmpname, tmpname, tmpname);

  return 0;
}

FILE *maps[100] = {NULL};

int import_maps(){
  int i;
  FILE *outfile = fopen(MAPDIR "maps_out.c", "w+");
  int nmaps = 0;
  if(!outfile){
    printf("Failed to open file \"" MAPDIR "maps_out.c\"\n");
    printf("Error : %d (%d)\n", errno, EINVAL); 
    return 1;
  }
  fprintf(outfile, "#include <stdint.h>\n#include \"../src/types.h\"\n");
  for(i = 0; i < 100; i++){
    snprintf(tmpname, 256, MAPDIR MAPNAME "%d.tmx", i);
    printf("Loading map \"%s\"...\n", tmpname);
    maps[i] = fopen(tmpname, "r");
    if(!maps[i]){
      printf("Failed to load map, stopping here\n");
      break;
    }
    snprintf(tmpname, 256, MAPNAME "%d", i);
    if(import_map(maps[i], outfile))
      return 0;
    nmaps++;
  }
  fprintf(outfile, "MapCollec mapcollec = {%d,{", nmaps);
  for(int i = 0; i < nmaps; i++){
    fprintf(outfile, "&" MAPNAME "%d,", i);
  }
  fprintf(outfile, "}};\n");
  fclose(outfile);
  return i;
}

void clean_maps(){
  for(int i = 0; i < 100; i++){
    if(maps[i])
      fclose(maps[i]);
  }
}

int main(){
  printf("===== Converter output =====\n");
  filebuf = malloc(FBUF_SIZE);
  if(!filebuf)
    return 1;
  if(!import_maps())
    return 1;

  clean_maps(); 
  free(filebuf);

  printf("===== Converter end =====\n");

  return 0;
}