/*   EXTRAITS DE LA LICENCE
	Copyright CEA, contributeurs : Luc BILLARD et Damien
	CALISTE, laboratoire L_Sim, (2001-2005)
  
	Adresse mèl :
	BILLARD, non joignable par mèl ;
	CALISTE, damien P caliste AT cea P fr.

	Ce logiciel est un programme informatique servant à visualiser des
	structures atomiques dans un rendu pseudo-3D. 

	Ce logiciel est régi par la licence CeCILL soumise au droit français et
	respectant les principes de diffusion des logiciels libres. Vous pouvez
	utiliser, modifier et/ou redistribuer ce programme sous les conditions
	de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA 
	sur le site "http://www.cecill.info".

	Le fait que vous puissiez accéder à cet en-tête signifie que vous avez 
	pris connaissance de la licence CeCILL, et que vous en avez accepté les
	termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel).
*/

/*   LICENCE SUM UP
	Copyright CEA, contributors : Luc BILLARD et Damien
	CALISTE, laboratoire L_Sim, (2001-2005)

	E-mail address:
	BILLARD, not reachable any more ;
	CALISTE, damien P caliste AT cea P fr.

	This software is a computer program whose purpose is to visualize atomic
	configurations in 3D.

	This software is governed by the CeCILL  license under French law and
	abiding by the rules of distribution of free software.  You can  use, 
	modify and/ or redistribute the software under the terms of the CeCILL
	license as circulated by CEA, CNRS and INRIA at the following URL
	"http://www.cecill.info". 

	The fact that you are presently reading this means that you have had
	knowledge of the CeCILL license and that you accept its terms. You can
	find a copy of this licence shipped with this software at Documentation/licence.en.txt.
*/

#ifndef VISU_CONFIG_FILE_H
#define VISU_CONFIG_FILE_H

#include <glib.h>
#include <glib-object.h>
#include <stdarg.h>
#include <visu_data.h>
#include <coreTools/toolColor.h>

typedef struct _VisuConfigFileEntry VisuConfigFileEntry;

/**
 * VisuConfigFileKind:
 * @VISU_CONFIG_FILE_KIND_PARAMETER: a kind of configuration that is
 * used to change settings in the way V_Sim is working.
 * @VISU_CONFIG_FILE_KIND_RESOURCE:  a kind of configuartion that is
 * used to change the rendering output of V_Sim.
 *
 * This defines a parameter entry in the config files.
 */
typedef enum {
  VISU_CONFIG_FILE_KIND_PARAMETER,
  VISU_CONFIG_FILE_KIND_RESOURCE
} VisuConfigFileKind;

/**
 * VISU_TYPE_CONFIG_FILE:
 *
 * return the type of #VisuConfigFile.
 */
#define VISU_TYPE_CONFIG_FILE	     (visu_config_file_get_type ())
/**
 * VISU_CONFIG_FILE:
 * @obj: a #GObject to cast.
 *
 * Cast the given @obj into #VisuConfigFile type.
 */
#define VISU_CONFIG_FILE(obj)	     (G_TYPE_CHECK_INSTANCE_CAST(obj, VISU_TYPE_CONFIG_FILE, VisuConfigFile))
/**
 * VISU_CONFIG_FILE_CLASS:
 * @klass: a #GObjectClass to cast.
 *
 * Cast the given @klass into #VisuConfigFileClass.
 */
#define VISU_CONFIG_FILE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST(klass, VISU_TYPE_CONFIG_FILE, VisuConfigFileClass))
/**
 * VISU_IS_CONFIG_FILE:
 * @obj: a #GObject to test.
 *
 * Test if the given @ogj is of the type of #VisuConfigFile object.
 */
#define VISU_IS_CONFIG_FILE(obj)    (G_TYPE_CHECK_INSTANCE_TYPE(obj, VISU_TYPE_CONFIG_FILE))
/**
 * VISU_IS_CONFIG_FILE_CLASS:
 * @klass: a #GObjectClass to test.
 *
 * Test if the given @klass is of the type of #VisuConfigFileClass class.
 */
#define VISU_IS_CONFIG_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE(klass, VISU_TYPE_CONFIG_FILE))
/**
 * VISU_CONFIG_FILE_GET_CLASS:
 * @obj: a #GObject to get the class of.
 *
 * It returns the class of the given @obj.
 */
#define VISU_CONFIG_FILE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS(obj, VISU_TYPE_CONFIG_FILE, VisuConfigFileClass))

