#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "ecriture.h"

void ajoute_desc(struct cell_link *c, char *desc_no, char *desc_tag)
{
    char tmp[500];
    /* no */
    sprintf(tmp, "%lu,", c->link->no + 1);
    strcat(desc_no, tmp);

    /* tag */
    sprintf(tmp, "%d,", c->tag);
    strcat(desc_tag, tmp);
}

int genere_fichier(char *nom_fichier,
                   int total_cellules,
                   int total_liens,
                   struct cell *tabcell,
                   unsigned long taille_x, unsigned long taille_y,
                   unsigned long taille_z, char *buffer_erreur,
                   int maxlen_erreur)
{
    FILE *houtput;
    int i, j;
    time_t mytime;
    struct tm mytm;
    struct cell *c;
    char desc_no[500];
    char desc_tag[500];

    /* variable de retour, par défaut = ok */
    int ret = 0;

    /* ouverture ecriture fichier */
    houtput = fopen(nom_fichier, "wb+");
    if (houtput == NULL) {
        snprintf(buffer_erreur, maxlen_erreur,
                 "Erreur d'ouverture en écriture du fichier <%s>.\n",
                 nom_fichier);
        return -1;
    }

    time(&mytime);
    localtime_r(&mytime, &mytm);

    fprintf(houtput, "; -------------------------------\n");
    fprintf(houtput,
            "; fichier généré le %d/%d/%d à %02d:%02d:%02d\n\n",
            mytm.tm_mday, mytm.tm_mon + 1, mytm.tm_year + 1900,
            mytm.tm_hour, mytm.tm_min, mytm.tm_sec);

    fprintf(houtput, "; -------------------------------\n");
    fprintf(houtput,
            "; nombre de cellules et de liens composant le labyrinthe\n");
    fprintf(houtput, ";\n");
    fprintf(houtput, "total_cells:%d\n", total_cellules);
    fprintf(houtput, "total_links:%d\n\n", total_liens);
    fprintf(houtput, "; -------------------------------\n");
    fprintf(houtput, "; dll à appeler pour générer le fichier\n");
    fprintf(houtput, "maze_type:carre_classique\n");
    fprintf(houtput, "\n");

    fprintf(houtput, "; -------------------------------\n");
    fprintf(houtput, "; informations supplémentaires\n");
    fprintf(houtput,
            "; utilisées spécifiquement en fonction du labyrinthe :\n");
    fprintf(houtput,
            "; (si plusieurs fois params alors c'est concaténé\n"
            ";  avec un espace au milieu) :\n");
    fprintf(houtput, ";\n");
    fprintf(houtput, "params:largeur=%lu\n", taille_x);
    fprintf(houtput, "params:longueur=%lu\n", taille_y);
    fprintf(houtput, "params:hauteur=%lu\n", taille_z);
    fprintf(houtput, "params:1=25\n");
    fprintf(houtput, "params:2=25\n");
    fprintf(houtput, "params:3=25\n");
    fprintf(houtput, "params:4=25\n");
    fprintf(houtput, "params:5=100000000\n");
    fprintf(houtput, "\n");

    fprintf(houtput, "; -------------------------------\n");
    fprintf(houtput, "; avant de construire le labyrinthe :\n");
    fprintf(houtput, "; forcer des chemins ou des murs.\n");
    fprintf(houtput, "; syntaxe :\n");
    fprintf(houtput,
            "; - force_paths:{ no cellule  } = { no lien à forcer en path }\n");
    fprintf(houtput,
            "; - force_walls:{ no cellule  } = { no lien à forcer en wall }\n");
    fprintf(houtput, ";\n");
    for (i = 0; i < total_cellules; i++) {
        c = &tabcell[i];
        for (j = 0; j < c->nb_paths; j++) {
            fprintf(houtput, "force_paths:%lu=%lu\n", c->no + 1,
                    c->paths[j].link->no + 1);
        }
        for (j = 0; j < c->nb_walls; j++) {
            fprintf(houtput, "force_walls:%lu=%lu\n", c->no + 1,
                    c->walls[j].link->no + 1);
        }
    }
    fprintf(houtput, "\n");
    /* (!) RAF : prendre en compte les paramètres 
       'nombre de cases de départ possibles',
       ici codé temporairement en dur : */
    fprintf(houtput, "; -------------------------------\n");
    fprintf(houtput, "; cases de départ/entrée possibles :\n");
    fprintf(houtput, ";\n");
    fprintf(houtput, "begin_nb_cells_min:1\n");
    fprintf(houtput, "begin_nb_cells_max:1\n");
    fprintf(houtput, "\n");
    /* lister toutes les cases de départ possibles
       (!) RAF : prendre en compte les paramètres !
       ici codé temporairement en dur : */
    fprintf(houtput, "; cases de départ/entrée possibles :\n");
    for (i = 0; i < total_cellules; i++) {
        fprintf(houtput, "b:%d\n", i + 1);
    }

    fprintf(houtput, "\n");
    /* (!) RAF : prendre en compte les paramètres
       'nombre de cases de fin/sortie possibles',
       ici codé temporairement en dur : */
    fprintf(houtput, "; -------------------------------\n");
    fprintf(houtput, "; cases de fin/sortie possibles :\n");
    fprintf(houtput, ";\n");
    fprintf(houtput, "end_nb_cells_min:1\n");
    fprintf(houtput, "end_nb_cells_max:1\n");
    fprintf(houtput, "\n");
    /* lister toutes les cases de départ possibles
       (!) RAF : prendre en compte les paramètres !
       ici codé temporairement en dur : */
    fprintf(houtput, "; cases de fin/sortie possibles :\n");
    for (i = 0; i < total_cellules; i++) {
        fprintf(houtput, "e:%d\n", i + 1);
    }

    fprintf(houtput, "\n");
    fprintf(houtput, "; -------------------------------\n");
    fprintf(houtput, "; pour chaque cellule :\n");
    fprintf(houtput,
            ";   - [n° cellule] ':' [tag] = ( [lien Xx cell destination],...) ( [lien Xx tag],...)\n");
    fprintf(houtput, ";\n");

    /* petite note d'informations */
    for (i = 0; i < total_cellules; i++) {
        c = &tabcell[i];
        desc_no[0] = 0;
        desc_tag[0] = 0;
        fprintf(houtput, "; cell %d (tag = %ld) :\n", i + 1, c->tag);
        for (j = 0; j < c->nb_links; j++) {
            ajoute_desc(&c->links[j], desc_no, desc_tag);
        }
        if (c->nb_links > 0) {
            desc_no[strlen(desc_no) - 1] = 0;
            desc_tag[strlen(desc_tag) - 1] = 0;
        }
        fprintf(houtput, ";     liens : (%s) (%s)\n", desc_no, desc_tag);

        desc_no[0] = 0;
        desc_tag[0] = 0;
        for (j = 0; j < c->nb_paths; j++) {
            ajoute_desc(&c->paths[j], desc_no, desc_tag);
        }
        if (c->nb_paths > 0) {
            desc_no[strlen(desc_no) - 1] = 0;
            desc_tag[strlen(desc_tag) - 1] = 0;
        }
        fprintf(houtput, ";     paths : (%s) (%s)\n", desc_no, desc_tag);

        desc_no[0] = 0;
        desc_tag[0] = 0;
        for (j = 0; j < c->nb_walls; j++) {
            ajoute_desc(&c->walls[j], desc_no, desc_tag);
        }
        if (c->nb_walls > 0) {
            desc_no[strlen(desc_no) - 1] = 0;
            desc_tag[strlen(desc_tag) - 1] = 0;
        }
        fprintf(houtput, ";     walls : (%s) (%s)\n", desc_no, desc_tag);
    }
    fprintf(houtput, ";\n");

    /* ecriture des cellules */
    for (i = 0; i < total_cellules; i++) {
        c = &tabcell[i];

        desc_no[0] = 0;
        desc_tag[0] = 0;

        for (j = 0; j < c->nb_links; j++) {
            ajoute_desc(&c->links[j], desc_no, desc_tag);
        }

        for (j = 0; j < c->nb_paths; j++) {
            ajoute_desc(&c->paths[j], desc_no, desc_tag);
        }

        for (j = 0; j < c->nb_walls; j++) {
            ajoute_desc(&c->walls[j], desc_no, desc_tag);
        }

        desc_no[strlen(desc_no) - 1] = 0;
        desc_tag[strlen(desc_tag) - 1] = 0;

        fprintf(houtput, "%d:%lu=(%s) (%s)\n", i + 1, c->tag, desc_no,
                desc_tag);
    }

    fclose(houtput);
    return ret;
}
