//#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <dirent.h>

#include "asc.h"
#include "dialogues.h"
#include "elconfig.h"
#include "errors.h"
#include "io/elpathwrapper.h"
#include "init.h"
#include "translate.h"
#include "colors.h"
#include "themes.h"

#include "info_combat.h"

theme liste_themes[LISTE_THEMES_MAX]; // liste des thèmes trouvés (updates + datadir)
int liste_themes_nb = 0;              // nombre d'éléments dans la liste des thèmes
char titre_theme[20] = "officiel";    // titre du thème à utiliser par défaut

Uint8 couleur_mp = c_orange1;
Uint8 couleur_canal_actif = c_grey1;
Uint8 couleur_canaux = c_grey2;
Uint8 couleur_dev_canal = c_purple1;
Uint8 couleur_coord_canal = c_purple2;
Uint8 couleur_mod_canal = c_blue1;
Uint8 couleur_mg_canal = c_blue3;
Uint8 couleur_ig_canal = c_blue2;

int police_nom_pnj_dialogue = 0;
couleurs_rvb couleur_nom_pnj_dialogue = {1.0, 1.0, 1.0};

int police_titre = 0;
couleurs_rvb couleur_titre = {0.8, 0.8, 0.8};

couleurs_rvba couleur_fond_fenetre = {0.0, 0.0, 0.0, 0.4};
couleurs_rvba couleur_bord_fenetre = {0.77, 0.57, 0.39, 0.0};
couleurs_rvba couleur_ligne_fenetre = {0.77, 0.57, 0.39, 0.0};

#ifdef FR_LIVRES
int police_texte_livre = 2;
#endif //FR_LIVRES

#ifdef FR_QUICKITEMS
int fr_quickitems_dim = 30;      // dimension d'une case (largeur=hauteur, hors cadre)
int fr_quickitems_x = 3+30;      // position horizontale par défaut
int fr_quickitems_y = 64;        // position verticale par défaut
int fr_quickitems_dir = 1;       // orientation par défaut de la barre (VERTICAL=1)
int fr_quickitems_delta = 3;     // taille du séparateur entre les groupes de cases
int fr_quickitems_division = 4;  // nombre de cases formant un groupe
int quickbar_x = 3+30;
int quickbar_y = 64;
int quickbar_dir = 1;
couleurs_rvba fr_quickitems_zerocolor = {0.80, 0.00, 0.00, 0.50};
couleurs_rvba fr_quickitems_coolcolor = {0.14, 0.35, 0.82, 0.50};
#endif //FR_QUICKITEMS


void strtod_securise(char * valeur, float * variable)
{
    char *PosErreur;
    float resultat;

    resultat = strtod(valeur, &PosErreur);

    // La commande precedente n'a pas renvoyer d'erreur
    if (*PosErreur == '\0')
    {
        *variable = (float)resultat;
    }
    else
    {
        LOG_ERROR("La balise ne contient pas de chiffre !\n");
    }
}

void strtol_securise(char * valeur, int * variable)
{
    char *PosErreur;
    long resultat;

    resultat = strtol(valeur, &PosErreur, 10);

    // La commande precedente n'a pas renvoyer d'erreur
    if (*PosErreur == '\0')
    {
        if (resultat >= INT_MIN && resultat <= INT_MAX)
        {
            *variable = (int)resultat;
        }
        else
        {
            LOG_ERROR("La balise contient un chiffre, mais ce n'est pas un entier\n");
        }
    }
    else
    {
        LOG_ERROR("La balise ne contient pas de chiffre\n");
    }
}


/* Lecture des valeurs des composantes d'une couleur :
 *
 * L'élément XML fourni sera analysé pour y trouver les valeurs rouge, vert et bleu
 * (ainsi que la couche alpha pour la fonction rvba) qui seront affectées dans la
 * structure passée en paramètre.
 *
 * Les composantes peuvent être indiquées aussi bien en valeurs d'éléments enfants
 * qu'en attributs de l'élément père dans le document XML. C'est à dire :
 * - soit <couleur><rouge>1</rouge><vert>0</vert><bleu>0.5</bleu></couleur>
 * - soit <couleur rouge="1" vert="0" bleu="0.5" />
 *
 * De plus, si les valeurs doivent être comprises entre 0 et 1, il est possible
 * d'utiliser la notation de 0 à 255 dans les champs XML : pour celà toute valeur
 * supérieure à 1 sera systématiquement divisée par 255.
 */

