
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

#if defined (HAVE_CF_INTERFACE)
#  if defined __clang__
#    pragma GCC diagnostic push
#    pragma GCC diagnostic ignored "-Wreserved-id-macro"
#  endif
#  include "cfortran.h"
#  if defined __clang__
#    pragma GCC diagnostic pop
#  endif

#if ! defined   (GRIBFORTRAN_H)
#  include "gribFortran.h"
#endif

/*
  Rename PBIO routines if RENAME_PB is set
*/
#if  defined  (RENAME_PB)
#  define  pbopen   pb_open
#  define  pbclose  pb_close
#  define  pbread   pb_read
#  define  pbwrite  pb_write
#  define  pbseek   pb_seek
#  define  pbseek64 pb_seek64
#  define  pbtell   pb_tell
#  define  pbflush  pb_flush
#  define  pbsize   pb_size
#  define  pbgrib   pb_grib
#  define  pbsetraw pb_setraw
#endif

/*
    Rename GRIB routines if RENAME_GR is set
*/
#if  defined  (RENAME_GR)
#  define  gribex   gr_ibex
#  define  grprs0   gr_prs0
#  define  grprs1   gr_prs1
#  define  grprs2   gr_prs2
#  define  grprs3   gr_prs3
#  define  grprs4   gr_prs4
#  define  grsdbg   gr_sdbg
#  define  grsrnd   gr_srnd
#  define  grsref   gr_sref
#  define  grsvck   gr_svck
#endif

/*
  PDOUBLE on old CRAY PVPs has been 128bit, but that is not true anymore
*/
/* #if  defined  (CRAY) */
/* #  define  PDOUBLE  PFLOAT */
/* #endif */

/* These functions are meant to be called from Fortran and don't
 * need an interface declaration in a C header. */
#if defined __clang__
#  pragma GCC diagnostic push
#  pragma GCC diagnostic ignored "-Wmissing-prototypes"
#endif
/*
  PBIO
*/
FCALLSCSUB4 (pbOpen,   PBOPEN,   pbopen,   PINT, STRING, STRING, PINT)
FCALLSCSUB2 (pbClose,  PBCLOSE,  pbclose,  INT, PINT)
FCALLSCSUB4 (pbRead,   PBREAD,   pbread,   INT, PVOID, INT, PINT)
FCALLSCSUB4 (pbWrite,  PBWRITE,  pbwrite,  INT, PVOID, INT, PINT)
FCALLSCSUB4 (pbSeek,   PBSEEK,   pbseek,   INT, INT, INT, PINT)
FCALLSCSUB2 (pbTell,   PBTELL,   pbtell,   INT, PINT)
FCALLSCSUB1 (pbFlush,  PBFLUSH,  pbflush,  INT)
FCALLSCSUB2 (pbSize,   PBSIZE,   pbsize,   INT, PINT)
FCALLSCSUB5 (pbGrib,   PBGRIB,   pbgrib,   INT, PVOID, INT, PINT, PINT)
FCALLSCSUB2 (pbSetRaw, PBSETRAW, pbsetraw, INT, INT)
/*
  Extension: large file support for Fortran using 64 Bit integers [ha]
 */
FCALLSCSUB4 (pbSeek64, PBSEEK,   pbseek64, INT, LONGLONG, INT, PLONGLONG)

/*
  GRIBEX Print
*/
FCALLSCSUB1 (gribprs0,    GRPRS0,    grprs0,    PINT)
FCALLSCSUB2 (gribprs1,    GRPRS1,    grprs1,    PINT, PINT)

FCALLSCSUB3 (gribprs2,    GRPRS2,    grprs2,    PINT, PINT, PVOID)
FCALLSCSUB3 (gribprs2dp,  GRPRS2DP,  grprs2dp,  PINT, PINT, PDOUBLE)
FCALLSCSUB3 (gribprs2sp,  GRPRS2SP,  grprs2sp,  PINT, PINT, PFLOAT)

FCALLSCSUB3 (gribprs3,    GRPRS3,    grprs3,    PINT, PINT, PVOID)
FCALLSCSUB3 (gribprs3dp,  GRPRS3DP,  grprs3dp,  PINT, PINT, PDOUBLE)
FCALLSCSUB3 (gribprs3sp,  GRPRS3SP,  grprs3sp,  PINT, PINT, PFLOAT)

FCALLSCSUB3 (gribprs4,    GRPRS4,    grprs4,    PINT, PINT, PVOID)
FCALLSCSUB3 (gribprs4dp,  GRPRS4DP,  grprs4dp,  PINT, PINT, PDOUBLE)
FCALLSCSUB3 (gribprs4sp,  GRPRS4SP,  grprs4sp,  PINT, PINT, PFLOAT)

/*
  GRIBEX
*/
FCALLSCSUB14 (gribEx,   GRIBEX,    gribex,    PINT, PINT, PINT, PVOID ,  PINT,
	       PVOID,   PINT, PVOID,   INT,   PINT,  INT, PINT, STRING,  PINT)
FCALLSCSUB14 (gribExDP, GRIBEXDP,  gribexdp,  PINT, PINT, PINT, PDOUBLE, PINT,
               PDOUBLE, PINT, PDOUBLE,  INT,  PINT,  INT, PINT, STRING,  PINT)
FCALLSCSUB14 (gribExSP, GRIBEXSP,  gribexsp,  PINT, PINT, PINT, PFLOAT,  PINT,
               PFLOAT,  PINT, PFLOAT,  INT,   PINT,  INT, PINT, STRING,  PINT)

