/*    TabPostOffice.x -- contains calls from the Application to the TabPostOffice Server. */

program TabPostOfficeServer {
    version Vers←1 {
	SessionResult TPO←StartSession(SessionInfo) = 1;                          /* Begins a session */
	MsgInfoResult TPO←GetMsgInfo(MsgIDRange) = 2;        /* Returns Headers for message requested */
	MsgTextResult TPO←GetMsgText(MsgTextInfo) = 3;           /* Returns Text of message requested */
	NewMailResult TPO←CheckNewMail(void) = 4;                              /* Checks for new mail */
	FoldersResult TPO←GetFolders(void) = 5;           /* Gets the possible folders (message sets) */
	ErrorInfo TPO←MarkMsg(Mark) = 6;                                           /* Marks a message */
	ErrorInfo TPO←EndSession(void) = 7;                                         /* Ends a session */
    } = 1;
} = 40400042;

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

struct ErrorInfo {
	int errno;
	string msg<>;
};


typedef string Property<>;                                       /* Like: Priority, From, Date, Subject */
typedef string Relation<>;    /* Like: Equals, GreaterThan, LessThan, GreaterThanEquals, LessThanEquals */
typedef string Value<>;                                            /* Values for the various properties */
typedef Property PropertyArray<>;

struct PropInfo {
	Property p;
	Relation r;
	Value v;
};
typedef PropInfo PropInfoArray<>;


typedef int MsgID;
typedef int Priority;

typedef string Filter<>;
typedef Filter FilterSet<>;

typedef string Folder<>;
typedef Folder Folders<>;

typedef int Time;                    /* Times are # of seconds since the start of January 1, 1970 GMT */

enum Status { New, Unread, Read };

enum Whences {
	BOM,                                    /* Beginning of Message -- includes ALL header fields */
	BOB                                 /* Beginning of Message Body -- includes NO header fields */
};

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




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

	SessionResult TPO←StartSession(SessionInfo) = 1;                           Begins a session 

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

struct SessionInfo {
	int numselects;          /* Number of elements in plist */
	PropInfoArray plist;     /* All Properties ANDed together */
	int numorders;           /* Number of elements in olist */
	PropertyArray olist;     /* First element of olist is primary index */
};

struct SessionResult {
	int total;               /* Total number of messages selected */
	int new;                 /* Total number of new messages selected */
	int unread;              /* Total number of unread messages selected */
	Priority loPri;          /* Lowest priority of a selected message */
	Priority hiPri;          /* Highest priority of a selected message */
	Time lastModifyTime;     /* Last modify time of mailbox */
	Time lastAccessTime;     /* Last access time of mailbox */
	ErrorInfo e;             /* Error information */
};


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

	MsgInfoResult TPO←GetMsgInfo(MsgIDRange) = 2;              Returns Headers for message requested 

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

struct MsgIDRange {
        MsgID beginId;           /* First message */
	MsgID endId;             /* Last message */
};

struct MsgInfo {
	MsgID msgId;             /* Message ID of this message */
	string from<>;           /* From header -- not including the "From: " */
	string to<>;             /* To header -- not including the "To: " */
	string cc<>;             /* CC header -- not including the "CC: " */
	string date<>;           /* Date header -- not including the "Date: " */
	string subject<>;        /* Subject header -- not including the "Subject: " */
	Priority priority;       /* Priority of this message */
	FilterSet filters;       /* The filter which gave this message, this priority -- a singleton */
	Status status;           /* Status of this message */
	int bodyLength;          /* Number of bytes in a message body   */
	int bodyLines;	         /* Number o newlines in a message body */
};
typedef MsgInfo MsgInfos<>;

struct MsgInfoResult {
	MsgInfos info;           /* Array of message info's -- one per message */
	ErrorInfo e;             /* Error information, if any */
};

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

	MsgTextResult TPO←GetMsgText(MsgTextInfo) = 3;            Returns Text of message requested 

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

struct MsgTextInfo {
	MsgID msgId;             /* ID of message */
	int beginByte;           /* Byte on which to start */
	int numBytes;            /* Maximum number of bytes to return */
	Whences whence;          /* Start reading from here */
};

struct MsgTextResult {
	string body<>;           /* No headers here */
	ErrorInfo e;             /* Error information, if any */
};


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

	NewMailResult TPO←CheckNewMail(void) = 4;                               Checks for new mail 

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

struct NewMailResult {
	bool newMail;            /* TRUE if new mail, FALSE otherwise */
	ErrorInfo e;             /* Error information, if any */
};


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

	FoldersResult TPO←GetFolders(void) = 5;            Gets the possible folders (message sets) 

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

struct FoldersResult {
	Folders folders;
	int numFolders;          /* Number of elements in folders */
	ErrorInfo e;             /* Error information, if any */
};


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

	ErrorInfo TPO←MarkMsg(Mark) = 6;                                            Marks a message 

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

struct Mark {
	MsgID msgId;             /* Message ID of this message */
	string markID<>;         /* Mark for this message */
	string markMsg<>;        /* Mark message for this message */
};