void lecture_couleurs_rvb(xmlNode * noeud, couleurs_rvb * variable)
{
	strtod_securise(get_string_property(noeud, (char*)"rouge"), &variable->rouge);
	strtod_securise(get_string_property(noeud, (char*)"vert"),  &variable->vert);
	strtod_securise(get_string_property(noeud, (char*)"bleu"),  &variable->bleu);

	for (noeud = noeud->children; noeud; noeud = noeud->next)
	{
		if (noeud->type != XML_ELEMENT_NODE) continue;

		if (xmlStrEqual(noeud->name, (xmlChar*)"rouge"))
		{
			strtod_securise((char *)noeud->children->content, &variable->rouge);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"vert"))
		{
			strtod_securise((char *)noeud->children->content, &variable->vert);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"bleu"))
		{
			strtod_securise((char *)noeud->children->content, &variable->bleu);
		}
		else
		{
			LOG_ERROR("Couleur : balise '%s' inconnue !\n", noeud->name);
		}
	}

	if (variable->rouge > 1) variable->rouge /= 255;
	if (variable->vert  > 1) variable->vert  /= 255;
	if (variable->bleu  > 1) variable->bleu  /= 255;
}

void lecture_couleurs_rvba(xmlNode * noeud, couleurs_rvba * variable)
{
	strtod_securise(get_string_property(noeud, (char*)"rouge"), &variable->rouge);
	strtod_securise(get_string_property(noeud, (char*)"vert"),  &variable->vert);
	strtod_securise(get_string_property(noeud, (char*)"bleu"),  &variable->bleu);
	strtod_securise(get_string_property(noeud, (char*)"alpha"), &variable->alpha);

	for (noeud = noeud->children; noeud; noeud = noeud->next)
	{
		if (noeud->type != XML_ELEMENT_NODE) continue;

		if (xmlStrEqual(noeud->name, (xmlChar*)"rouge"))
		{
			strtod_securise((char *)noeud->children->content, &variable->rouge);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"vert"))
		{
			strtod_securise((char *)noeud->children->content, &variable->vert);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"bleu"))
		{
			strtod_securise((char *)noeud->children->content, &variable->bleu);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"alpha"))
		{
			strtod_securise((char *)noeud->children->content, &variable->alpha);
		}
		else
		{
			LOG_ERROR("Couleur : balise '%s' inconnue !\n", noeud->name);
		}
	}

	if (variable->rouge > 1) variable->rouge /= 255;
	if (variable->vert  > 1) variable->vert  /= 255;
	if (variable->bleu  > 1) variable->bleu  /= 255;
	if (variable->alpha > 1) variable->alpha /= 255;
}

