// AGSMAIN.H
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//


#if !defined(__AGSMAIN_H__)
#define __AGSMAIN_H__

#include <e32std.h>
#include <e32base.h>

#include "agnserv.h"
#include "agsfmgr.h"
#include "agssess.h"

#include <apparc.h>
#include <apffndr.h>
#include <agmmiter.h>

const TUint KDefaultHeapSize = 0x100000;

// Set server priority
const TInt KServerPriority = 0;  // EStandard Priority

const TUid KUidAgnGeneralPrefs=			{0x10000235};
const TUid KUidAgnModel=				{0x100000f1};
const TUid KUidAgnPrintSetup=			{0x1000010D};


enum TAgnServerPanic
	{
	EBadRequest =	-1,
	EBadDescriptor = -2,
	EBadStore =		-3,
	EFileCorrupt =	-4,
	EFileUnlocked = -5,
	EBadExtractor = -6,
	EIndexError	  = -7
	};


// class TSignal

class TSignal
	{
	public:
inline TSignal() {}
	inline TInt Set(const TDesC& aCommand);
	//
	inline TSignal(TRequestStatus& aStatus);
	inline TPtrC Command() const;
public:
	TRequestStatus* iStatus;
	TThreadId iId;
	};

inline TSignal::TSignal(TRequestStatus& aStatus)
	:iStatus(&aStatus),iId(RThread().Id())
	{aStatus=KRequestPending;}
inline TPtrC TSignal::Command() const
	{return TPtrC((const TText*)this,sizeof(*this)/sizeof(TText));}
inline TInt TSignal::Set(const TDesC& aCommand)
	{return aCommand.Size()!=sizeof(*this) ? KErrGeneral : (Mem::Copy(this,aCommand.Ptr(),sizeof(*this)),KErrNone);}


IMPORT_C TInt ThreadFunction(TSignal& aPtr);


// define some logging macros
// LOG logs a string to the log file  e.g. LOG("Message")
// LOGD logs a descriptor to the log file 


#ifdef INFOPRINTLOG

#define LOG(text) User::InfoPrint(_L(text))
#define LOGD(text) User::InfoPrint(text)
#define LOGI(text) User::InfoPrint(_L(text))
#define LOGID(text) User::InfoPrint(text)
#define LOGM(text,mem)
#define LOGF(text) User::InfoPrint(_L(text))
#else

#ifdef LOGGING
#define LOG(text) iAgnServer->iFile.Write(_L(text));
#define LOGD(text) iAgnServer->iFile.Write(text);
#else
#define LOG(x)
#define LOGD(x)
#endif

#ifdef FUNCLOGGING
#define LOGF(text) iAgnServer->iFile.Write(_L(text));
#else
#define LOGF(x)
#endif

#ifdef INITLOGGING
#define LOGM(text,mem) {TBuf<50> buffer; iAgnServer->iFile.Write(_L(text)); buffer.AppendFormat(_L("[%d->%d]\n"),mem,User::CountAllocCells()); iAgnServer->iFile.Write(buffer); mem = User::CountAllocCells();}
#define LOGI(text) iAgnServer->iFile.Write(_L(text));
#define LOGID(text) iAgnServer->iFile.Write(text);
#else
#define LOGM(text,mem)
#define LOGI(x)
#define LOGID(x)
#endif

#endif

class CAgnServerSession;
class TAgnEntryTransaction;
class CAgnServer;

class CAgnServUndertaker : public CActive
	{
public:
	static CAgnServUndertaker* NewL();
	void ConstructL();
	void DestroyServer();
	void CancelUndertaker();
private:
	inline CAgnServUndertaker(TInt aPriority = EPriorityStandard) : CActive(aPriority){};
	void DoCancel();
	void RunL();
private:
	TBool	iCancelled;	// set this to cancel the undertaker after it has been started
public:
	CAgnServer* iServer;
	};


// CAgnServer

class CAgnServer : public CServer
	{
public:
	static CAgnServer* NewL();
	void ConstructL();
	~CAgnServer();

	IMPORT_C static TInt StartServer();
	static TInt GlobalThreadFunction(TAny* aPtr);
	static CAgnServer* InitL(CAgnServUndertaker* aUndertaker);

	virtual CSession* NewSessionL(RThread aClient, const TVersion &aVersion) const;
	inline CAgnServFileMgr* FileMgr();
	void SessionClosed();
	void SessionAdded();
	RFs* FsSession();
	void BroadcastNotify(CAgnServerSession* aSession, CAgnServerSession::TNotifyType aType);
	// Notify with an entry transaction
	void BroadcastNotifyL(CAgnServerSession* aSession, CAgnServerSession::TNotifyType aType, TAgnEntryTransaction aTransaction);
public:
#ifdef LOGGING
	RFile iFile;
#endif
protected:
	CAgnServer(TInt aPriority);
private:
	CAgnServFileMgr* iFileMgr;
	RFs ifs;
	TInt iSessionCount;
	CAgnServUndertaker* iUndertaker;	// used to clear itself up
	};





/// CAgnServPictureFactory



///// inline functions

 CAgnServFileMgr* CAgnServer::FileMgr() {return iFileMgr;}




#endif