typedef struct _VisuConfigFilePrivate VisuConfigFilePrivate;
typedef struct _VisuConfigFile VisuConfigFile;
struct _VisuConfigFile
{
  VisuObject parent;

  VisuConfigFilePrivate *priv;
};

/**
 * VisuConfigFileClass:
 * @parent: the parent class.
 *
 * A short way to identify #_VisuConfigFileClass structure.
 */
typedef struct _VisuConfigFileClass VisuConfigFileClass;
struct _VisuConfigFileClass
{
  VisuObjectClass parent;
};

/**
 * visu_config_file_get_type:
 *
 * This method returns the type of #VisuConfigFile, use VISU_TYPE_CONFIG_FILE instead.
 *
 * Returns: the type of #VisuConfigFile.
 */
GType visu_config_file_get_type(void);

VisuConfigFile* visu_config_file_getStatic(VisuConfigFileKind kind);

/**
 * VISU_CONFIG_FILE_RESOURCE:
 *
 * Default instance of #VisuConfigFile object handling resource data.
 *
 * Since: 3.8
 */
#define VISU_CONFIG_FILE_RESOURCE visu_config_file_getStatic(VISU_CONFIG_FILE_KIND_RESOURCE)
/**
 * VISU_CONFIG_FILE_PARAMETER:
 *
 * Default instance of #VisuConfigFile object handling parameter data.
 *
 * Since: 3.8
 */
#define VISU_CONFIG_FILE_PARAMETER visu_config_file_getStatic(VISU_CONFIG_FILE_KIND_PARAMETER)

/**
 * VisuConfigFileReadFunc:
 * @entry: the #VisuConfigFileEntry that raises this callback.
 * @lines: an array of strings ;
 * @nbLines: an integer ;
 * @position: an integer ;
 * @error: a pointer to a GError pointer.
 *
 * This prototype corresponds to methods called when an entry is
 * found. The @lines argument is an array of lines read from the files.
 * These strings are copies and can be modified but not freed. There are
 * @nbLines and this value correspond to the number of lines defined
 * for the entry. The @error argument is used to store some text
 * messages and error ids. They should be in UTF8. The @error argument
 * must be initialised with (GError*)0. The @position argument give the number
 * of the first line given in @lines argument.
 *
 * Returns: TRUE if everything goes right, FALSE otherwise.
 */
typedef gboolean (*VisuConfigFileReadFunc)(VisuConfigFileEntry *entry,
                                           gchar **lines, int nbLines,
					   int position, GError **error);
/**
 * VisuConfigFileExportFunc:
 * @data: an empty GString to store the export ;
 * @dataObj: (allow-none): a #VisuData object ;
 *
 * This prototype defines a method that is used to export some resources
 * or parameters. The @data argument is an empty GString where the export has
 * to be written. If the argument @dataObj is not null, only resources related
 * to the #VisuData object should be exported (for parameters files, @dataObj is
 * always NULL).
 */
typedef void (*VisuConfigFileExportFunc)(GString *data, VisuData* dataObj);

/**
 * VisuConfigFileEnumFunc:
 * @label: a string.
 * @value: a location to store an enum value.
 *
 * Try to match @label with a enum @value.
 *
 * Since: 3.8
 *
 * Returns: TRUE if found.
 */
typedef gboolean (*VisuConfigFileEnumFunc)(const gchar *label, guint *value);
/**
 * VisuConfigFileForeachFuncExport:
 * @data: the string where the values are exported to ;
 * @dataObj: the current #VisuData object, values are related to.
 *
 * This structure can be used to encapsulate the arguments of an export method
 * when used in a foreach glib loop.
 */
struct _VisuConfigFileForeachFuncExport
{
  GString *data;
  VisuData *dataObj;
};

GType visu_config_file_entry_get_type(void);
#define VISU_TYPE_CONFIG_FILE_ENTRY (visu_config_file_entry_get_type())

VisuConfigFileEntry* visu_config_file_addEntry(VisuConfigFile *conf, const gchar *key,
                                               const gchar* description, int nbLines,
                                               VisuConfigFileReadFunc readFunc);
VisuConfigFileEntry* visu_config_file_ignoreEntry(VisuConfigFile *conf, const gchar *key,
                                                  guint nbLines);
VisuConfigFileEntry* visu_config_file_addTokenizedEntry(VisuConfigFile *conf, const gchar *key,
                                                        const gchar* description,
                                                        gboolean labelled);