/*
	* Convertion d'une chaine, en couleur définie dans client_server.h
	* et utilisées en paramètre de LOG_TO_CONSOLE.
	* Par exemple : c_red1, c_yellow2, c_green1...
*/
void lecture_couleur_console(char *str, Uint8 *couleur)
{
	/* Note : Les couleurs rouge ont été retirés, pour qu'elles continuent
	 * a être reservées à la modération.
	 */
	if(!strcmp(str, "green1"))
		*couleur = c_green1;
	else if(!strcmp(str, "green2"))
		*couleur = c_green2;
	else if(!strcmp(str, "green3"))
		*couleur = c_green3;
	else if(!strcmp(str, "green4"))
		*couleur = c_green4;
	else if(!strcmp(str, "yellow1"))
		*couleur = c_yellow1;
	else if(!strcmp(str, "yellow2"))
		*couleur = c_yellow2;
	else if(!strcmp(str, "yellow3"))
		*couleur = c_yellow3;
	else if(!strcmp(str, "yellow4"))
		*couleur = c_yellow4;
	else if(!strcmp(str, "orange1"))
		*couleur = c_orange1;
	else if(!strcmp(str, "orange2"))
		*couleur = c_orange2;
	else if(!strcmp(str, "orange3"))
		*couleur = c_orange3;
	else if(!strcmp(str, "orange4"))
		*couleur = c_orange4;
	else if(!strcmp(str, "purple1"))
		*couleur = c_purple1;
	else if(!strcmp(str, "purple2"))
		*couleur = c_purple2;
	else if(!strcmp(str, "purple3"))
		*couleur = c_purple3;
	else if(!strcmp(str, "purple4"))
		*couleur = c_purple4;
	else if(!strcmp(str, "blue1"))
		*couleur = c_blue1;
	else if(!strcmp(str, "blue2"))
		*couleur = c_blue2;
	else if(!strcmp(str, "blue3"))
		*couleur = c_blue3;
	else if(!strcmp(str, "blue4"))
		*couleur = c_blue4;
	else if(!strcmp(str, "grey1"))
		*couleur = c_grey1;
	else if(!strcmp(str, "grey2"))
		*couleur = c_grey2;
	else if(!strcmp(str, "grey3"))
		*couleur = c_grey3;
	else if(!strcmp(str, "grey4"))
		*couleur = c_grey4;
	else if(!strcmp(str, "rose1"))
		*couleur = c_rose1;
	else LOG_ERROR("Couleur : balise '%s' inconnue!\n", str);
}

/* Utilisation d'un thème XML :
 *
 * Chargement du fichier XML correspondant au thème indiqué.
 * Parcours des éléments XML et affectation des valeurs trouvées aux variables du jeu
 */

