/*   EXTRAITS DE LA LICENCE
	Copyright CEA, contributeurs : Luc BILLARD et Damien
	CALISTE, laboratoire L_Sim, (2001-2006)
  
	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-2006)

	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 VISUTOOLS_H
#define VISUTOOLS_H

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <glib.h>
#include <glib-object.h>

#ifndef DEBUG
  #define DEBUG 0
#endif
#ifndef INSTALL_DIR
  #define INSTALL_DIR "/usr/local"
#endif
#ifdef ENABLE_NLS
#  include <libintl.h>
#  undef _
#  define _(String) dgettext (PACKAGE, String)
#  ifdef gettext_noop
#    define N_(String) gettext_noop (String)
#  else
#    define N_(String) (String)
#  endif
#else
#  define textdomain(String) (String)
#  define gettext(String) (String)
#  define dgettext(Domain,Message) (Message)
#  define dcgettext(Domain,Message,Type) (Message)
#  define bindtextdomain(Domain,Directory) (Domain)
#  define _(String) (String)
#  define N_(String) (String)
#endif

/**
 * DBG_fprintf
 *
 * For developpers : use this macro instead of fprintf.
 */
#define DBG_fprintf if(DEBUG) fprintf

#define V_SIM_NAME             PACKAGE
#define V_SIM_VERSION          VERSION
#define V_SIM_WEB_SITE         "<u>http://www-drfmc.cea.fr/sp2m/L_Sim/V_Sim</u>"

#define V_SIM_LICENCE_FILE  _("licence.en.txt")
#define V_SIM_AUTHORS_FILE  _("authors")
#define V_SIM_README_FILE   _("readme")


gchar *v_sim_data_dir;
gchar *v_sim_conf_dir;
gchar *v_sim_legal_dir;
gchar *v_sim_pixmaps_dir;
gchar *v_sim_local_conf_dir;

/**
 * MAX_LINE_LENGTH
 *
 * This is the maximum number of characters read on a
 * line of an input file.
 */
#define MAX_LINE_LENGTH 256

/**
 * MASK_RGB_R:
 *
 * This value can be used to create a mask for methods that
 * require one for reading rgb color array. This value actually
 * correspond to red.
 */
#define MASK_RGB_R (1 << 0)
/**
 * MASK_RGB_G:
 *
 * This value can be used to create a mask for methods that
 * require one for reading rgb color array. This value actually
 * correspond to green.
 */
#define MASK_RGB_G (1 << 1)
/**
 * MASK_RGB_B:
 *
 * This value can be used to create a mask for methods that
 * require one for reading rgb color array. This value actually
 * correspond to blue.
 */
#define MASK_RGB_B (1 << 2)
/**
 * MASK_RGB_ALL:
 *
 * This value can be used to create a mask for methods that
 * require one for reading rgb color array. This value is a
 * shortcut for #MASK_RGB_R | #MASK_RGB_G | #MASK_RGB_B.
 */
#define MASK_RGB_ALL (7)

/**
 * voidDataFunc:
 * @data: a pointer to some user defined object.
 *
 * These methods are used when no specific argument is required except
 * a user-defined object and when void is the return type.
 */
typedef void (*voidDataFunc)(gpointer data);

/**
 * struct VisuIO_struct:
 * @dest: in or out flux,
 * @nbLine: number of lines already read or written,
 * @informations: store whatever one wants.
 *
 * This structure is convenient to store informations on
 * a file open for reading or writing. @informations is usually
 * used to store comments on what happens, about the error
 * messages...
 */
struct VisuIO_struct
{
  FILE **flux;
  int *nbLine;
  GString *informations;

/*   char **message; */
/*   int *size; */
};
/**
 * VisuIO:
 *
 * Shorter name for #VisuIO_struct structure.
 */
typedef struct VisuIO_struct VisuIO;


/**
 * setFileSystemInUTF8:
 * @val: a boolean to specify if the file system is in UTF-8 or not.
 *
 * A call to this method stores a flag to identify the file system
 * as in UTF-8 or not. If system is not in UTF-8, the programmer needs
 * to convert from locale to UTF-8 to use file names in the GTK interface
 * and have to do some transformations from UTF-8 to locale when strings
 * are retrieve from the GTK interface.
 */
void setFileSystemInUTF8(int val);
/**
 * getFileSystemInUTF8:
 *
 * This method can retrieve the flag for the coding of the file system.
 * This flag must have been initialized by a call to %setFileSystemInUTF8
 * before using this method. If system is not in UTF-8, the programmer needs
 * to convert from locale to UTF-8 to use file names in the GTK interface
 * and have to do some transformations from UTF-8 to locale when strings
 * are retrieve from the GTK interface.
 *
 * Returns: 1 if the flag of the file system is on UTF-8, 0 otherwise.
 */