/*
  GRIBEX defaults
*/
FCALLSCSUB1 (gribsdbg,    GRSDBG,    grsdbg,    INT)
FCALLSCSUB1 (gribsrnd,    GRSRND,    grsrnd,    INT)
FCALLSCSUB1 (gribsref,    GRSREF,    grsref,    PVOID)
FCALLSCSUB1 (gribsrefsp,  GRSREFSP,  grsrefsp,  FLOAT)
FCALLSCSUB1 (gribsrefdp,  GRSREFDP,  grsrefdp,  DOUBLE)
FCALLSCSUB1 (gribsvck,    GRSVCK,    grsvck,    INT)


FCALLSCSUB2 (flt2ibmXX,   FLT2IBM,    flt2ibm,    PVOID,      PINT)
FCALLSCSUB2 (ibm2fltXX,   IBM2FLT,    ibm2flt,    PINT,      PVOID)
FCALLSCSUB2 (flt2ibmSP,   FLT2IBMSP,  flt2ibmsp,  PFLOAT,     PINT)
FCALLSCSUB2 (ibm2fltSP,   IBM2FLTSP,  ibm2fltsp,  PINT,     PFLOAT)
FCALLSCSUB2 (flt2ibmDP,   FLT2IBMDP,  flt2ibmdp,  PDOUBLE,    PINT)
FCALLSCSUB2 (ibm2fltDP,   IBM2FLTDP,  ibm2fltdp,  PINT,    PDOUBLE)

#if defined __clang__
#  pragma GCC diagnostic pop
#endif

void gribEx(int *isec0, int *isec1, int *isec2, void *fsec2, int *isec3,
            void *fsec3, int *isec4, void *fsec4, int klenp, int *kgrib,
            int kleng, int *kword, const char *hoper, int *kret)
{
#if defined (FORT_REAL4)
  gribExSP(isec0, isec1, isec2, (float *) fsec2, isec3,
	   (float *) fsec3, isec4, (float *) fsec4, klenp, kgrib,
	   kleng, kword, hoper, kret);
#else
  gribExDP(isec0, isec1, isec2, (double *) fsec2, isec3,
	   (double *) fsec3, isec4, (double *) fsec4, klenp, kgrib,
	   kleng, kword, hoper, kret);
#endif
}

void gribprs2(int *isec0, int *isec2, void *fsec2)
{
#if defined (FORT_REAL4)
  gribprs2sp(isec0, isec2, (float *) fsec2);
#else
  gribprs2dp(isec0, isec2, (double *) fsec2);
#endif
}

void gribprs3(int *isec0, int *isec3, void *fsec3)
{
#if defined (FORT_REAL4)
  gribprs3sp(isec0, isec3, (float *) fsec3);
#else
  gribprs3dp(isec0, isec3, (double *) fsec3);
#endif
}

void gribprs4(int *isec0, int *isec4, void *fsec4)
{
#if defined (FORT_REAL4)
  gribprs4sp(isec0, isec4, (float *) fsec4);
#else
  gribprs4dp(isec0, isec4, (double *) fsec4);
#endif
}

void gribprs0(int *isec0)
{
  gribPrintSec0(isec0);
}

void gribprs1(int *isec0, int *isec1)
{
  gribPrintSec1(isec0, isec1);
}

void gribprs2dp(int *isec0, int *isec2, double *fsec2)
{
  gribPrintSec2DP(isec0, isec2, fsec2);
}

void gribprs2sp(int *isec0, int *isec2, float  *fsec2)
{
  gribPrintSec2SP(isec0, isec2, fsec2);
}

void gribprs3dp(int *isec0, int *isec3, double *fsec3)
{
  gribPrintSec3DP(isec0, isec3, fsec3);
}

void gribprs3sp(int *isec0, int *isec3, float  *fsec3)
{
  gribPrintSec3SP(isec0, isec3, fsec3);
}

void gribprs4dp(int *isec0, int *isec4, double *fsec4)
{
  gribPrintSec4DP(isec0, isec4, fsec4);
}

void gribprs4sp(int *isec0, int *isec4, float  *fsec4)
{
  gribPrintSec4SP(isec0, isec4, fsec4);
}

void gribprs4w(int *isec4)
{
  gribPrintSec4Wave(isec4);
}

void gribsdbg(int debug)
{
  gribSetDebug(debug);
}

void gribsrnd(int round)
{
  gribSetRound(round);
}

void gribsref(void *fref)
{
#if defined (FORT_REAL4)
  gribSetRefSP(*((float *) fref));
#else
  gribSetRefDP(*((double *) fref));
#endif
}

void gribsrefdp(double fref)
{
  gribSetRefDP(fref);
}

void gribsrefsp(float fref)
{
  gribSetRefSP(fref);
}

void gribsvck(int vcheck)
{
  gribSetValueCheck(vcheck);
}

void flt2ibmXX(void *rval, int *ival)
{
#if defined (FORT_REAL4)
  flt2ibmSP((float *) rval, ival);
#else
  flt2ibmDP((double *) rval, ival);
#endif
}

void ibm2fltXX(int *ival, void *rval)
{
#if defined (FORT_REAL4)
  ibm2fltSP(ival, (float *) rval);
#else
  ibm2fltDP(ival, (double *) rval);
#endif
}

#endif /* HAVE_CF_INTERFACE */
