#ifdef PETSC_RCS_HEADER
static char vcid[] = "$Id: aoreg.c,v 1.2 2000/01/10 03:15:40 knepley Exp $";
#endif

#include "src/dm/ao/aoimpl.h"      /*I "petscao.h"  I*/

PetscFList AOSerializeList              = 0;
int        AOSerializeRegisterAllCalled = 0;

#undef __FUNCT__  
#define __FUNCT__ "AOSetSerializeType"
/*@C
  AOSetSerializeType - Sets the serialization method for the application ordering.

  Collective on AO

  Input Parameters:
+ ao     - The AO context
- method - A known method

  Options Database Command:
. -ao_serialize_type <method> - Sets the method; use -help for a list
                                of available methods (for instance, debug_binary)

   Notes:
   See "petsc/include/petscao.h" for available methods (for instance)
+  AO_SER_DEBUG_BINARY - Debugging ordering to binary file
-  AO_SER_BASIC_BINARY - Scalable ordering to binary file


   Level: intermediate

.keywords: AO, set, type, serialization
@*/
int AOSetSerializeType(AO ao, AOSerializeType method)
{
  int      (*r)(MPI_Comm, AO *, PetscViewer, PetscTruth);
  PetscTruth match;
  int        ierr;

  PetscFunctionBegin;
  PetscValidHeaderSpecific(ao, AO_COOKIE);
  ierr = PetscSerializeCompare((PetscObject) ao, method, &match);                                         CHKERRQ(ierr);
  if (match == PETSC_TRUE) PetscFunctionReturn(0);

  /* Get the function pointers for the method requested but do not call */
  if (!AOSerializeRegisterAllCalled) {
    ierr = AOSerializeRegisterAll(PETSC_NULL);                                                            CHKERRQ(ierr);
  }
  ierr = PetscFListFind(ao->comm, AOSerializeList, method, (void (**)(void)) &r);                         CHKERRQ(ierr);
  if (!r) {
    SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Unknown method: %s", method);
  }

  ierr = PetscObjectChangeSerializeName((PetscObject) ao, method);                                        CHKERRQ(ierr);
  PetscFunctionReturn(0);
}

/*MC
  AOSerializeRegister - Adds a serialization method to the application ordering package.

  Synopsis:

  AOSerializeRegister(char *serialize_name, char *path, char *serialize_func_name,
                      int (*serialize_func)(MPI_Comm, AO *, PetscViewer, PetscTruth))

  Not Collective

  Input Parameters:
+ serialize_name      - The name of a new user-defined serialization routine
. path                - The path (either absolute or relative) of the library containing this routine
. serialize_func_name - The name of routine to create method context
- serialize_func      - The serialization routine itself

   Notes:
   AOSerializeRegister() may be called multiple times to add several user-defined solvers.

   If dynamic libraries are used, then the fourth input argument (routine_create) is ignored.

   Sample usage:
.vb
   AOSerializeRegister("my_store", /home/username/my_lib/lib/libO/solaris/mylib.a, "MyStoreFunc", MyStoreFunc);
.ve

   Then, your serialization can be chosen with the procedural interface via
$     AOSetSerializeType(ao, "my_store")
   or at runtime via the option
$     -ao_serialize_type my_store

   Level: advanced

   $PETSC_ARCH and $BOPT occuring in pathname will be replaced with appropriate values.

.keywords: AO, register

.seealso: AOSerializeRegisterAll(), AOSerializeRegisterDestroy()
M*/
#undef __FUNCT__  
#define __FUNCT__ "AOSerializeRegister_Private"
int AOSerializeRegister_Private(const char *sname,const char *path,const char *name,int (*function)(MPI_Comm, AO *, PetscViewer, PetscTruth))
{
  char fullname[256];
  int  ierr;

  PetscFunctionBegin;
  ierr = PetscStrcpy(fullname, path);                                                                     CHKERRQ(ierr);
  ierr = PetscStrcat(fullname, ":");                                                                      CHKERRQ(ierr);
  ierr = PetscStrcat(fullname, name);                                                                     CHKERRQ(ierr);
  ierr = PetscFListAdd(&AOSerializeList, sname, fullname, (void (*)(void)) function);                     CHKERRQ(ierr);
  PetscFunctionReturn(0);
}

/*-------------------------------------------------------------------------------------------------------------------*/
#undef __FUNCT__  
#define __FUNCT__ "AOSerializeRegisterDestroy"
/*@C
   AOSerializeRegisterDestroy - Frees the list of serialization routines for
   application orderings that were registered by PetscFListAdd().

   Not Collective

   Level: advanced

.keywords: AO, application ordering, register, destroy

.seealso: AOSerializeRegisterAll(), AORegisterAll()
@*/
int AOSerializeRegisterDestroy(void)
{
  int ierr;

  PetscFunctionBegin;
  if (AOSerializeList) {
    ierr = PetscFListDestroy(&AOSerializeList);                                                           CHKERRQ(ierr);
    AOSerializeList = PETSC_NULL;
  }
  AOSerializeRegisterAllCalled = 0;
  PetscFunctionReturn(0);
}
