#include <glib.h>
#include <visu_data.h>

G_BEGIN_DECLS

/**
 * VISU_TYPE_CRYSTALFP:
 *
 * return the type of #VisuCrystalfp.
 *
 * Since: 3.8
 */
#define VISU_TYPE_CRYSTALFP	     (visu_crystalfp_get_type ())
/**
 * VISU_CRYSTALFP:
 * @obj: a #GObject to cast.
 *
 * Cast the given @obj into #VisuCrystalfp type.
 *
 * Since: 3.8
 */
#define VISU_CRYSTALFP(obj)	     (G_TYPE_CHECK_INSTANCE_CAST(obj, VISU_TYPE_CRYSTALFP, VisuCrystalfp))
/**
 * VISU_CRYSTALFP_CLASS:
 * @klass: a #GObjectClass to cast.
 *
 * Cast the given @klass into #VisuCrystalfpClass.
 *
 * Since: 3.8
 */
#define VISU_CRYSTALFP_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST(klass, VISU_TYPE_CRYSTALFP, VisuCrystalfpClass))
/**
 * VISU_IS_CRYSTALFP:
 * @obj: a #GObject to test.
 *
 * Test if the given @ogj is of the type of #VisuCrystalfp object.
 *
 * Since: 3.8
 */
#define VISU_IS_CRYSTALFP(obj)    (G_TYPE_CHECK_INSTANCE_TYPE(obj, VISU_TYPE_CRYSTALFP))
/**
 * VISU_IS_CRYSTALFP_CLASS:
 * @klass: a #GObjectClass to test.
 *
 * Test if the given @klass is of the type of #VisuCrystalfpClass class.
 *
 * Since: 3.8
 */
#define VISU_IS_CRYSTALFP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE(klass, VISU_TYPE_CRYSTALFP))
/**
 * VISU_CRYSTALFP_GET_CLASS:
 * @obj: a #GObject to get the class of.
 *
 * It returns the class of the given @obj.
 *
 * Since: 3.8
 */
#define VISU_CRYSTALFP_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS(obj, VISU_TYPE_CRYSTALFP, VisuCrystalfpClass))

typedef struct _VisuCrystalfp        VisuCrystalfp;
typedef struct _VisuCrystalfpPrivate VisuCrystalfpPrivate;
typedef struct _VisuCrystalfpClass   VisuCrystalfpClass;

struct _VisuCrystalfp
{
  GObject parent;

  VisuCrystalfpPrivate *priv;
};

struct _VisuCrystalfpClass
{
  GObjectClass parent;
};

typedef enum
  {
    VISU_CRYSTALFP_PER_ELEMENT_DIFFRACTION
  } VisuCrystalfpMethod;

typedef enum
  {
    VISU_CRYSTALFP_DISTANCE_COSINE,
    VISU_CRYSTALFP_DISTANCE_EUCLIDEAN,
    VISU_CRYSTALFP_DISTANCE_MINKOWSKI_ONE_THIRD
  } VisuCrystalfpDistanceMethod;

/**
 * VisuCrystalfp2DPlot:
 * @x:
 * @y:
 * @totalEnergy:
 * @perAtEnergy:
 * @stress:
 *
 * Since: 3.8
 */
typedef struct _VisuCrystalfp2DPlot VisuCrystalfp2DPlot;
struct _VisuCrystalfp2DPlot
{
  float x, y;
  float totalEnergy, perAtEnergy, stress;
};

/**
 * visu_crystalfp_get_type:
 *
 * This method returns the type of #VisuCrystalfp, use
 * VISU_TYPE_CRYSTALFP instead.
 *
 * Since: 3.8
 *
 * Returns: the type of #VisuCrystalfp.
 */
GType visu_crystalfp_get_type(void);

VisuCrystalfp* visu_crystalfp_new();
void visu_crystalfp_addStructure(VisuCrystalfp *fp, VisuData *data);
float visu_crystalfp_computeCutoffDistance(VisuCrystalfp *fp, float margin);
GArray* visu_crystalfp_getFingerprint(VisuCrystalfp *fp, VisuData *data);
float visu_crystalfp_getDistance(VisuCrystalfp *fp, VisuData *data1, VisuData *data2,
                                 VisuCrystalfpDistanceMethod meth);
GArray* visu_crystalfp_get2DPlot(VisuCrystalfp *fp,
                                 guint retries, guint maxIter,
                                 float min_energy, float timestep);

G_END_DECLS
