/*
	PostOffice.h
*/

#ifndef _POST_OFFICE_H
#define _POST_OFFICE_H
#include <Binder.h>
#include <Directory.h>
#include <SmartArray.h>
#include <Volume.h>
#include "mail/IMAP.h"
#include "mail/MailCacheSupport.h"

namespace Wagner {

const uint32 kSyncAllMsg = 'sall';
const uint32 kSyncUserMsg = 'susr';

// Forward Declarations
class SendMessageContainer;

class PostOffice : public BinderNode {
	public:
		static PostOffice *		MailMan();
		static void				GoPostal();
		virtual 				~PostOffice();
		
		void					Initialize();
		void					Flush();
								// BinderNode Virtuals
		virtual status_t		OpenProperties(void **cookie, void *copyCookie);
		virtual status_t		NextProperty(void *cookie, char *nameBuffer, int32 *length);
		virtual status_t		CloseProperties(void *cookie);
		virtual put_status_t	WriteProperty(const char *name, const property &inProperty);
		virtual get_status_t	ReadProperty(const char *name, property &outProperty, const property_list &inArgs = empty_arg_list);
		
								// GHandler virtual		
		virtual	status_t		HandleMessage(BMessage *message);
		virtual	void			Cleanup();
		
								// PostOffice calls
		status_t				CreateCache(UserContainer &container, const char *mailbox);
		status_t				CreateDraftsCache(UserContainer &container);
		status_t				SyncUserCache(const char *user, const char *mailbox);
		status_t				SyncUserCache(UserContainer &container, const char *mailbox);
		status_t				ClearAllCaches();
		status_t				ClearUserCache(UserContainer &container, const char *mailbox);
		status_t				ExpungeMessages(UserContainer &container);
		status_t				SendMessage(SendMessageContainer *container);
		
		status_t				SaveSummaryToDisk(loaded_summary *summary);
		status_t				LoadSummaryFile(UserContainer &container, const char *mailbox, loaded_summary *summary, bool onlyHeader = false);
		status_t				LoadSummaryHeader(UserContainer &container, const char *mailbox, loaded_summary *summary, BDataIO &stream);
		
								// Imap mirror functions
		status_t				SelectMailbox(const char *user, const char *mailbox);
		MimeMessage *			GetMimeMessage(int32 index);
		status_t				GetMimeMessage(const char *uid, MimeMessage *outMessage);
		status_t				GetMessageFieldData(const char *msgUid, const char *field, void *data);
		BDataIO *				FetchSection(const char *mailbox, const char *msgUid, const char *part, int partSize, BString &contentType, bool cache, bool flagRead, bool &usingYurysServer);
		MimeMessage *			FindMessage(const char *msgUid);
		status_t				SetFlags(const char *msgUid, uint32 flags, bool add);
		int32					TotalMessagesInMailbox() const;
		status_t				SaveDraft(const property_list &inArgs, const char *bodyText, BString &encodedRunArray);

		bool					IsNetworkUp() const;
		bool					IsSpaceAvailable(const char *path, int size);
		status_t				OpenImapConnection(IMAP *imap, UserContainer &container, const char *mailbox, bool writable);
		status_t				GetCacheDirectory(const char *user, const char *folder, BDirectory *dir);
		status_t				UpdateStatusNode(const char *userName, loaded_summary *summary);

	private:
								// You can only have one mail cache...
								PostOffice();
		void					VerifyMailStatusNode(const char *name);
		
		static status_t			UserNodeCallback(PostOffice *userData, uint32 observed, void *extraData);
		inline bool				CanSync();
		inline void				EnableCheckMailButton(bool enable);
		
		// Member variables.
		volatile bool fKeepChecking;
		time_t fSyncInterval;
		volatile bool fSyncing;
		volatile bool fKeepRemindingMe;
		volatile bool fNetworkUp;
		
		loaded_summary fLoadedMailbox;
		BVolume fBootVolume;
		
		SmartArray<BString> fPropertyList;
		BinderNode::property fUserRootNode;
		
		BLocker fCacheLock;
		BLocker fSyncingLock;

		BString	fWebMailUrl;
		BString	fViewBodyPartTemplate;
		
		static PostOffice * fPostOfficeInstance;
		static BLocker fFactoryLocker;
};

}
#endif
