// MSVAPI.H
//
// Copyright (c) 1998 Symbian Ltd.  All rights reserved.
//

#if !defined(__MSVAPI_H__)
#define __MSVAPI_H__

#if !defined(__E32BASE_H__)
#include <e32base.h>
#endif

#if !defined(__S32FILE_H__)
#include <s32file.h>
#endif

#if !defined(__MSVSTD_H__)
#include <msvstd.h>
#endif

#if !defined(__MSVSTORE_H__)
#include <msvstore.h>
#endif

#if !defined(__MSVIPC_H__)
#include <msvipc.h>
#endif

#if !defined(__MSVARRAY_H__)
#include <msvarray.h>
#endif

#if !defined(__MCLIENT_H__)
#include "mclient.h"
#endif


// Forward declarations
class CMsvSession;
class CMsvEntry;
class CBaseMtm;
class CMsvClientEntry;
class CMsvEntryArray;

//**********************************
// CMsvOperation
//**********************************
//
// Abstract base class for operations controlling asynchronous functions
//

class CMsvOperation : public CActive
	{
public:
	IMPORT_C CMsvOperation(CMsvSession& aMsvSession, TInt aPriority, TRequestStatus& aObserverRequestStatus);
	IMPORT_C ~CMsvOperation();
	virtual const TDesC8& ProgressL()=0;
	//
	inline TMsvOp Id() const;
	inline TUid Mtm() const;
	inline TMsvId Service() const;
	//
protected:
	TMsvId iService;
	TUid iMtm;
	TRequestStatus& iObserverRequestStatus;
	CMsvSession& iMsvSession;
private:
	TMsvOp iId;
	};


//**********************************
// CMsvOperationWait
//**********************************
//
// Allows a synchronous wait on a operation
//

class CMsvOperationWait: public CActive
	{
public:
	IMPORT_C static CMsvOperationWait* NewLC(TInt aPriority=EPriorityStandard);
	IMPORT_C ~CMsvOperationWait();
	IMPORT_C void Start();
protected:
	CMsvOperationWait(TInt aPriority);
	void RunL();
	void DoCancel();
	};


//**********************************
// CMsvCompletedOperation
//**********************************
//
// An operation which is already completed on construction
//

class CMsvCompletedOperation : public CMsvOperation
	{
public:
	IMPORT_C static CMsvCompletedOperation* NewL(CMsvSession& aMsvSession, TUid aMtm, const TDesC8& aProgress, TMsvId aService, TRequestStatus& aObserverRequestStatus, TInt aErr=KErrNone);
	IMPORT_C ~CMsvCompletedOperation();
	//
	const TDesC8& ProgressL();
private:
	CMsvCompletedOperation(CMsvSession& aSession, TRequestStatus& aObserverRequestStatus);
	void ConstructL(TUid aMtm, TInt aError, const TDesC8& aProgress, TMsvId aService);
	// from CActive
	void DoCancel();
	void RunL();
	//
private:
	HBufC8* iProgress;
	};


//**********************************
// MMsvSessionObserver
//**********************************
//
// 
//

class MMsvSessionObserver
	{
public:
	enum TMsvSessionEvent { EMsvEntriesCreated,
							EMsvEntriesChanged,
							EMsvEntriesDeleted,
							EMsvEntriesMoved,
							EMsvMtmGroupInstalled,
							EMsvMtmGroupDeInstalled,
							EMsvStoreDeleted,
							EMsvStoreCommitted,
							EMsvGeneralError,
							EMsvStoreCreated,
							EMsvCloseSession,
							EMsvServerReady,
							EMsvServerFailedToStart,
							EMsvCorruptedIndexRebuilt,
							EMsvServerTerminated
							};
public: 
	virtual void HandleSessionEvent(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3)=0;
	};


//**********************************
// CMsvSession
//**********************************
//
// 
//

const TInt KMsvSessionObserverGranularity=4;  //???

