#ifndef _rm_folderP_h_
#define _rm_folderP_h_

#include <sys/param.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/file.h>
#include <errno.h>
#include "assert.h"
#include "bool.h"
#include "folder.h"
#include "foldert.h"
#include "memory.h"
#include "al.h"
#include "rm_folder.h"
#include "msg.h"
#include "darray.h"
#include "buffer.h"
#include "registry.h"
#include "OSinter.h"

#ifndef BSD
#define CDIRSIZ  DIRSIZ       /* max directory name length if not using BSD */
#else
#define CDIRSIZ  MAXNAMLEN    /* max directory name length if using BSD     */
#endif

#define BUFSIZE  (512 + CDIRSIZ)
#define OR ||

#ifndef RMF_DEBUG
#define RMF_DEBUG  0
#endif

#if (RMF_DEBUG == 1)
#define RMFolder_debug(str)   printf(str)
#define RMFolder_debug1(s1, s2)   printf(s1, s2)
#define RMF_debug_c(c)      putchar(c); fflush(stdout)
#else
#define RMFolder_debug(str) 
#define RMFolder_debug1(s1, s2)
#define RMF_debug_c(c)  
#endif

#define FORMFEED '\014'
#define SEPERATOR 0x1f
                        /* character which seperates messages in RMAIL */
                        /* format is

			   SEPERATOR LINE_FEED
			   [n][,state],,[x,]*
			
			   where n is an integer, x is a string, and
			   * is the Klein star operator   
			   and state is one of {unseen|answered} (I don't know
			   the rest). the state is kept as the FolderString
			   in the RmMsg object. */

#define RMAIL_ENCODED_CHARS ","   /* the comma, Also all */
				  /* unprintables will be encoded */

/****************************************************************************/
typedef struct RmMsg_str {
  unsigned OwnersRMFid;       /* The id of the owner of this particular */
			      /* rmfolder msg object */
  Darray StatesUPsAndLabels;  /* A darray of strings, one string each */
			      /* for each state, user property, */
  Darray FolderString;        /* the special strings RMAIL uses */
  char *header;
  char *cHeader;              /* the header and the body will comprise */
			      /* the body of the msg.  The cHeader is */
			      /* the condensed header that RMAIL makes */
			      /* and we want to ignore that   --MA-- */
  char * body;                /* The entire body of the msg   --MA-- */
  Bool Deleted;
  unsigned HeaderLength;      /* buffer lengths */
  unsigned CHeaderLength;
  unsigned BodyLength;
} *RmMsg;

struct RMFolder_str {
  char *read_name; /* name of the file as received by AlRM_create.and */
		   /* opened.  --MA-- */
  ino_t INumber;   /* This files inode number. If the file  is stdin this */
		   /* will be */
		   /* set to 0 */
  unsigned RMFid;  /* This is a unique id given to each opened RMFolder */
		   /* object to a unique file.  This is used to make sure */
		   /* that if we are reading and writing to the same file we */
		   /* mantain the integrity of the reads and writes. */
  unsigned LinksIn; /* the number of RMFolder objects that have links into */
		    /* the data contained in the Msgs field */
  struct RMFolder_str* OriginalRMF; /* This will point to another RMFolder */
				    /* if  the */
			     /* other RMFolder opened the file this guy */
			     /* wanted before this giy tried to.  In that */
			     /* case, the Msgs field below is actually owned */
			     /* by the RMFolder pointed to here. */
  Bool opened;  /* flags if a opendir has already been performed */
  FILE *fp;      /* file data pointer (file id) */
  char * fileHeader;  /*   --MA-- The top header of the RMAIL file */
  Darray Msgs;   /* holds the whole file in memory one msg at a time. */
		 /* Each msg is storred in a RmfMsg object defined */
		 /* above */
  int LastMsgN;  /* last processed msg number, 
			 messages are counting numbers
                         i.e. they start with 1.  0 means none have been
			 read yet.   */
  Bool  FromStdin;  /* we really don't need an extra flag here but it will */
		    /* make reading the code easier for others. */
  int  OpenStatus;  /* either FOLDER_OPEN_RW or FOLDER_OPEN_APPEND */
  OSinter_TimeType ModTime;
};

typedef struct RMFolder_str *RMFolder;

#ifdef __STDC__
char *NewLine(unsigned*,unsigned*);
NORET KillLine(char*);
void AppendToHeader(RmMsg,char*);
void AppendToCHeader(RmMsg,char*);
void AppendToBody(RmMsg,char*);
NORET  SULCreate(char*,RmMsg);
RmMsg RmMsg_create();
NORET RmMsg_destroy(RmMsg);
char * AlRMFolder_get_next_msg_buff(RmMsg);
char * AlRMFolder_get_next_state_buff(RmMsg);
char * AlRMFolder_get_next_uprop_buff(RmMsg);
NORET AlRMFolder_get_next_fs_states(RMFolder,RmMsg,Registry);
NORET AlRMFolder_write_SUP_msg_to_rms(RMFolder,Msg);
NORET AlRMFolder_write_FS_msg_to_rms(RMFolder,Msg);
RmMsg RMFolder_fill_SUP(RmMsg,Msg);
RmMsg RMFolder_fill_FS(RmMsg,Msg);
NORET Labels_add(RMFBuffer,char*);
Bool SequentialMatch(char *,unsigned,char *);
char *CreateTempName(char *);
VOIDP Parse_from_stream(RMFolder);
ino_t Get_inumber(char *);
RMFolder RMF_establish_uniqueness(RMFolder,ino_t);
Bool RMF_is_unseen_in_SUP(RmMsg);
RMFolder rmf_open_file(RMFolder,char*);
char* rmf_create_second_name(char*);
NORET rmf_write_messages_to_file(RMFolder,FILE*);
#else
char *NewLine();
NORET KillLine();
void AppendToHeader();
void AppendToCHeader();
void AppendToBody();
NORET SULCreate();
RmMsg RmMsg_create();
NORET RmMsg_destroy();
char * AlRMFolder_get_next_msg_buff();
char * AlRMFolder_get_next_state_buff();
char * AlRMFolder_get_next_uprop_buff();
NORET AlRMFolder_get_next_fs_states();
NORET AlRMFolder_write_SUP_msg_to_rms();
NORET AlRMFolder_write_FS_msg_to_rms();
RmMsg RMFolder_fill_SUP();
RmMsg RMFolder_fill_FS();
NORET Labels_add();
Bool SequentialMatch();
char *CreateTempName();
VOIDP Parse_from_stream();
ino_t Get_inumber();
RMFolder RMF_establish_uniqueness();
Bool RMF_is_unseen_in_SUP();
RMFolder rmf_open_file();
char* rmf_create_second_name();
NORET rmf_write_messages_to_file();
#endif


#endif     /* end of  #ifndef _rm_folderP_h_  */