VisuConfigFileEntry* visu_config_file_addBooleanEntry(VisuConfigFile *conf, const gchar *key,
                                                      const gchar* description,
                                                      gboolean *location, gboolean labelled);
VisuConfigFileEntry* visu_config_file_addBooleanArrayEntry(VisuConfigFile *conf, const gchar *key,
                                                           const gchar* description,
                                                           guint nValues, gboolean *location,
                                                           gboolean labelled);
VisuConfigFileEntry* visu_config_file_addIntegerArrayEntry(VisuConfigFile *conf, const gchar *key,
                                                           const gchar* description,
                                                           guint nValues, int *location,
                                                           int clamp[2], gboolean labelled);
VisuConfigFileEntry* visu_config_file_addFloatArrayEntry(VisuConfigFile *conf, const gchar *key,
                                                         const gchar* description,
                                                         guint nValues, float *location,
                                                         float clamp[2], gboolean labelled);
VisuConfigFileEntry* visu_config_file_addEnumEntry(VisuConfigFile *conf, const gchar *key,
                                                   const gchar* description, guint *location,
                                                   VisuConfigFileEnumFunc toEnum,
                                                   gboolean labelled);
VisuConfigFileEntry* visu_config_file_addStringEntry(VisuConfigFile *conf, const gchar *key,
                                                     const gchar* description,
                                                     gchar **location);
VisuConfigFileEntry* visu_config_file_addStippleArrayEntry(VisuConfigFile *conf, const gchar *key,
                                                           const gchar* description,
                                                           guint nValues, guint16 *location);
void visu_config_file_addExportFunction(VisuConfigFile *conf, VisuConfigFileExportFunc writeFunc);

void visu_config_file_entry_setTag(VisuConfigFileEntry *entry, const gchar *tag);
void visu_config_file_entry_setVersion(VisuConfigFileEntry *entry, float version);
void visu_config_file_entry_setReplace(VisuConfigFileEntry *newEntry,
                                       VisuConfigFileEntry *oldEntry);
const gchar* visu_config_file_entry_getKey(const VisuConfigFileEntry *entry);
const gchar* visu_config_file_entry_getLabel(const VisuConfigFileEntry *entry);
gboolean visu_config_file_entry_popToken(VisuConfigFileEntry *entry, const gchar **value);
gboolean visu_config_file_entry_popTokenAsBoolean(VisuConfigFileEntry *entry, guint nValues,
                                                  gboolean *values);
gboolean visu_config_file_entry_popTokenAsInt(VisuConfigFileEntry *entry, guint nValues,
                                              int *values, const int clamp[2]);
gboolean visu_config_file_entry_popTokenAsColor(VisuConfigFileEntry *entry, const ToolColor **color);
gboolean visu_config_file_entry_popTokenAsFloat(VisuConfigFileEntry *entry, guint nValues,
                                                float *values, const float clamp[2]);
gboolean visu_config_file_entry_popTokenAsEnum(VisuConfigFileEntry *entry, guint *value,
                                               VisuConfigFileEnumFunc toEnum);
gchar* visu_config_file_entry_popAllTokens(VisuConfigFileEntry *entry);
void visu_config_file_entry_setErrorMessage(VisuConfigFileEntry *entry, const gchar *mess, ...);

gboolean visu_config_file_load(VisuConfigFile *conf, const char* filename, GError **error);
gboolean visu_config_file_loadCommandLine(GError **error);
gboolean visu_config_file_save(VisuConfigFile *conf, const char* fileName, int *lines,
                               VisuData *dataObj, GError **error);
gboolean visu_config_file_saveResourcesToXML(const char* filename, int *lines,
                                             VisuData *dataObj, GError **error);

void visu_config_file_addKnownTag(gchar* tag);

void visu_config_file_exportComment(GString *buffer, const gchar *comment);
void visu_config_file_exportEntry(GString *buffer, const gchar *name,
                                  const gchar *id_value, const gchar *format_, ...);

gchar* visu_config_file_getValidPath(VisuConfigFile *conf, int mode, int utf8);
gchar* visu_config_file_getNextValidPath(VisuConfigFile *conf, int accessMode, GList **list, int utf8);
const gchar* visu_config_file_getDefaultFilename(VisuConfigFileKind kind);
GList* visu_config_file_getPathList(VisuConfigFile *conf);


GList* visu_config_file_getEntries(VisuConfigFile *conf);
gboolean visu_config_file_exportToXML(VisuConfigFile *conf, const gchar *filename, GError **error);

const gchar* visu_config_file_getPath(VisuConfigFile *conf);

#endif