class CMsvSession: public CActive
	{
public: 
	IMPORT_C static CMsvSession* OpenSyncL(MMsvSessionObserver& aObserver);
	IMPORT_C static CMsvSession* OpenAsyncL(MMsvSessionObserver& aObserver);
	~CMsvSession();
	// --- Observer functions ---
	IMPORT_C void AddObserverL(MMsvSessionObserver& aObserver);
	IMPORT_C void RemoveObserver(MMsvSessionObserver& aObserver);
	// --- Utility functions ---
	inline CMsvEntry* GetEntryL(TMsvId aEntId);
	IMPORT_C CMsvOperation* TransferCommandL(const CMsvEntrySelection& aSelection, TInt aCommandId, const TDesC8& aParameter, TRequestStatus& aStatus);
	// --- cleanup functions
	IMPORT_C static void CleanupEntry(TAny* aPtr);
	IMPORT_C void CleanupEntryPushL(TMsvId aId);
	IMPORT_C void CleanupEntryPop(TInt aCount=1);
	inline void RemoveEntry(TMsvId aId);
	/// MTM functions
	inline TInt InstallMtmGroup(const TDesC& aFullName);
	inline TInt DeInstallMtmGroup(const TDesC& aFullName); 
	//
	inline TInt StopService(TMsvId aServiceId);
	inline TBool ServiceActive(TMsvId aServiceId);
	inline TInt ServiceProgress(TMsvId aServiceId, TDes8& aProgress);
	//
	inline void CloseMessageServer();
	//
protected:
	CMsvSession(MMsvSessionObserver& aObserver);
	void ConstructL(TBool aSyncOpening);
	//
	// used by friends
	inline TInt OperationId();
	inline RFs& FileSession();
	inline RMsvServerSession& Session();
	inline void GetEntryFileName(TMsvId aId, TMsvId aService, TFileName& aFileName);
	inline void GetEntryDirectory(TMsvId aId, TMsvId aService, TFileName& aFileName);
	//
	// from CActive
	void RunL();
	void DoCancel();
	//
private:
	void NotifyAllObservers(MMsvSessionObserver::TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3);
	void CleanupEntryDelete();
	void DoRunL(TMsvNotifBuffer& aBuffer);
	void DoGetEntryName(TMsvId aId, TMsvId aService, TFileName& aFileName, MsvUtils::TNameMode aMode);
	void GetMessageFolderL();
	//
private:
	TInt iOperationId;
	RFs	iFs;
	RMsvServerSession iSession;
	TMsvNotifBuffer iChange;	
	MMsvSessionObserver&	iMainObserver;
	CArrayPtrFlat<MMsvSessionObserver>* iObservers;
	CMsvEntrySelection* iCleanupList;
	TInt iSyncStart;
	HBufC* iMessageFolder;
	CMsvEntrySelection* iNotifSelection;
	//
friend class CSendAs;
friend class CMsvEntry;
friend class CMsvOperation;
friend class CMsvEntryOperation;
friend class CObserverRegistry;
	};




//**********************************
// MMsvEntryObserver
//**********************************
//
// 
//

class MMsvEntryObserver
	{
public:
	enum TMsvEntryEvent {	EMsvEntryChanged,
							EMsvNewChildren,
							EMsvDeletedChildren,
							EMsvChildrenChanged,
							EMsvEntryDeleted,
							EMsvContextInvalid,
							EMsvChildrenMissing,
							EMsvChildrenInvalid,
							EMsvStoreDeleted,
							EMsvStoreCommitted,
							EMsvStoreCreated,
							EMsvEntryMoved};
public: 
	virtual void HandleEntryEvent(TMsvEntryEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3)=0;
	};


//**********************************
// CMsvEntry
//**********************************
//
// 
//

