/*   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 VISU_DRAWING_H
#define VISU_DRAWING_H

#include <glib.h>
#include <stdio.h>

#include "visu_data.h"
#include "openGLFunctions/view.h"

/* The way visu renders its data is done by modules. They are called
   rendering methods and they describes how data are drawn on
   the screen. Many can be defined but only one is used at a
   time to render the data.
   One or more file type are associated with a rendering method. And
   a rendering method must specify the way to load the data it needs.
   A rendering method can introduced new resources and it must
   implement methods and create variable to deal with them :
    - one GHashTable that store as keys the name of all
    the resources introduced by the method and as value
    a description that is used as a commentary when the
    resources are exported to a file.
    - one method to read from a line the values of a specified
    resource.
    - one method to write to a file the values of a specified
    resource. */


/***************/
/* Public area */
/***************/

/* This structure allows the user to store data
   about a rendering method. */
struct RenderingMethod_struct;
typedef struct RenderingMethod_struct RenderingMethod;


/**
 * renderingMethodLoadFunc:
 * @data: an already allocated #VisuData ;
 * @errorMessage: a pointer to store a possible error message, can be NULL.
 *
 * Interface of functions that allow to load data. The filenames are retrieve from the given
 * #VisuData, using the visuDataGet_file() method. If the @errorMessage is NULL,
 * no error strings are returned.
 *
 * Returns : 1 if everything goes right.
 */
typedef int (*renderingMethodLoadFunc) (VisuData *data, GString **errorMessage);


/* Interfaces for OpenGl functions. */

/**
 * createOpenGLElementFunc:
 * @view: a #OpenGLView object that contains the geometric caracteristic for
 *        the rendering ;
 * @ele: a #VisuElement.
 *
 * Such functions are called whenever a newElement is registered.
 */
typedef void (*createOpenGLElementFunc) (OpenGLView *view, VisuElement* ele);
/**
 * createOpenGLNodeFunc:
 * @visuData: a #VisuData object ;
 * @node: a #VisuElement ;
 * @ele: a #VisuElement.
 *
 * Such functions are called when the OpenGl list of all the nodes is created.
 * The @ele parameter is the #VisuElement of the given node and the @visuData one
 * points to the #VisuData object that contains this node.
 */
typedef void (*createOpenGLNodeFunc) (VisuData *visuData, VisuNode* node, VisuElement* ele);
/**
 * getExtensOfNodeFunc:
 * @ele: a @VisuElement.
 *
 * This function is required to inform the OpenGL drawer
 * and to adapt the maximum size of the drawing area.
 *
 * Returns: the geometrical size of the element.
 */
typedef float (*getExtensOfNodeFunc) (VisuElement* ele);

/**
 * renderingMethod_new:
 * @name: a string to label the method ;
 * @printName: a string to label the method that can be safely translated ;
 * @description: a string to describe the method ;
 * @nbFileType: an integer ;
 * @loadMethod: a @loadDataFromFileFunc which the load function of the method.
 *
 * Method used to create rendering methods. The @nbFileType argument is used to declare
 * the number of files that the method needs to read to render a set of data.
 * Use renderingMethodSet_fileType() method to set some #FileFormat for each kind.
 *
 * Returns: the newly created method of a null pointer if something goes
 * wrong.
 */
RenderingMethod* renderingMethod_new(char* name, char* printName, char* description,
				     int nbFileType, renderingMethodLoadFunc loadMethod);
/**
 * renderingMethod_free:
 * @method: the method to delete.
 *
 * Free all the allocated attributes of the specified method.
 */
void renderingMethod_free(RenderingMethod* method);
/**
 * renderingMethodSet_fileType:
 * @method: a method ;
 * @fileTypeList: a list of #FileFormat ;
 * @fileType: an integer used as a key, must >= 0 and < method->nbFilesType ;
 * @name: a string to shortly describe the kind of file type (not NULL).
 *
 * Store a list of #FileFormat for the kind of file @fileType. The @name
 * argument is copied. but warning, the @fileTypeList GList* is not copied.
 */
void renderingMethodSet_fileType(RenderingMethod *method, GList *fileTypeList,
				 int fileType, gchar *name);
/**
 * renderingMethodGet_nbFileType:
 * @method: a method.
 *
 * This method is used to get the number of kind of files needed to
 * render a set of data.
 *
 * Returns: how many kind of files are handled by the given RenderingMethod.
 */
int renderingMethodGet_nbFileType(RenderingMethod *method);
/**
 * renderingMethodGet_fileType:
 * @method: a method ;
 * @fileType: an integer used as a key, must >= 0 and < method->nbFilesType.
 *
 * This method is used to get the file formats associated to a kind of input file
 * handled by the rendering method.
 *
 * Returns: a GList* with the #FileFormat. This GList should been considered read-only.
 */
GList* renderingMethodGet_fileType(RenderingMethod *method, int fileType);

