#ifndef __NAUNET_H__
#define __NAUNET_H__

{% if header %}
#include <cvode/cvode.h>                // prototypes for CVODE fcts., consts.
{% if info.method == "dense" -%}
#include <nvector/nvector_serial.h>     // access to serial N_Vector
#include <sunmatrix/sunmatrix_dense.h>  // access to dense SUNMatrix
#include <sunlinsol/sunlinsol_dense.h>  // access to dense SUNLinearSolver
#include <sundials/sundials_dense.h>    // use generic dense solver in precond
{% elif info.method == "sparse" -%}
#include <nvector/nvector_serial.h>     // access to serial N_Vector
#include <sunmatrix/sunmatrix_sparse.h> // access to sparse SUNMatrix
#include <sunlinsol/sunlinsol_klu.h>    // access to KLU sparse direct solver
{% elif info.method == "cusparse" -%}
#include <nvector/nvector_cuda.h>
#include <sunlinsol/sunlinsol_cusolversp_batchqr.h>
{% elif info.method == "spgmr" -%}
#include <sunlinsol/sunlinsol_spgmr.h>  // access to SPGMR SUNLinearSolver
#include <cvode/cvode_spils.h>          // access to CVSpils interface
{% endif -%}
#include <sundials/sundials_types.h>    // defs. of realtype, sunindextype
#include <sundials/sundials_math.h>     // contains the macros ABS, SUNSQR, EXP

#include "naunet_userdata.h"
#include "naunet_ode.h"
#include "naunet_macros.h"
{% endif %}


class Naunet
{

private:
    // UserData *m_data;
    N_Vector m_y;
    SUNMatrix m_a;

    realtype m_atol;
    realtype m_rtol;
    void *m_cvode_mem;
    SUNLinearSolver m_ls;

    {% if info.method == "cusparse" -%}
    cusparseHandle_t m_cusp_handle;
    cusolverSpHandle_t m_cusol_handle;
    {% endif %}

public:
    Naunet();
    ~Naunet();
    int initSolver();
    {% if info.method == "cusparse" -%}
    int resetSolver(int nsystem);
    {% endif -%}
    int solve(realtype *ab, realtype dt, UserData *data);
};

#endif
