#ifndef DDS_INTERFACE
#define DDS_INTERFACE

#ifdef __cplusplus
extern "C" {
#endif
  
  typedef struct 
  {
    int np[4]; //number of processes in each dimension t x y z
    int gl[4]; //global lattice size t x y z
    int npr[8]; //tm, tp, xm, xp, ym, yp, zm, zp MPI ranks of neigh. proc.
    int cpr[4]; //t, x, y, z  cartesian coords of this proc.
    int id; // MPI rank of this proc.
  } dds_lat_grid;
  
  
  /* init */  
  void dds_init(dds_lat_grid *par);
  void dds_tune(int nbr, int ncy, int nkv, int ndfl, int blkrel, int *bs);

  /* IN/OUT */
  double *dds_sptr_src(int t, int x, int y, int z);
  double *dds_sptr_dst(int t, int x, int y, int z);
  double *dds_uptr(int t, int x, int y, int z, int mu);
      
    
  /* after updating the gauge fld call this function to notify the solver (update sw term, etc) */
  void dds_gauge_updated();
  
  /* solve */
  int dds_solve(double kappa, double csw, double tol, int nmx, double *res); 
 
  /* dirac */
  void dds_dirac(double kappa, double csw); 
  void dds_clover(double kappa, double csw); 
 
  
#ifdef __cplusplus  
}
#endif

#endif


#ifdef NamesToLower_
# define dds_init_fc dds_init_fc_
# define dds2 dds2_
# define dd_put_gauge dd_put_gauge_
# define dds_clover_fc  dds_clover_fc_
# define dd_put_gauge  dd_put_gauge_
# define ddg ddg_
# define dds_tune_fc dds_tune_fc_
# define dds_solve_fc dds_solve_fc_
# define dds_spinor_src_put_fc dds_spinor_src_put_fc_
# define dds_spinor_dst_get_fc dds_spinor_dst_get_fc_
# define dds_gauge_updated_fc dds_gauge_updated_fc_
#endif

#ifdef NamesToLower__
# define dds_init_fc dds_init_fc__
# define dds2 dds2__
# define dd_put_gauge dd_put_gauge__
# define dds_clover_fc  dds_clover_fc__
# define dd_put_gauge  dd_put_gauge__
# define ddg ddg__
# define dds_tune_fc dds_tune_fc__
# define dds_solve_fc dds_solve_fc__
# define dds_spinor_src_put_fc dds_spinor_src_put_fc__
# define dds_spinor_dst_get_fc dds_spinor_dst_get_fc__
# define dds_gauge_updated_fc dds_gauge_updated_fc__
#endif