/**
 * renderingMethodGet_fileType:
 * @method: a method ;
 * @fileType: an integer used as a key, must >= 0 and < method->nbFilesType.
 *
 * This method is used to get the name associated to a kind of input file
 * handled by the rendering method.
 *
 * Returns: a string own by V_Sim. This string should been considered read-only.
 */
gchar* renderingMethodGet_fileTypeName(RenderingMethod *method, int fileType);

/**
 * renderingMethodGet_AllMethods:
 *
 * This method gives a GList with pointers to each rendering method.
 * Warning : the returned GList is not a copy, it must not be modified,
 * just read.
 *
 * Returns: A GList containing all the registered rendering methods.
 */
GList* renderingMethodGet_AllMethods();

/**
 * renderingMethodSet_icon:
 * @method: a method ;
 * @path: a path to an image file.
 *
 * This method is used to set the path to an icon for the specified method.
 * The path is copied, and the given name can be freed freely after a call to
 * this method.
 */
void renderingMethodSet_icon(RenderingMethod *method, char *path);

/**
 * renderingMethodGet_sizeOfElement:
 * @method: a method ;
 * @ele: a #VisuElement to get the size of.
 *
 * This method is used to retrieve the radius of the sphere that contains
 * the @ele.
 *
 * Returns: the radius of the given element.
 */
float renderingMethodGet_sizeOfElement(RenderingMethod *method, VisuElement *ele);

/**
 * setOpenGLMethods:
 * @method: a RenderingMethod ;
 * @createElement: a @createOpenGLElementFunc ;
 * @createNode: a @createOpenGLNodeFunc ;
 * @getSize: a @getExtensOfNodeFunc.
 *
 * This method is used to set the callback functions for the specified
 * rendering method. These callbacks are used by the OpenGl part of the code.
 * The @createElement parameter is a method called to create an OpenGl list
 * that draw the symbol corresponding to the element. The @createNode parameter
 * is called to position and drw the specified node. It should not create a list.
 */
void setOpenGLMethods(RenderingMethod* method,
		      createOpenGLElementFunc createElement,
		      createOpenGLNodeFunc createNode,
		      getExtensOfNodeFunc getSize);

/**
 * registerRenderingMethod:
 * @method: a RenderingMethod.
 *
 * A method used by user to registered a new method.
 */
void registerRenderingMethod(RenderingMethod *method);

/**
 * setRenderingMethodInUse:
 * @method: a RenderingMethod.
 *
 * Choose the method used to render the data.
 */
void setRenderingMethodInUse(RenderingMethod* method);

/**
 * setRenderingMethodByName:
 * @name: the name of a rendering method.
 *
 * Choose the method used to render the data.
 *
 * Returns : 1 if the method exists and is set, 0 otherwise.
 */
int setRenderingMethodByName(char* name);

/**
 * getRenderingMethodInUse:
 *
 * Get the current method used to render the data.
 *
 * Returns: the name of the currently used rendering method.
 */
RenderingMethod* getRenderingMethodInUse();
/**
 * initRenderingMethods:
 *
 * Initialise all the variable of this part. It is called
 * by the main program at startup and should not be used by
 * users.
 *
 * Returns: true if everything goes right.
 */
int initRenderingMethods();




/****************/
/* Private area */
/****************/

/**
 * RenderingMethod_struct:
 * @name: a string describing the method (not NULL) ;
 * @printName: a string describing the method (not NULL) that can be safely translated ;
 * @description: a string to give a longer description to the method (can be NULL) ;
 * @icon: a path to a small 16x16 image to represent the method,
 *   if null, no image is used ;
 * @nbFilesType: the number of files required to render one set of data,
 *   for example 2 for one file with positions and one file with orientations
 *   to represent a vector field ;
 * @fileType: an array of GList* that contains #FileFormat ;
 * @fileTypeLabel: an array of string that describes each kind of file ;
 * @loadMethod: a pointer to a method used to read input data ;
 * @createElement: a pointer to a method used to create OpenGL lists for #VisuElement ;
 * @createNode: a pointer to a method used to draw a given node ;
 * @getExtensForElement: not used.
 */
struct RenderingMethod_struct
{
  /* Some variable to describe this rendering method.
     The attribute name is mandatory since it is
     used to identify the method. */
  char* name;
  char* printName;
  char* description;
  /* A path to a small 16x16 image to represent the method.
     If null, no image is used. */
  char* icon;

  /* Dealing with file type. */
  /* Number of files required to render one set of data. */
  int nbFilesType;
  /* Types of files described by this rendering method. */
  GList **fileType;
  /* Label associated to this each kind of file. */
  gchar **fileTypeLabel;

  /* Pointer to the file functions. */
  renderingMethodLoadFunc loadMethod;
  
  /* Pointers to useful openGL methods. */
  createOpenGLElementFunc createElement;
  createOpenGLNodeFunc createNode;
  getExtensOfNodeFunc getExtensForElement;
};


#endif
