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

#include <glib.h>
#include <glib-object.h>

G_BEGIN_DECLS

/**
 * TOOL_XYZ_MASK_X:
 *
 * This value can be used to create a mask for methods that
 * require one for reading xyz coordinates array. This value actually
 * correspond to the x direction.
 *
 * Since: 3.3
 */
#define TOOL_XYZ_MASK_X (1 << 0)
/**
 * TOOL_XYZ_MASK_Y:
 *
 * This value can be used to create a mask for methods that
 * require one for reading xyz coordinates array. This value actually
 * correspond to the y direction.
 *
 * Since: 3.3
 */
#define TOOL_XYZ_MASK_Y (1 << 1)
/**
 * TOOL_XYZ_MASK_Z:
 *
 * This value can be used to create a mask for methods that
 * require one for reading xyz coordinates array. This value actually
 * correspond to the z direction.
 *
 * Since: 3.3
 */
#define TOOL_XYZ_MASK_Z (1 << 2)
/**
 * TOOL_XYZ_MASK_ALL:
 *
 * This value can be used to create a mask for methods that
 * require one for reading xyz coordinates array. This value is a
 * shortcut for #TOOL_XYZ_MASK_X | #TOOL_XYZ_MASK_Y | #TOOL_XYZ_MASK_Z.
 *
 * Since: 3.3
 */
#define TOOL_XYZ_MASK_ALL (7)

/**
 * ToolXyzDir:
 * @TOOL_XYZ_X: the x axis;
 * @TOOL_XYZ_Y: the y axis;
 * @TOOL_XYZ_Z: the z axis.
 *
 * The three space axis.
 *
 * Since: 3.8
 */
typedef enum {
  TOOL_XYZ_X,
  TOOL_XYZ_Y,
  TOOL_XYZ_Z
} ToolXyzDir;

/**
 * TOOL_PI180:
 *
 * Value of pi / 180.
 */
#define TOOL_PI180 0.017453292522

void tool_matrix_setIdentity(float mat[3][3]);
void tool_matrix_set(float mat[3][3], float orig[3][3]);
void tool_matrix_dtof(float mf[3][3], double md[3][3]);
void tool_matrix_productMatrix(float matRes[3][3], float matA[3][3], float matB[3][3]);
void tool_matrix_productVector(float vectRes[3], float mat[3][3], float vect[3]);
gboolean tool_matrix_invert(float inv[3][3], float mat[3][3]);
float tool_matrix_determinant(float mat[3][3]);
void tool_matrix_rotate(float mat[3][3], float angle, ToolXyzDir dir);

gboolean tool_matrix_reducePrimitiveVectors(double reduced[6], double full[3][3]);
gboolean tool_matrix_getRotationFromFull(float rot[3][3],
				       double full[3][3], double box[6]);

/**
 * ToolMatrixSphericalCoord:
 * @TOOL_MATRIX_SPHERICAL_MODULUS: the modulus of a spherical vector.
 * @TOOL_MATRIX_SPHERICAL_THETA: the theta angle of a spherical vector.
 * @TOOL_MATRIX_SPHERICAL_PHI: the phi angle of a spherical vector.
 *
 * This is used to access the ordering of the vectors with
 * tool_matrix_cartesianToSpherical() or with
 * tool_matrix_sphericalToCartesian().
 *
 * Since: 3.6
 */
typedef enum
  {
    TOOL_MATRIX_SPHERICAL_MODULUS,
    TOOL_MATRIX_SPHERICAL_THETA,
    TOOL_MATRIX_SPHERICAL_PHI
  } ToolMatrixSphericalCoord;
void tool_matrix_cartesianToSpherical(float spherical[3], const float cartesian[3]);
void tool_matrix_sphericalToCartesian(float cartesian[3], const float spherical[3]);
float tool_vector_spherical(const float cart[3], ToolMatrixSphericalCoord at);