int getFileSystemInUTF8();
/**
 * getStringInUTF8:
 * @str: a string to convert.
 *
 * Convert the given string from the locale of the file system to UTF-8.
 *
 * Returns: a newly allocated string, must be freed by a call to g_free after use.
 */
gchar* getStringInUTF8(const gchar* str);

/* All signal emit by visu are handled by this ogbject. */
GObject *visu;


/**
 * freeUserDataFunc:
 * @data: some allocated data.
 *
 * This prototype is used when a method must be given to free some data.
 */
typedef void (*freeUserDataFunc)(gpointer data);

/**
 * freeString:
 * @ele: the char* to be freed.
 * 
 * It deallocates @ele. @ele must be a char* and have
 * been allocated with malloc or realloc. This function
 * can be used as a freed method for a GHashTable of which
 * values are char*.
 */
void freeString(gpointer ele);
/**
 * freeFloat:
 * @ele: the float* to be freed.
 * 
 * It deallocates @ele. @ele must be a float* and have
 * been allocated with malloc or realloc. This function
 * can be used as a freed method for a GHashTable of which
 * values are float*.
 */
void freeFloat(gpointer ele);
/**
 * freeInt:
 * @ele: the int* to be freed.
 * 
 * It deallocates @ele. @ele must be a int* and have
 * been allocated with malloc or realloc. This function
 * can be used as a freed method for a GHashTable of which
 * values are int*.
 */
void freeInt(gpointer ele);
/**
 * freeGPointer:
 * @ele: the gpointer to be freed.
 * 
 * It deallocates @ele. @ele must have been allocated with
 * malloc or realloc. This function can be used as a freed
 * method for a GHashTable of which values are of complex structure.
 */
void freeGPointer(gpointer ele);

/**
 * getValidPath:
 * @pathList: a pointer to a GList with all the possible path,
 * @fileName: a string,
 * @accessMode: a value from R_OK, W_OK and X_OK as described in unistd.h.
 *
 * @pathList contains a list of directories (first is most prefered)
 * and fileName is the file name which one likes have informations on. This routine
 * look for the first directory where fileName can be writen or read (depending
 * on accessMode parameter). The pointer to the GList indicates at the end the
 * first valid entry in the GList.
 *
 * Returns: the first valid complete path (from @pathList plus @fileName)
 * if one can be found depnding on @accessMode or NULL if none found.
 */
gchar* getValidPath(GList **pathList, char *fileName, int accessMode);

/**
 * visuWaitFunction:
 *
 * This function must be called in a blocking loop to update
 * different things like the gtk for example.
 */
void visuWaitFunction();

/**
 * allocationProblems:
 *
 * Print a message.
 */
void allocationProblems();

/******************/
/* Storing colors */
/******************/
/**
 * Color:
 * @rgba: the coding of color in Red, Green, Blue, Alpha format,
 *        floating point numbers between 0 and 1 ;
 * @userData: a pointer to store some data (should be used with care).
 *
 * A structure to store colors.
 */
typedef struct Color_struct
{
  float rgba[4];
  gpointer userData;
} Color;
/**
 * initColorStorage:
 *
 * This method must be called once at the beginning of the program, if
 * you want to use the color storage system.
 */
void initColorStorage();
/**
 * colorNew_floatRGBA:
 * @rgba: four values between 0. and 1. that represent [Red, Green, Blue, Alpha].
 * 
 * Create a new color with initial values given as arguments.
 *
 * Returns: a new allocated %Color.
 */
Color* colorNew_floatRGBA(float rgba[4]);
/**
 * colorGet_byId:
 * @num: an integer (>0).
 *
 * This function retrieves the nth stored color. Number 0, is the last
 * added color.
 *
 * Returns: the corresponding color, or NULL if none has been found.
 */
Color* colorGet_byId(int num);
/**
 * colorGet_lastStored:
 *
 * This method is typiccally called after a client has catched
 * the colorNewAvailable signal.
 *
 * Returns: the last added color, NULL if no color exists.
 */
Color* colorGet_lastStored();
/**
 * colorGet_byColor:
 * @color: a pointer to a stored color.
 *
 * This function retrieves the number (begining at 0) of the specified color.
 *
 * Returns: the position of the specified color or -1 if not found.
 */
int colorGet_byColor(Color *color);
/**
 * colorGet_byValues:
 * @pos: an allocated int to store the position of the found color ;
 * @red: a value between 0. and 1. ;
 * @green: a value between 0. and 1. ;
 * @blue: a value between 0. and 1. ;
 * @alpha: a value between 0. and 1..
 *
 * This method is used to look for a specific color in the stored list. The argument @pos
 * is -1 if nothing is found or stores the position (beginning at 0) of the found color.
 *
 * Returns: the found color, or NULL if none exists.
 */
