/*
  This file is part of CDO. CDO is a collection of Operators to manipulate and analyse Climate model Data.

  Author: Uwe Schulzweida

*/
#ifndef GRIDDES_H
#define GRIDDES_H

#include <vector>
#include <string>
#include <cdi.h>

constexpr double undef_grid_value = 9.e20;

struct // GridDesciption
#ifdef WARN_UNUSED
[[gnu::warn_unused]]
#endif
GridDesciption
{
  std::vector<int> mask;
  std::vector<double> xvals;
  std::vector<double> yvals;
  std::vector<double> xbounds;
  std::vector<double> ybounds;
  std::vector<double> area;
  std::vector<int> reducedPoints;
  double xfirst = undef_grid_value, yfirst = undef_grid_value;
  double xlast = undef_grid_value, ylast = undef_grid_value;
  double xinc = undef_grid_value, yinc = undef_grid_value;
  double xpole = 0.0, ypole = 0.0, angle = 0.0;  // rotated north pole
  int scanningMode = 64;
  /*
    scanningMode  = 128 * iScansNegatively + 64 * jScansPositively + 32 * jPointsAreConsecutive;
              64  = 128 * 0                + 64 *        1         + 32 * 0
              00  = 128 * 0                + 64 *        0         + 32 * 0
              96  = 128 * 0                + 64 *        1         + 32 * 1
    Default  implicit scanning mode is 64: i and j scan positively, i points are consecutive (row-major)
  */
  double a = 0.0;
  int isRotated = 0;  // true for rotated grids
  int datatype = CDI_UNDEFID;
  int type = CDI_UNDEFID;
  int ntr = 0;
  int nvertex = 0;
  size_t size = 0;
  size_t xsize = 0;
  size_t ysize = 0;
  int numLPE = 0;
  int lcomplex = 1;
  bool genBounds = false;
  int nd = 0, ni = 0, ni2 = 0, ni3 = 0;
  int number = 0, position = 0;
  unsigned char uuid[CDI_UUID_SIZE] = { 0 };
  char path[16384] = { 0 };
  char xname[CDI_MAX_NAME] = { 0 };
  char xlongname[CDI_MAX_NAME] = { 0 };
  char xunits[CDI_MAX_NAME] = { 0 };
  char xdimname[CDI_MAX_NAME] = { 0 };
  char yname[CDI_MAX_NAME] = { 0 };
  char ylongname[CDI_MAX_NAME] = { 0 };
  char yunits[CDI_MAX_NAME] = { 0 };
  char ydimname[CDI_MAX_NAME] = { 0 };
  char vdimname[CDI_MAX_NAME] = { 0 };
};

int grid_define(GridDesciption &grid);

int gird_from_nc_file(const char *gridfile);
int grid_from_h5_file(const char *gridfile);
int grid_from_name(const char *gridname);

void write_n_cgrid(const char *gridfile, int gridID, int *imask);

int cdo_define_grid(const std::string &gridfile);

int grid_read(FILE *gfp, const char *dname);  // TODO: Find better place for this

int cdo_cdf_openread(const char *filename);
void cdo_cdf_close(int nc_file_id);
void cdo_set_grids(const char *gridarg);

void gaussian_latitudes_in_degrees(std::vector<double> &lats, std::vector<double> &lat_bounds, size_t nlat);

#endif /* GRIDDES_H */
