#include "WrapperMpi"
#include <config.h>
#include <string.h>

using namespace Futile;

extern "C" {
void FC_FUNC_(bind_f90_mpi_environment_copy_constructor, BIND_F90_MPI_ENVIRONMENT_COPY_CONSTRUCTOR)(MpiEnvironment::f90_mpi_environment_pointer*,
  const MpiEnvironment::f90_mpi_environment*);
void FC_FUNC_(bind_f90_mpi_environment_type_new, BIND_F90_MPI_ENVIRONMENT_TYPE_NEW)(MpiEnvironment::f90_mpi_environment_pointer*,
  const FReferenceCounter::f90_f_reference_counter*,
  const int*,
  const int*,
  const int*,
  const int*,
  const int*);
void FC_FUNC_(bind_f90_mpi_environment_free, BIND_F90_MPI_ENVIRONMENT_FREE)(MpiEnvironment::f90_mpi_environment_pointer*);
void FC_FUNC_(bind_mpi_environment_null, BIND_MPI_ENVIRONMENT_NULL)(MpiEnvironment::f90_mpi_environment_pointer*);
void FC_FUNC_(bind_mpi_environment_comm, BIND_MPI_ENVIRONMENT_COMM)(MpiEnvironment::f90_mpi_environment_pointer*,
  const int*);
void FC_FUNC_(bind_release_mpi_environment, BIND_RELEASE_MPI_ENVIRONMENT)(MpiEnvironment::f90_mpi_environment*);
void FC_FUNC_(bind_mpi_environment_set, BIND_MPI_ENVIRONMENT_SET)(MpiEnvironment::f90_mpi_environment*,
  const int*,
  const int*,
  const int*,
  const int*);
void FC_FUNC_(bind_mpi_environment_dict, BIND_MPI_ENVIRONMENT_DICT)(const MpiEnvironment::f90_mpi_environment*,
  f90_dictionary_pointer*);
void FC_FUNC_(bind_mpi_environment_set1, BIND_MPI_ENVIRONMENT_SET1)(MpiEnvironment::f90_mpi_environment*,
  const int*,
  const int*,
  const int*,
  const int*);
}

MpiEnvironment::MpiEnvironment(const MpiEnvironment& other)
{
  FC_FUNC_(bind_f90_mpi_environment_copy_constructor, BIND_F90_MPI_ENVIRONMENT_COPY_CONSTRUCTOR)
    (*this, other);
}

MpiEnvironment::MpiEnvironment(const FReferenceCounter& refcnt,
    const int (*igroup),
    const int (*iproc),
    const int (*mpi_comm),
    const int (*ngroup),
    const int (*nproc))
{
  FC_FUNC_(bind_f90_mpi_environment_type_new, BIND_F90_MPI_ENVIRONMENT_TYPE_NEW)
    (*this, refcnt, igroup, iproc, mpi_comm, ngroup, nproc);
}

MpiEnvironment::~MpiEnvironment(void)
{
  FC_FUNC_(bind_f90_mpi_environment_free, BIND_F90_MPI_ENVIRONMENT_FREE)
    (*this);
}

MpiEnvironment::MpiEnvironment(const int (*comm))
{
  FC_FUNC_(bind_mpi_environment_comm, BIND_MPI_ENVIRONMENT_COMM)
    (*this, comm);
}

void MpiEnvironment::release_mpi_environment(void)
{
  FC_FUNC_(bind_release_mpi_environment, BIND_RELEASE_MPI_ENVIRONMENT)
    (*this);
}

void MpiEnvironment::set(int iproc,
    int nproc,
    int mpi_comm,
    int groupsize)
{
  FC_FUNC_(bind_mpi_environment_set, BIND_MPI_ENVIRONMENT_SET)
    (*this, &iproc, &nproc, &mpi_comm, &groupsize);
}

void MpiEnvironment::dict(Dictionary& dict_info) const
{
  FC_FUNC_(bind_mpi_environment_dict, BIND_MPI_ENVIRONMENT_DICT)
    (*this, dict_info);
}

void MpiEnvironment::set1(int iproc,
    int mpi_comm,
    int groupsize,
    int ngroup)
{
  FC_FUNC_(bind_mpi_environment_set1, BIND_MPI_ENVIRONMENT_SET1)
    (*this, &iproc, &mpi_comm, &groupsize, &ngroup);
}

