#ifndef GEOMETRY_HPP
#define GEOMETRY_HPP

#include <iostream>
#include <limits>

#include "math/spline.hpp"

using namespace std;

using Func = double (*)(double);

extern double inf; 

//! The Geometry class contains all geometric parameters of the domain.
class Geometry{
public:
  //!
  Geometry();
  
  //! Geometry constructor
  Geometry(double _lX,size_t _nX,size_t _nZ,Func _hsoil,Func _dhsoil,Func _hbot,Func _dhbot);


  void initDefault();
  
  //! Horizontal length of the domain
  double lX;

  //! Number of horizontal steps
  size_t nX;

  //! Horizontal step
  double dX;

  size_t nZ_max;

  double depth;

  
  //! Level of the soil depending on X, e.g, hsoil[k]=level of the soil at X=k*dX.
  //! Vector of size nX.
  double* hsoil;

  //! Derivative of the soil depending on X, vector of size nX.
  double* dhsoil;

  //! Level of the bottom depending on X, e.g, hbot[k]=level of the bottom at X=k*dX.
  //! Vector of size nX.
  double* hbot;

  //! Derivative of the bottom depending on X, vector of size nX.
  double* dhbot;

  
  //! Number of vertical step at a given X, vector of size nX.
  size_t* nZ;
  
  //! Vertical step at a given X, vector of size nX.
  double* dZ;

  //! Vertical considered positions at a given X, vector of vectors of size nX. For each k, Z[k] is a vector of size nZ[k]
  double** Z;

  
  void initZ(double dZ_avg);

  void update(double _lX,size_t _nX,double _depth,size_t _nZ_max);
};
#endif
