#include "profile.h"
#include "foldertP.h"

NORET AlFolderT_register(ft_name,
			 create_from_file_funcptr,
			 create_from_stdin_funcptr,
			 next_msg_funcptr,
			 remove_msg_funcptr,
		         add_msg_funcptr,
			 print_self_funcptr,
			 destroy_funcptr, data_ptr)
     char          *ft_name;
     VOIDP_FUNCPTR create_from_file_funcptr;
     VOIDP_FUNCPTR create_from_stdin_funcptr;
     NORET_FUNCPTR next_msg_funcptr;
     BOOL_FUNCPTR  remove_msg_funcptr;
     BOOL_FUNCPTR  add_msg_funcptr;
     NORET_FUNCPTR print_self_funcptr;
     NORET_FUNCPTR destroy_funcptr;
     VOIDP         data_ptr;
 {
   AlFolderType the_foldertype;

   /* Some code to trap bad pointers */
   /* ------------------------------ */
   assert((create_from_file_funcptr != NULL));
   assert((create_from_stdin_funcptr != NULL));
   assert((next_msg_funcptr != NULL));
   assert((remove_msg_funcptr != NULL));
   assert((destroy_funcptr != NULL) && (strlen(ft_name) > 0));

   /* If the global Folder Type registry hasn't been initiated, do it now. */
   /* -------------------------------------------------------------------- */
   if (AlFolderTypeRegistry == NULL)
     AlFolderTypeRegistry = Registry_create(Registry_strcmp, Registry_strhash);

   the_foldertype = (AlFolderType)
                       Memory_allocate(sizeof(struct AlFolderType_struct));
   the_foldertype->name               = ft_name;
   the_foldertype->create_from_file   = create_from_file_funcptr;
   the_foldertype->create_from_stdin  = create_from_stdin_funcptr;
   the_foldertype->next_msg           = next_msg_funcptr;
   the_foldertype->remove_msg         = remove_msg_funcptr;
   the_foldertype->add_msg            = add_msg_funcptr;
   the_foldertype->print_self         = print_self_funcptr;
   the_foldertype->destroy            = destroy_funcptr;
   the_foldertype->data               = data_ptr;
   Registry_add(AlFolderTypeRegistry, (VOIDP) ft_name, (VOIDP) the_foldertype);
 };              /* end of AlFolderT_register()  */

/*****************************************************************************/

char *AlFolderT_name(the_foldertype)
     AlFolderType the_foldertype;
 { /* Get the folder type's name, given a folder type object */
   /* ------------------------------------------------------ */
   return(the_foldertype->name);
 };              /* end of AlFolderT_name()  */

/*****************************************************************************/

AlFolderType AlFolderT_get_folder_type(ft_name)
     char *ft_name;
 { /* Get the folder type object, given the type name */
   /* ----------------------------------------------- */
   return((AlFolderType) Registry_get(AlFolderTypeRegistry, (VOIDP) ft_name));
 };              /* end of AlFolderT_get_folder_type()  */

/*****************************************************************************/

char *AlFolderT_default_name()
 { /* get name of default FolderType ob */
   return((char *) AlProfile_get_CP_val(ALPROF_MAILUA));
 };              /* end of AlFolderT_default_name()  */

/*****************************************************************************/

AlFolderType AlFolderT_default_type()
 {          /* get default FT ob  */
   return(AlFolderT_get_folder_type(AlFolderT_default_name()));
 };              /* end of AlFolderT_default_type()  */

/*****************************************************************************/

VOIDP AlFolderT_eval_create_from_file(ft, filename, open_stat)
     AlFolderType ft;
     char *filename;
     int open_stat;
 { return((VOIDP) 
	  /* Invoke folder type's create folder function to create data ob */
	  /* ------------------------------------------------------------- */
	  ((ft->create_from_file) (filename, open_stat)));
 };              /* end of AlFolderT_eval_create_from_file()  */

/*****************************************************************************/

VOIDP AlFolderT_eval_create_from_stdin(ft)
     AlFolderType ft;
 { return((VOIDP) 
	  /* Invoke folder type's create folder function to create data ob */
	  /* ------------------------------------------------------------- */
	  ((ft->create_from_stdin) ()));
 };              /* end of AlFolderT_eval_create_from_stdin()  */

/*****************************************************************************/

Bool AlFolderT_remove_msg(ft, data_ob, the_msg)
     AlFolderType ft;
     VOIDP data_ob;
     Msg the_msg;
 { return((Bool) 
       /* Invoke folder type's remove function to remove msg from the folder */
       /* ------------------------------------------------------------------ */
	  ((ft->remove_msg) (data_ob, the_msg)));
 };              /* end of AlFolderT_remove_msg()  */

/*****************************************************************************/

Bool AlFolderT_add_msg(ft, data_ob, the_msg)
     AlFolderType ft;
     VOIDP data_ob;
     Msg the_msg;
 { return((Bool) 
       /* Invoke folder type's add function to add a msg to the folder */
       /* ------------------------------------------------------------ */
	  ((ft->add_msg) (data_ob, the_msg)));
 };              /* end of AlFolderT_add_msg()  */

/*****************************************************************************/

NORET AlFolderT_print_self(ft, data_ob, outfile)
     AlFolderType ft;
     VOIDP data_ob;
     FILE *outfile;
 { /* Invoke folder type's print  function to print out data object */
   /* ------------------------------------------------------------- */
   (ft->print_self) (data_ob, outfile);
 };              /* end of AlFolderT_print_self()  */

/*****************************************************************************/

NORET AlFolderT_eval_destroy(ft, data_ob)
     AlFolderType ft;
     VOIDP data_ob;
 { /* Invoke folder type's destroy folder function to destroy data ob */
   /* --------------------------------------------------------------- */
   (ft->destroy) (data_ob);
 };              /* end of AlFolderT_eval_destroy()  */

/*****************************************************************************/

NORET AlFolderT_eval_next_msg(ft, data_ob, 
			      msg_buf_ptr, state_buf_ptr, uprop_buf_ptr,
			      fs_state_registry,
			      do_nested_folders,
			      no_external_state_usage,
			      no_external_uprop_usage, the_previous_msg)
     AlFolderType ft;
     VOIDP        data_ob;
     char **msg_buf_ptr, **state_buf_ptr, **uprop_buf_ptr;
     Registry fs_state_registry;
     Bool do_nested_folders, no_external_state_usage, no_external_uprop_usage;
     Msg the_previous_msg;
 { /* Invoke folder type's next_msg folder function to get next msg */
   /* ------------------------------------------------------------- */
   (ft->next_msg) (data_ob,
		   msg_buf_ptr, state_buf_ptr, uprop_buf_ptr,
		   fs_state_registry,
		   do_nested_folders,
		   no_external_state_usage,
		   no_external_uprop_usage, the_previous_msg);
 };              /* end of AlFolderT_eval_next_msg()  */
