#include <petsc/private/fortranimpl.h>
#include <petscmat.h>
#include <petscviewer.h>

#if defined(PETSC_HAVE_FORTRAN_CAPS)
#define matnullspacecreate0_             MATNULLSPACECREATE0
#define matnullspacecreate1_             MATNULLSPACECREATE1
#define matnullspacegetvecs_             MATNULLSPACEGETVECS
#define matnullspaceview_                MATNULLSPACEVIEW
#elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
#define matnullspacecreate0_             matnullspacecreate0
#define matnullspacecreate1_             matnullspacecreate1
#define matnullspacegetvecs_             matnullspacegetvecs
#define matnullspaceview_                matnullspaceview
#endif

PETSC_EXTERN void  matnullspacecreate0_(MPI_Fint * comm,PetscBool *has_cnst,PetscInt *n, Vec vecs[],MatNullSpace *SP, PetscErrorCode *ierr)
{
  *ierr = MatNullSpaceCreate(MPI_Comm_f2c(*(comm)),*has_cnst,*n,vecs,SP);
}

PETSC_EXTERN void  matnullspacecreate1_(MPI_Fint * comm,PetscBool *has_cnst,PetscInt *n, Vec vecs[],MatNullSpace *SP, PetscErrorCode *ierr)
{
  *ierr = MatNullSpaceCreate(MPI_Comm_f2c(*(comm)),*has_cnst,*n,vecs,SP);
}

PETSC_EXTERN void matnullspacegetvecs_(MatNullSpace *sp,PetscBool *HAS_CNST,PetscInt *N, Vec *VECS,PetscErrorCode *ierr)
{
  PetscBool has_cnst;
  PetscInt i,n;
  const Vec *vecs;

  CHKFORTRANNULLBOOL(HAS_CNST);
  CHKFORTRANNULLINTEGER(N);
  CHKFORTRANNULLOBJECT(VECS);

  *ierr = MatNullSpaceGetVecs(*sp, &has_cnst, &n, &vecs);

  if (HAS_CNST) {
    *HAS_CNST = has_cnst;
  }
  if (N) {
    *N = n;
  }
  if (VECS) {
    for (i=0; i<n; i++) {
      VECS[i] = vecs[i];
    }
  }
}

PETSC_EXTERN void matnullspaceview_(MatNullSpace *sp,PetscViewer *vin,PetscErrorCode *ierr)
{
  PetscViewer v;
  PetscPatchDefaultViewers_Fortran(vin,v);
  *ierr = MatNullSpaceView(*sp,v);
}

