#ifndef ABINIT_H
#define ABINIT_H

#include <glib.h>
#include <gio/gio.h>
#include <config.h>
#include <visu_data.h>

#if AB_LIBRARY_VERSION == 6
#ifdef HAVE_ABINIT_SYMMETRY
#include <ab6_symmetry.h>
#define AbSymmetry Ab6Symmetry
#define AbSymmetryMat Ab6SymmetryMat
#define AbSymmetryTrans Ab6SymmetryTrans
#endif
#include <ab6_invars.h>
#define AbError    Ab6Error
#define AbInvars   Ab6Invars

#define AB_NO_ERROR AB6_NO_ERROR
#define AB_ERROR_SYM_BRAVAIS_XRED AB6_ERROR_SYM_BRAVAIS_XRED
#define AB_ERROR_SYM_NOT_PRIMITIVE AB6_ERROR_SYM_NOT_PRIMITIVE
#define AB_INVARS_NTYPAT AB6_INVARS_NTYPAT
#define AB_INVARS_NATOM AB6_INVARS_NATOM
#define AB_INVARS_TYPAT AB6_INVARS_TYPAT
#define AB_INVARS_ZNUCL AB6_INVARS_ZNUCL
#define AB_INVARS_RPRIMD_ORIG AB6_INVARS_RPRIMD_ORIG
#define AB_INVARS_XRED_ORIG AB6_INVARS_XRED_ORIG
#define AB_INVARS_SPINAT AB6_INVARS_SPINAT
#define AB_INVARS_STR AB6_INVARS_STR

#define ab_mpi_init ab6_mpi_init
#define ab_error_string_from_id ab6_error_string_from_id

#define ab_invars_new_from_file_with_pseudo ab6_invars_new_from_file_with_pseudo
#define ab_invars_get_ndtset ab6_invars_get_ndtset
#define ab_invars_get_integer ab6_invars_get_integer
#define ab_invars_get_integer_array ab6_invars_get_integer_array
#define ab_invars_get_real_array ab6_invars_get_real_array
#define ab_invars_free ab6_invars_free

#ifdef HAVE_ABINIT_SYMMETRY
#define ab_symmetry_get_equivalent_atom ab7_symmetry_get_equivalent_atom
#define ab_symmetry_set_lattice ab6_symmetry_set_lattice
#define ab_symmetry_set_structure ab6_symmetry_set_structure
#define ab_symmetry_get_type ab6_symmetry_get_type
#define ab_symmetry_get_group ab6_symmetry_get_group
#define ab_symmetry_get_matrices ab6_symmetry_get_matrices
#define ab_symmetry_get_bravais ab6_symmetry_get_bravais
#define ab_symmetry_new ab6_symmetry_new
#define ab_symmetry_free ab6_symmetry_free
#define ab_symmetry_set_tolerance ab6_symmetry_set_tolerance
#endif
#endif

#if AB_LIBRARY_VERSION == 7
#include <ab7_invars.h>
#define AbInvars   Ab7Invars

#define ab_mpi_init ab7_mpi_init
#define ab_error_string_from_id ab7_error_string_from_id

#define ab_invars_new_from_file_with_pseudo ab7_invars_new_from_file_with_pseudo
#define ab_invars_get_ndtset ab7_invars_get_ndtset
#define ab_invars_get_integer ab7_invars_get_integer
#define ab_invars_get_integer_array ab7_invars_get_integer_array
#define ab_invars_get_real_array ab7_invars_get_real_array
#define ab_invars_free ab7_invars_free
#endif

#define AbError    Ab7Error
#define AB_NO_ERROR AB7_NO_ERROR
#define AB_ERROR_SYM_BRAVAIS_XRED AB7_ERROR_SYM_BRAVAIS_XRED
#define AB_ERROR_SYM_NOT_PRIMITIVE AB7_ERROR_SYM_NOT_PRIMITIVE
#define AB_INVARS_NTYPAT AB7_INVARS_NTYPAT
#define AB_INVARS_NATOM AB7_INVARS_NATOM
#define AB_INVARS_TYPAT AB7_INVARS_TYPAT
#define AB_INVARS_ZNUCL AB7_INVARS_ZNUCL
#define AB_INVARS_RPRIMD_ORIG AB7_INVARS_RPRIMD_ORIG
#define AB_INVARS_XRED_ORIG AB7_INVARS_XRED_ORIG
#define AB_INVARS_SPINAT AB7_INVARS_SPINAT
#define AB_INVARS_STR AB7_INVARS_STR

#include <ab7_symmetry.h>
#define AbSymmetry Ab7Symmetry
#define AbSymmetryMat Ab7SymmetryMat
#define AbSymmetryTrans Ab7SymmetryTrans

#define ab_symmetry_get_equivalent_atom ab7_symmetry_get_equivalent_atom
#define ab_symmetry_set_lattice ab7_symmetry_set_lattice
#define ab_symmetry_set_structure ab7_symmetry_set_structure
#define ab_symmetry_get_type ab7_symmetry_get_type
#define ab_symmetry_get_group ab7_symmetry_get_group
#define ab_symmetry_get_matrices ab7_symmetry_get_matrices
#define ab_symmetry_get_bravais ab7_symmetry_get_bravais
#define ab_symmetry_new ab7_symmetry_new
#define ab_symmetry_free ab7_symmetry_free
#define ab_symmetry_set_tolerance ab7_symmetry_set_tolerance

struct _abinitData
{
  VisuData *data;
  GCancellable *cancel;
  GError *error;

  /* Queue to send messages from V_Sim to ABINIT thread. */
  GAsyncQueue *signals;
  gboolean useSignals;

  /* Queue to send messages from the ABINIT thread to
     V_Sim. */
  GAsyncQueue *messages;
  gboolean getMessages;

  /* Data for the invars part. */
#ifdef HAVE_ABINIT_PARSER
  AbInvars *dt;
  gchar *filename;
  int nSet;
  gboolean isABFormat;
#endif

  /* Data for the symmetries. */
  AbSymmetry *sym;
};
typedef struct _abinitData AbinitData;

void abinit_mutexInit();
void abinit_mutexRelease();
void abinit_mutexUnlock();
AbinitData* abinit_getDt();
AbinitData* abinit_getDirectDt();

#endif