// Chargement des éléments de personnalisation renseignés dans le thème XML */
int chargement_theme(xmlNode * noeud)
{
	if (! xmlStrEqual(noeud->name, (xmlChar*)"Theme")) return 0;

    for (noeud = noeud->children; noeud; noeud = noeud->next)
    {
        if (noeud->type != XML_ELEMENT_NODE) continue;

		if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_mp"))
		{
			lecture_couleur_console((char *)noeud->children->content, &couleur_mp);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_dev_canal"))
		{
			lecture_couleur_console((char *)noeud->children->content, &couleur_dev_canal);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_coord_canal"))
		{
			lecture_couleur_console((char *)noeud->children->content, &couleur_coord_canal);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_mod_canal"))
		{
			lecture_couleur_console((char *)noeud->children->content, &couleur_mod_canal);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_mg_canal"))
		{
			lecture_couleur_console((char *)noeud->children->content, &couleur_mg_canal);
		}
      else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_ig_canal"))
		{
			lecture_couleur_console((char *)noeud->children->content, &couleur_ig_canal);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_canal_actif"))
		{
			lecture_couleur_console((char *)noeud->children->content, &couleur_canal_actif);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_canaux"))
		{
			lecture_couleur_console((char *)noeud->children->content, &couleur_canaux);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"police_nom_pnj_dialogue"))
		{
			strtol_securise((char *)noeud->children->content, &police_nom_pnj_dialogue);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_nom_pnj_dialogue"))
		{
			lecture_couleurs_rvb(noeud, &couleur_nom_pnj_dialogue);
		}
#ifdef FR_TITRE
		else if (xmlStrEqual(noeud->name, (xmlChar*)"police_titre"))
		{
			strtol_securise((char *)noeud->children->content, &police_titre);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_titre"))
		{
			lecture_couleurs_rvb(noeud, &couleur_titre);
		}
#endif //FR_TITRE
#ifdef FR_LIVRES
		else if (xmlStrEqual(noeud->name, (xmlChar*)"police_texte_livre"))
		{
			strtol_securise((char *)noeud->children->content, &police_texte_livre);
		}
#endif //FR_LIVRES

		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_fond_fenetre"))
		{
			lecture_couleurs_rvba(noeud, &couleur_fond_fenetre);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_bord_fenetre"))
		{
			lecture_couleurs_rvba(noeud, &couleur_bord_fenetre);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_ligne_fenetre"))
		{
			lecture_couleurs_rvba(noeud, &couleur_ligne_fenetre);
		}
#ifdef FR_QUICKITEMS
		else if (xmlStrEqual(noeud->name, (xmlChar*)"taille_case_barre_rapide"))
		{
			strtol_securise((char *)noeud->children->content, &fr_quickitems_dim);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"defaut_x_barre_rapide"))
		{
			strtol_securise((char *)noeud->children->content, &fr_quickitems_x);
			quickbar_x = fr_quickitems_x;
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"defaut_y_barre_rapide"))
		{
			strtol_securise((char *)noeud->children->content, &fr_quickitems_y);
			quickbar_y = fr_quickitems_y;
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"defaut_dir_barre_rapide"))
		{
			strtol_securise((char *)noeud->children->content, &fr_quickitems_dir);
			quickbar_dir = fr_quickitems_dir;
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"delta_barre_rapide"))
		{
			strtol_securise((char *)noeud->children->content, &fr_quickitems_delta);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"division_barre_rapide"))
		{
			strtol_securise((char *)noeud->children->content, &fr_quickitems_division);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_barre_rapide_zero"))
		{
			lecture_couleurs_rvba(noeud, &fr_quickitems_zerocolor);
		}
		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_barre_rapide_cool"))
		{
			lecture_couleurs_rvba(noeud, &fr_quickitems_coolcolor);
		}
#endif //FR_QUICKITEMS
#ifdef FR_COMBAT_INFO
        else if (xmlStrEqual(noeud->name, (xmlChar*)"console_coup_critiques"))
        {
            strtol_securise((char *)noeud->children->content, &console_coup_critiques);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"console_chance_critique"))
        {
            strtol_securise((char *)noeud->children->content, &console_chance_critique);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"console_degat_feu"))
        {
            strtol_securise((char *)noeud->children->content, &console_degat_feu);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"console_degat_froid"))
        {
            strtol_securise((char *)noeud->children->content, &console_degat_froid);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"console_degat_magie"))
        {
            strtol_securise((char *)noeud->children->content, &console_degat_magie);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"console_degat_lumiere"))
        {
            strtol_securise((char *)noeud->children->content, &console_degat_lumiere);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"console_degat_poison"))
        {
            strtol_securise((char *)noeud->children->content, &console_degat_poison);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"flottant_coup_critiques"))
        {
            strtol_securise((char *)noeud->children->content, &flottant_coup_critiques);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"flottant_chance_critique"))
        {
            strtol_securise((char *)noeud->children->content, &flottant_chance_critique);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"flottant_degat_feu"))
        {
            strtol_securise((char *)noeud->children->content, &flottant_degat_feu);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"flottant_degat_froid"))
        {
            strtol_securise((char *)noeud->children->content, &flottant_degat_froid);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"flottant_degat_magie"))
        {
            strtol_securise((char *)noeud->children->content, &flottant_degat_magie);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"flottant_degat_lumiere"))
        {
            strtol_securise((char *)noeud->children->content, &flottant_degat_lumiere);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"flottant_degat_poison"))
        {
            strtol_securise((char *)noeud->children->content, &flottant_degat_poison);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_degat_feu"))
        {
            lecture_couleurs_rvb(noeud, &couleur_degat_feu);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_degat_froid"))
        {
            lecture_couleurs_rvb(noeud, &couleur_degat_froid);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_degat_magie"))
        {
            lecture_couleurs_rvb(noeud, &couleur_degat_magie);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_degat_lumiere"))
        {
            lecture_couleurs_rvb(noeud, &couleur_degat_lumiere);
        }
        else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_degat_poison"))
        {
            lecture_couleurs_rvb(noeud, &couleur_degat_poison);
        }
#endif //FR_COMBAT_INFO
		else if (xmlStrEqual(noeud->name, (xmlChar*)"couleur_palette"))
		{
			couleurs_rvb couleur_temp;
			int numero;
			strtol_securise(get_string_property(noeud, (char*)"numero"), &numero);
			if ((numero < 0) || (numero >= 30))
			{
				LOG_ERROR("Numero de couleur non valide : %i (accepté de 0 à 29)\n", numero);
				continue;
			}
			lecture_couleurs_rvb(noeud, &couleur_temp);
			colors_list[numero].r1 = 255 * couleur_temp.rouge;
			colors_list[numero].g1 = 255 * couleur_temp.vert;
			colors_list[numero].b1 = 255 * couleur_temp.bleu;
		}
		else
		{
			LOG_ERROR("Theme : balise '%s' inconnue !\n", noeud->name);
		}
    }

	return 1;
}

// Ouverture du fichier XML correspondant au thème spécifié pour lancer son chargement */
void init_theme(char * titre)
{
	xmlDoc *doc;
	int i;
	for (i = 0; i < liste_themes_nb; i++)
	{
		if (strcmp(liste_themes[i].titre, titre) == 0)
		{
			log_info("Theme '%s' : chargement du fichier xml (%s)\n", titre, liste_themes[i].fichier);
			doc = xmlReadFile(liste_themes[i].fichier, NULL, 0);

			if (doc != NULL) chargement_theme(xmlDocGetRootElement(doc));
			else LOG_ERROR("Echec à l'ouverture du fichier xml (%s) !\n", liste_themes[i].fichier);

			xmlFreeDoc(doc);
			return;
		}
	}

	LOG_ERROR("Le thème spécifié (%s) n'a pas été trouvé dans la liste des thèmes\n", titre);
}


/* Gestion de la liste des thèmes disponibles :
 *
 * Les thèmes XML sont recherchés dans tous les dossiers pouvant en contenir.
 * Chaque fichier trouvés est ouvert pour valider qu'il s'agit bien d'un thème.
 * Le champs "détail" est lu à cette occasion pour fournir une description.
 */

// Ouverture du fichier XML d'un thème pour récupérer sa description et valider son enregistrement
int chargement_theme_detail(int n)
{
	xmlNode *root;
	xmlDoc *doc;
	int ok = 1;

	doc = xmlReadFile(liste_themes[n].fichier, NULL, 0);
	if (doc == NULL)
	{
		LOG_ERROR("%s : %s \"%s\"\n", reg_error_str, liste_themes[n].fichier, cant_open_file);
		return 0;
	}

	root = xmlDocGetRootElement(doc);
	if (root == NULL)
	{
		LOG_ERROR("Impossible de traiter le fichier du theme '%s'", liste_themes[n].fichier);
		ok = 0;
	}
	else if (! xmlStrEqual(root->name, (xmlChar*)"Theme"))
	{
		LOG_ERROR("Balise inconnue '%s' ('Theme' attendu).", root->name);
		ok = 0;
	}
	else
	{
		strncpy(liste_themes[n].detail, get_string_property(root, (char*)"detail"), sizeof(liste_themes[n].detail));
	}

	xmlFreeDoc(doc);
	return ok;
}

// Parcours le dossier spécifié à la recherche de fichiers XML de thèmes à ajouter dans la liste
int chargement_liste_themes(char * dossier_themes)
{
	DIR *dp;
	struct dirent *ep;
	int i, deja;

	log_info("Themes : recherche dans le dossier '%s'", dossier_themes);
	dp = opendir(dossier_themes);
	if (dp == NULL) return 0;

	while ((ep = readdir(dp)) != NULL)
	{
		/* on ne garde que les fichiers contenant un 'titre' entre 1 et 20 caractères */
		if ((strlen(ep->d_name) <= 4) || (strlen(ep->d_name) > 24)) continue;
		/* et qui se terminent par le suffixe '.xml' */
		if (strcmp(ep->d_name + strlen(ep->d_name) - 4, ".xml") != 0) continue;

		/* on détermine le titre du thème en retirant le suffixe du nom du fichier */
		safe_snprintf(liste_themes[liste_themes_nb].titre, strlen(ep->d_name)-3, "%s", ep->d_name);

		/* le xml io-wrapper se charge de chercher dans les différents dossiers de base possible */
		safe_snprintf(liste_themes[liste_themes_nb].fichier, sizeof(liste_themes[liste_themes_nb].fichier), "themes/%s", ep->d_name);
//		safe_snprintf(liste_themes[liste_themes_nb].fichier, sizeof(liste_themes[liste_themes_nb].fichier), "%s/%s", dossier_themes, ep->d_name);

		/* vérification qu'un thème avec ce nom n'est pas déjà dans la liste */
		deja = 0;
		for (i = 0; i < liste_themes_nb && !deja; i++)
		{
			if (strcmp(liste_themes[i].titre, liste_themes[liste_themes_nb].titre) == 0) deja = 1;
		}
		if (deja) continue;

		/* vérification que la liste des thèmes n'est pas pleine ! */
		if (liste_themes_nb >= LISTE_THEMES_MAX)
		{
			LOG_ERROR("Nombre de thèmes excessif (max %i) : fichier '%s' non chargé !\n", LISTE_THEMES_MAX, ep->d_name);
			continue;
		}

		/* validation de l'enregistrement du thème trouvé dans la liste */
		if (chargement_theme_detail(liste_themes_nb)) liste_themes_nb++;
	}
	closedir(dp);
	return 1;
}

// Initialise la liste des thèmes disponibles depuis les dossiers updates, datadir puis local
void init_liste_themes()
{
	char dossier_themes[256];

	// on remet la liste à zéro (en cas de rechargement de la liste)
	liste_themes_nb = 0;

	// on cherche d'abord la présence de thèmes dans le dossier perso (conf locale)
	safe_snprintf(dossier_themes, sizeof(dossier_themes), "%s/themes/", get_path_config());
	chargement_liste_themes(dossier_themes);

	// on cherche ensuite la présence de thèmes dans le dossier des mises à jour auto
	safe_snprintf(dossier_themes, sizeof(dossier_themes), "%s/themes/", get_path_updates());
	chargement_liste_themes(dossier_themes);

	// on récupère ensuite les thèmes disponible dans le dossier de données du jeu
	safe_snprintf(dossier_themes, sizeof(dossier_themes), "%s/themes/", datadir);
	chargement_liste_themes(dossier_themes);

	// éventuellement on regarde dans un dossier de thèmes à partir du dossier courant (normalement datadir aussi)
	safe_snprintf(dossier_themes, sizeof(dossier_themes), "%s/themes/", ".");
	chargement_liste_themes(dossier_themes);
}


/* Commandes de gestion in-game du thème actif
 *
 * Ces fonctions correspondent à des commandes consoles
 * permettant d'afficher la liste des thèmes dispo
 * et de sélectionner le thème à utiliser.
 */

// Relance un parcours des dossiers pour regénérer la liste des thèmes disponibles
int recharge_themes()
{
	init_liste_themes();
	return 1;
}

// Affiche à l'écran la liste des thèmes en indiquant en surbrillance le thème actif
int command_liste_themes()
{
	char str[200];
	int i;
	recharge_themes();
	LOG_TO_CONSOLE(c_green2, "Liste des thèmes disponibles :");
	for (i=0; i < liste_themes_nb; i++)
	{
		safe_snprintf(str, sizeof(str), "-%-12s : %s", liste_themes[i].titre, liste_themes[i].detail);
		LOG_TO_CONSOLE(strcmp(titre_theme, liste_themes[i].titre) ? c_yellow1 : c_yellow2, str);
//		safe_snprintf(str, sizeof(str), "  (fichier %s)", liste_themes[i].fichier);
//		LOG_TO_CONSOLE(c_grey2, str);
	}
	return 1;
}

// Sélectionne le nouveau thème actif qui sera chargé et mémorisé dans le fichier de conf
int command_change_theme(char *text)
{
	char str[200];
	int i;
	recharge_themes();
	for (; isspace(*text); text++);
	for (i=0; i < liste_themes_nb; i++)
	{
		if (strcmp(text, liste_themes[i].titre) == 0)
		{
			safe_snprintf(titre_theme, sizeof(titre_theme), "%s", text);
			set_var_unsaved("titre_theme", OPT_STRING_INI); // forcer la sauvegarde dans le fichier ini

			LOG_TO_CONSOLE(c_green1, "Le thème actif a été modifié et appliqué.");
			LOG_TO_CONSOLE(c_green1, "(certaines modifications peuvent nécessiter un redémarrage du client)");
			init_theme(titre_theme);
			return 1;
		}
	}
	safe_snprintf(str, sizeof(str), "Ce thème ne figure pas dans la liste ! (%s)", text);
	LOG_TO_CONSOLE(c_red1, str);
	return 1;
}