class CMsvEntry: public CBase, public MMsvSessionObserver, public MMsvStoreObserver
	{
public: // Public member functions
	IMPORT_C static CMsvEntry* NewL(CMsvSession& aMsvSession, TMsvId aMsvId, const TMsvSelectionOrdering& aOrdering);
	IMPORT_C ~CMsvEntry();
	//
	// --- Observer functions ---
	IMPORT_C void AddObserverL(MMsvEntryObserver& aObserver);
	IMPORT_C void RemoveObserver(MMsvEntryObserver& aObserver);
	//
	// --- Accessor for associated session ---
	inline CMsvSession& Session(); 
	//
	// --- Accessors the associated message store ---
	IMPORT_C CMsvStore* ReadStoreL();
	IMPORT_C CMsvStore* EditStoreL();
	//
	// --- Synchronous Current Entry functions ---
	inline TMsvId EntryId() const; 
	inline const TMsvEntry& Entry() const; 
	inline const TMsvSelectionOrdering& SortType() const;
	inline TMsvId OwningService() const;
	IMPORT_C void SetSortTypeL(const TMsvSelectionOrdering& aSortType);
	IMPORT_C void SetMtmListL(const CArrayFix<TUid>& aMtmList);
	IMPORT_C void SetEntryL(TMsvId aMsvId);
	//
	// for binary files associated with an entry
	IMPORT_C TInt GetFilePath(TFileName& aDirectory) const;
	//
	// --- Asynchronous Current Entry functions ---
	IMPORT_C CMsvOperation* ChangeL(const TMsvEntry& aEntry, TRequestStatus& aStatus);
	//
	// --- Asynchronous Child Entry functions ---
	IMPORT_C CMsvOperation* CreateL(const TMsvEntry& aEntry, TRequestStatus& aStatus);
	IMPORT_C CMsvOperation* DeleteL(const CMsvEntrySelection& aSelection, TRequestStatus& aStatus);
	IMPORT_C CMsvOperation* DeleteL(TMsvId aMsvId, TRequestStatus& aStatus);
	IMPORT_C CMsvOperation* CopyL(const CMsvEntrySelection& aSelection, TMsvId aTargetId, TRequestStatus& aStatus);
	IMPORT_C CMsvOperation* CopyL(TMsvId aMsvId, TMsvId aTargetId, TRequestStatus& aStatus);
	IMPORT_C CMsvOperation* MoveL(const CMsvEntrySelection& aSelection, TMsvId aTargetId, TRequestStatus& aStatus);
	IMPORT_C CMsvOperation* MoveL(TMsvId aMsvId, TMsvId aTargetId, TRequestStatus& aStatus);
	//
	// --- Synchronous Child Entry functions ---
	IMPORT_C CMsvEntrySelection* ChildrenL() const;
	IMPORT_C CMsvEntrySelection* ChildrenWithServiceL(TMsvId aServiceId) const;
	IMPORT_C CMsvEntrySelection* ChildrenWithMtmL(TUid aMtm) const;
	IMPORT_C CMsvEntrySelection* ChildrenWithTypeL(TUid aEntryType) const;
	inline TInt Count() const;
	IMPORT_C const TMsvEntry& ChildDataL(TMsvId aMsvId) const;
	IMPORT_C const TMsvEntry& operator[](TInt aIndex) const;
	IMPORT_C CMsvEntry* ChildEntryL(TMsvId aMsvId) const;
	//
	// from MMsvSessionObserver
	void HandleSessionEvent(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3);
	// From MMsvStoreObserver
	void HandleStoreEvent(TMsvStoreEvent aEvent, TMsvId aId);
	//
private: // Private members
	CMsvEntry(CMsvSession& aMsvSession, const TMsvSelectionOrdering& aOrdering);
	void ConstructL(TMsvId aMsvId);
	//
	void NotifyAllObservers(MMsvEntryObserver::TMsvEntryEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3);
	void ContextChanged(MMsvEntryObserver::TMsvEntryEvent aEvent);
	void NewChildren(const CMsvEntrySelection& aSelection);
	CMsvEntrySelection* DoGetNewChildrenL(const CMsvEntrySelection& aSelection);
	void DeletedChildren(const CMsvEntrySelection& aSelection);
	void ChildrenChanged(const CMsvEntrySelection& aSelection);
	void DoGetChangedChildrenL(const CMsvEntrySelection& aSelection);
	void CheckNewGrandchildren(TMsvId aId);
	void CheckDeletedGrandchildren(TMsvId aId);
	void CheckChildrenStores(TMsvId aId);
	void NotifyChildChanged(TMsvId aId);
	CMsvEntrySelection* DoMakeSelection(TMsvId aId);
	void CheckIfContextMoved(const CMsvEntrySelection& aSelection);
	//
	TBool IsAChild(TMsvId aId) const;
	TBool AreChildren(const CMsvEntrySelection& aSelection) const;
	//
	CMsvOperation* DoDeleteL(const CMsvEntrySelection& aSelection, TRequestStatus& aStatus);
	CMsvClientEntry* DoGetEntryLC(TMsvId aId, TMsvId& aOwningService);
	void DoGetChildrenL();
	CMsvEntryArray* GetNewSortedListL(const TMsvSelectionOrdering& aOrdering, const CArrayFix<TUid>& aMtmList);
	void DoSortTypeL(CMsvClientEntry* aContext);
	void ReplaceChildL(TInt pos, const TMsvEntry& aEntry);
	//
private:
	enum TEntryState {	EValid,
						EInvalidChangingContext,
						EInvalidDeletedContext,
						EInvalidOldContext,
						EInvalidMissingChildren};
	//
private:
	TBool iOberserverAdded;
	TEntryState	iState;
	CMsvSession& iMsvSession;
	TMsvSelectionOrdering iOrdering;
	const TMsvEntry* iEntryPtr;
	CArrayPtrFlat<MMsvEntryObserver>* iObservers;
	CArrayPtrFlat<CMsvClientEntry>* iEntries;
	CMsvEntryArray* iSortedChildren;
	CMsvStore* iStore;
	CArrayFixFlat<TUid>* iMtmList;
	TMsvId iOwningService;
	};


//**********************************
// MtmClientUtils
//**********************************
//
// 
//

class McliUtils
    {
 public:
    IMPORT_C static TMsvLocalOperationProgress GetLocalProgressL(CMsvOperation& aOperation);
    };

#include "msvapi.inl"

#endif
