#ifndef SCHEME_MODULE_HPP
#define SCHEME_MODULE_HPP

#include <language/modules/BuiltinModule.hpp>
#include <language/utils/ASTNodeDataTypeTraits.hpp>
#include <utils/PugsMacros.hpp>

class IBoundaryConditionDescriptor;
template <>
inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const IBoundaryConditionDescriptor>> =
  ASTNodeDataType::build<ASTNodeDataType::type_id_t>("boundary_condition");

class VariableBCDescriptor;
template <>
inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const VariableBCDescriptor>> =
  ASTNodeDataType::build<ASTNodeDataType::type_id_t>("variable_boundary_condition");

class DiscreteFunctionVariant;
template <>
inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const DiscreteFunctionVariant>> =
  ASTNodeDataType::build<ASTNodeDataType::type_id_t>("Vh");

class IDiscreteFunctionDescriptor;
template <>
inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const IDiscreteFunctionDescriptor>> =
  ASTNodeDataType::build<ASTNodeDataType::type_id_t>("Vh_type");

class IQuadratureDescriptor;
template <>
inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const IQuadratureDescriptor>> =
  ASTNodeDataType::build<ASTNodeDataType::type_id_t>("quadrature");

class SchemeModule : public BuiltinModule
{
  friend class MathFunctionRegisterForVh;

 public:
  std::string_view
  name() const final
  {
    return "scheme";
  }

  void registerOperators() const final;

  SchemeModule();

  ~SchemeModule() = default;
};

#endif   // SCHEME_MODULE_HPP