/*   EXTRAITS DE LA LICENCE
	Copyright CEA, contributeurs : Damien
	CALISTE, laboratoire L_Sim, (2015)
  
	Adresse 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 : Damien
	CALISTE, laboratoire L_Sim, (2015)

	E-mail address:
	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_PLANE_SET_H
#define VISU_PLANE_SET_H

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

#include "plane.h"
#include <visu_data.h>
#include <iface_nodemasker.h>

/***************/
/* Public part */
/***************/

/**
 * VISU_TYPE_PLANE_SET:
 *
 * return the type of #VisuPlaneSet.
 */
#define VISU_TYPE_PLANE_SET	     (visu_plane_set_get_type ())
/**
 * VISU_PLANE_SET:
 * @obj: a #GObject to cast.
 *
 * Cast the given @obj into #VisuPlaneSet type.
 */
#define VISU_PLANE_SET(obj)	        (G_TYPE_CHECK_INSTANCE_CAST(obj, VISU_TYPE_PLANE_SET, VisuPlaneSet))
/**
 * VISU_PLANE_SET_CLASS:
 * @klass: a #GObjectClass to cast.
 *
 * Cast the given @klass into #VisuPlaneSetClass.
 */
#define VISU_PLANE_SET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST(klass, VISU_TYPE_PLANE_SET, VisuPlaneSetClass))
/**
 * VISU_IS_PLANE_SET:
 * @obj: a #GObject to test.
 *
 * Test if the given @ogj is of the type of #VisuPlaneSet object.
 */
#define VISU_IS_PLANE_SET(obj)    (G_TYPE_CHECK_INSTANCE_TYPE(obj, VISU_TYPE_PLANE_SET))
/**
 * VISU_IS_PLANE_SET_CLASS:
 * @klass: a #GObjectClass to test.
 *
 * Test if the given @klass is of the type of #VisuPlaneSetClass class.
 */
#define VISU_IS_PLANE_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE(klass, VISU_TYPE_PLANE_SET))
/**
 * VISU_PLANE_SET_GET_CLASS:
 * @obj: a #GObject to get the class of.
 *
 * It returns the class of the given @obj.
 */
#define VISU_PLANE_SET_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS(obj, VISU_TYPE_PLANE_SET, VisuPlaneSetClass))


/**
 * VisuPlaneSetPrivate:
 * 
 * Private data for #VisuPlaneSet objects.
 */
typedef struct _VisuPlaneSetPrivate VisuPlaneSetPrivate;

/**
 * VisuPlaneSet:
 * 
 * Common name to refer to a #_VisuPlaneSet.
 */
typedef struct _VisuPlaneSet VisuPlaneSet;
struct _VisuPlaneSet
{
  VisuObject parent;

  VisuPlaneSetPrivate *priv;
};

/**
 * VisuPlaneSetClass:
 * @parent: private.
 * 
 * Common name to refer to a #_VisuPlaneSetClass.
 */
typedef struct _VisuPlaneSetClass VisuPlaneSetClass;
struct _VisuPlaneSetClass
{
  VisuObjectClass parent;
};

/**
 * visu_plane_set_get_type:
 *
 * This method returns the type of #VisuPlaneSet, use
 * VISU_TYPE_PLANE_SET instead.
 *
 * Since: 3.8
 *
 * Returns: the type of #VisuPlaneSet.
 */
GType visu_plane_set_get_type(void);

/**
 * VisuPlaneSetItemNew:
 * @plane: a #VisuPlane object.
 * @data: some user data.
 *
 * A method to generate a new plane item in the plane set for
 * @plane. This method is called to encapsulate @plane when @plane is
 * added to the plane set.
 *
 * Since: 3.8
 */
typedef gpointer (*VisuPlaneSetItemNew)(VisuPlane *plane, gpointer data);
/**
 * VisuPlaneSetItemFree:
 * @plane: a #VisuPlane object.
 * @data: some user data.
 *
 * A method to free a given plane item in the plane set for
 * @plane. This method is called when @plane is removed from the plane set.
 *
 * Since: 3.8
 */
typedef void (*VisuPlaneSetItemFree)(VisuPlane *plane, gpointer data);

VisuPlaneSet* visu_plane_set_new();
VisuPlaneSet* visu_plane_set_newFull(VisuPlaneSetItemNew newItem,
                                     VisuPlaneSetItemFree freeItem,
                                     gpointer data);

gboolean visu_plane_set_add(VisuPlaneSet *set, VisuPlane *plane);
gboolean visu_plane_set_remove(VisuPlaneSet *set, VisuPlane *plane);
gboolean visu_plane_set_removeAll(VisuPlaneSet *set);

VisuPlane* visu_plane_set_getAt(const VisuPlaneSet *set, guint i);

typedef struct _VisuPlaneSetIter VisuPlaneSetIter;
struct _VisuPlaneSetIter
{
  const VisuPlaneSet *set;
  VisuPlane *plane;

  GList *next;
};
gboolean visu_plane_set_iter_new(const VisuPlaneSet *set, VisuPlaneSetIter *iter);
gboolean visu_plane_set_iter_next(VisuPlaneSetIter *iter);

gboolean visu_plane_set_getIntersection(const VisuPlaneSet *set, float pointA[3],
                                        float pointB[3], float inter[3], gboolean inside);

/**
 * VisuPlaneSetHiddingEnum:
 * @VISU_PLANE_SET_HIDE_UNION: element are masked if one plane at least mask it ;
 * @VISU_PLANE_SET_HIDE_INTER: element are masked if all planes mask it ;
 * @VISU_PLANE_SET_HIDE_N_VALUES: number of masking possibilities.
 *
 * Enum used to address different hiding modes. See visu_plane_set_setHiddingMode() for
 * further details.
 */
typedef enum
  {
    VISU_PLANE_SET_HIDE_UNION,
    VISU_PLANE_SET_HIDE_INTER,
    VISU_PLANE_SET_HIDE_N_VALUES
  } VisuPlaneSetHiddingEnum;
gboolean visu_plane_set_setHiddingMode(VisuPlaneSet *set, VisuPlaneSetHiddingEnum mode);

gboolean visu_plane_set_getHiddingStatus(const VisuPlaneSet *set);
gboolean visu_plane_set_getVisibility(const VisuPlaneSet *set, float point[3]);

gboolean visu_plane_set_parseXMLFile(VisuPlaneSet *set, const gchar* filename, GError **error);
gboolean visu_plane_set_exportXMLFile(const VisuPlaneSet *set, const gchar* filename, GError **error);

#endif
