/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

/*--  Header file for Metview Macro C/C++ interface functions  --*/

#pragma once

#include "grib_api.h"

#ifndef fortint
#define fortint int
#endif

#ifndef fortfloat
#define fortfloat double
#endif

#define MV_ALLOW_DEPRECATED_MCI_NAMES 1


#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif


/*------------------------  macro C/C++ interface routines --------------------------*/

/*--   'mci_' : M(acro) C I(nterface)   --*/

double mci_get_number();
void mci_return_number(double d);

const char* mci_get_string();
void mci_return_string(const char* s);

void mci_get_vector(double** vec, int* length);
void mci_return_vector(double* vec, int length);

void* mci_get_fieldset(int* field_count);           /* use 'void*' in order to hide 'mars.h' */
grib_handle* mci_load_one_grib(void* fieldset_ptr); /* handle must be deleted by calling pgm */
void mci_rewind_fieldset(void* fieldset_ptr);

void* mci_new_fieldset(); /* use 'void*' in order to hide 'mars.h' */
void mci_save_grib(void* fieldset_ptr, grib_handle* gh);
void mci_return_fieldset(void* fieldset_ptr);

#ifdef MV_ALLOW_DEPRECATED_MCI_NAMES
/*--  old names that confusingly use 'grib_id' for a 'fieldset' --*/
void* mci_get_grib_id_ptr(int* field_count); /* mci_get_fieldset()    */
void mci_rewind_grib(void* grib_id_ptr);     /* mci_rewind_fieldset() */
void* mci_new_grib_id_ptr();                 /* mci_new_fieldset()    */
void mci_return_grib(void* grib_id_ptr);     /* mci_return_fieldset() */
#endif

int mci_arg_count();
const char* mci_args();
void mci_fail(const char* msg);


/*---------------------- second generation macro Fortran interface routines -----------------------*/

/*-- 'mfi_' : M(acro) F(ortran) I(nterface) / functions written in C --*/

void mfi_get_number_(fortfloat* d);
void mfi_return_number_(fortfloat* d);

void mfi_get_string_(char* s, fortint s_len);
void mfi_return_string_(char* s, fortint s_len);

void mfi_get_vector_(double* vec, int* length);
void mfi_return_vector_(double* vec, int* length);

void mfi_get_fieldset_(fortint* fieldset_id_index, fortint* field_count);
void mfi_rewind_fieldset_(fortint* fieldset_id);

void mfi_new_fieldset_(fortint* fieldset_id_index);
void mfi_return_fieldset_(fortint* fieldset_id);

void mfi_args_(fortint* c, char* a, fortint a_len);
void mfi_fail_(char* msg, fortint a_len);

/*--  'mfi_' : M(acro) F(ortran) I(nterface) / routines written in Fortran 90  --*/

/*      subroutine mfi_load_one_grib( ifieldset_id, igrib_id ) - implemented in Fortran90 */
/*      subroutine mfi_save_grib( ifieldset_id, igrib_id )     - implemented in Fortran90 */


/*-- 'mifi_' : M(acro) I(nternal) F(ortran) I(nterface) --*/

void mifi_get_msg_length_(fortint* fieldset_id_index, fortint* msg_len);
void mifi_load_one_grib_to_memory_(fortint* fieldset_id_index, char* grib_in_memory);
void mifi_save_one_grib_to_file_(fortint* fieldset_id_index, char* grib_data, fortint* bytecount);


/*-- original first generation Fortran callable interface (sub)routines --*/

void mnewb_(); /*-- b: BUFR - not yet implemented --*/
void mgetb_();
void msetb_();
void mloadb_();
void msaveb_();

void mgetg_(fortint* g, fortint* c); /*-- g: fieldsets (GRIB msgs) --*/
void mloadg_(fortint* g, char* p, fortint* c);
void mrewg_(fortint* g);
void mnewg_(fortint* g);
void msaveg_(fortint* g, char* p, fortint* c);
void msavebyteg_(fortint* g, char* p, fortint* c);
void msetg_(fortint* g);

void mgeti_(fortint* g, fortint* c); /*-- i: images --*/
void mseti_(fortint* g);

void mgetm_(); /*-- m: matrices - not yet implemented --*/
void msetm_();

void mgetn_(fortfloat* f); /*-- n: floats (numbers, size of  Fortran REAL) --*/
void msetn_(fortfloat* f);

void mgetn2_(double* d); /*-- n2: doubles (numbers, size of C double) --*/
void msetn2_(double* d);

void mgets_(char* s, fortint l_s); /*-- s: strings --*/
void msets_(char* s, fortint l_s);

void mgetv_(fortint* s, fortfloat* v); /*-- v: vectors --*/
void msetv_(fortint* s, fortfloat* v);

/*-- miscellenius --*/
void margs_(fortint* cnt, char* types, fortint l_types);
void mfail_(char* msg, fortint l_msg);

#if defined(__cplusplus) || defined(c_plusplus)
}
#endif

/*-- MACRO_API_H --*/