/**
 * ToolMatrixScalingFlag:
 * @TOOL_MATRIX_SCALING_LINEAR: a linear convertion from [min,max] to [0,1] ;
 * @TOOL_MATRIX_SCALING_LOG: a TOOL_MATRIX_SCALING_LOGic transformation from [min,max] to [0,1], the
 * formula is -(f(x) - f(m) / f(m) where f(x) =
 * ln((x-xmin)/(xmax-xmin)) ;
 * @TOOL_MATRIX_SCALING_ZERO_CENTRED_LOG: a TOOL_MATRIX_SCALING_LOGic transformation for data that are
 * zero centred, the formula is
 * 0.5+s*(log(MAX*SEUIL)-log(max(abs(x),MAX*SEUIL)))/(2*log(SEUIL))
 * where s is the sign, max=max(xmax,-xmin) and seuil a parameter
 * (1e-5).
 * @TOOL_MATRIX_SCALING_N_VALUES: number of available scale functions.
 *
 * Flag used to specify the transformation for maps, see scalarFieldDraw_map()
 * routine.
 *
 * Since: 3.4
 */
typedef enum
  {
    TOOL_MATRIX_SCALING_LINEAR,
    TOOL_MATRIX_SCALING_LOG,
    TOOL_MATRIX_SCALING_ZERO_CENTRED_LOG,
    TOOL_MATRIX_SCALING_N_VALUES
  } ToolMatrixScalingFlag;
/**
 * tool_matrix_getScaledValue:
 * @x: the initial value ;
 * @minmax: the boundaries for the @x argument.
 *
 * Transform @x into [0;1] using the given @minmax values.
 *
 * Returns: a value into [0;1].
 *
 * Since: 3.4
 */
typedef float (*tool_matrix_getScaledValue)(float x, float minmax[2]);
float tool_matrix_getScaledLinear(float x, float minmax[2]);
float tool_matrix_getScaledLog(float x, float minmax[2]);
float tool_matrix_getScaledZeroCentredLog(float x, float minmax[2]);

float tool_matrix_getScaledLinearInv(float x, float minmax[2]);
float tool_matrix_getScaledLogInv(float x, float minmax[2]);
float tool_matrix_getScaledZeroCentredLogInv(float x, float minmax[2]);

gboolean tool_matrix_getInter2D(float *lambda,
			   float a[2], float b[2], float A[2], float B[2]);
gboolean tool_matrix_getInter2DFromList(float i[2], float *lambda,
				   float a[2], float b[2], GList *set);

/* These structures are used for bindings. */
#define    TOOL_TYPE_VECTOR (tool_vector_get_type())
GType      tool_vector_get_type(void);

gboolean tool_vector_set(float dest[3], const float orig[3]);

float* tool_vector_new(const float orig[3]);

/* typedef gfloat[3] ToolVector; */

/* typedef struct _ToolVector ToolVector; */
/* struct _ToolVector */
/* { */
/*   float vect[3]; */
/* }; */
typedef struct _ToolGridSize ToolGridSize;
struct _ToolGridSize
{
  guint grid[3];
};

void tool_matrix_init(void);

/* These structures are used for bindings. */
#define    TOOL_TYPE_MINMAX (tool_minmax_get_type())
GType      tool_minmax_get_type(void);

void tool_minmax(float global[2], const float minmax[2]);
void tool_minmax_fromDbl(float global[2], const double minmax[2]);

/**
 * ToolScalingId:
 * @TOOL_SCALING_NORMALIZE: input data are converted into [0;1] using input min/max values.
 * @TOOL_SCALING_MINMAX: input data are converted into [0;1] using user defined min/max values.
 *
 * Control how input data are converted into [0;1], after conversion,
 * values are clamped if needed.
 */
typedef enum
  {
    TOOL_SCALING_NORMALIZE,
    TOOL_SCALING_MINMAX
  } ToolScalingId;

G_END_DECLS

#endif