Color* colorGet_byValues(int *pos, float red, float green, float blue, float alpha);
/**
 * colorGet_storedColors:
 *
 * Use this method to get a pointeur to the list of stored colors.
 *
 * Returns: a GList pointer to the stored colors.
 */
GList* colorGet_storedColors();
/**
 * colorAdd_color:
 * @color: a %Color.
 *
 * This method copies color informations from @color to the list of stored colors.
 *
 * Returns: 0 if everything is OK.
 */
Color* colorAdd_color(Color* color);
/**
 * colorAdd_floatRGBA:
 * @rgba: four values between 0. and 1. that represent [Red, Green, Blue, Alpha] ;
 * @position: an int pointer to store the position off the returned colour.
 *
 * This method adds a new color in the list of stored colors with the given values.
 * If it already exits it returns the pointer of that color.
 *
 * Returns: a pointer to the color.
 */
Color* colorAdd_floatRGBA(float rgba[4], int *position);
/**
 * colorAdd_intRGBA:
 * @rgba: four values between 0 and 255 that represent [Red, Green, Blue, Alpha].
 *
 * This method adds a new color in the list of stored colors with the given values.
 *
 * Returns: 0 if everything is OK.
 */
Color* colorAdd_intRGBA(int rgba[4]);

/**
 * fModulo:
 * @a: a float ;
 * @b: an int.
 * 
 * This function is just like a%b except it works with a float @a argument. 
 * @a can be negative, but the return value of the function is always positive.
 *
 * Returns: the new float value after the modulo.
*/
float fModulo(float a, int b);

/**
 * HSVtoRGB:
 * @rgb: an allocated 3 elements array to receive the RGB values ;
 * @hsv: a 3 elements array to retrieve the HSV values from.
 *
 * This methods convert a HSV color to a RGB one.
 */
void HSVtoRGB(float* rgb, float* hsv);

/**
 * HSLtoRGB:
 * @rgb: an allocated 3 elements array to receive the RGB values ;
 * @hsl: a 3 elements array to retrieve the HSL values from.
 *
 * This methods convert a HSL color to a RGB one.
 */
void HSLtoRGB(float *rgb, float *hsl);

/**
 * cartesian_to_spherical:
 * @spherical: an allocated array of 3 floating point values to store the result ;
 * @cartesian: an allocated array of 3 floating point values to read the input.
 *
 * A method to transform cartesian coordinates in spherical coordinates (radius, phi and theta).
 */
void cartesian_to_spherical(float *spherical, float *cartesian);
/**
 * spherical_to_cartesian:
 * @cartesian: an allocated array of 3 floating point values to store the result ;
 * @spherical: an allocated array of 3 floating point values to read the input.
 *
 * A method to transform spherical coordinates (radius, phi and theta) to cartesian coordinates.
 */
void spherical_to_cartesian(float *cartesian, float *spherical);
/**
 * square_matrix_product:
 * @matrix: an array of floating point values of size @dim x @dim ;
 * @vector: an array of floating point values of dimension @dim ;
 * @result: an allocated array of floating point values of dimension @dim ;
 * @dim: the dimension of the vector space.
 *
 * Compute the mathematical product between @marix and @vector and
 * put the result vector in @result.
 */
void square_matrix_product(float *matrix, float *vector, float *result, int dim);
/**
 * matrixProduct:
 * @matRes: an array of floating point values of size 3x3 ;
 * @matA: an array of floating point values of size 3x3 ;
 * @matB: an array of floating point values of size 3x3.
 *
 * Compute the mathematical product between @matA and @matB and
 * put the result matrix in @matRes.
 */
void matrixProduct(float matRes[3][3], float matA[3][3], float matB[3][3]);
/**
 * vectorProduct:
 * @vectRes: an array of floating point values of size 3 ;
 * @mat: an array of floating point values of size 3x3 ;
 * @vect: an array of floating point values of size 3.
 *
 * Compute the mathematical product between @matA and @vect and
 * put the result vector in @vectRes.
 */
void vectorProduct(float vectRes[3], float mat[3][3], float vect[3]);

/**
 * normalize_path:
 * @path: a string, NULL terminated.
 *
 * This function normalizes the path, i.e. it removes all . and .. It should
 * work also on Windows. It must take an absolute path as argument, if not it is converted
 * assuming the current working directory.
 *
 * Returns: a newly created string.
 */
gchar* normalize_path(gchar* path);


#endif
