// IMSK.H
// 
// Copyright (c) 1998 Symbian Ltd.  All rights reserved. 
//

#if !defined(__IMSK_H__)
#define __IMSK_H__

#if !defined(__E32BASE_H__)
#include <e32base.h>
#endif

#if !defined(__ES_SOCK_H__)
#include <es_sock.h>
#endif

#if !defined(__IN_SOCK_H__)
#include <in_sock.h>
#endif

#if !defined(__F32FILE_H__)
#include <f32file.h>
#endif

#if !defined(__MENTACT_H__)
#include <mentact.h>
#endif

#if !defined(__MIUTLOG_H__)
#include <miutlog.h>
#endif

#if !defined(__MIUT_ERR_H__)
#include <miut_err.h>
#endif

#if !defined(__MIUTHDR_H__)
#include <miuthdr.h>
#endif

#if !defined(__LINKMAN_H__)
#include <linkman.h>
#endif

const TInt EActivePriorityHigh = 1;
//const TInt KImMailMaxBufferSize = 1024;	// 1000 is defined by the SMTP spec as max space
const TInt KCarriageLineFeedLength=2;
const KImskIPAddressLen=15;				// Max numeric IP address len = "255.255.255.255" = 15 chars


typedef TBuf8<KImMailMaxBufferSize> TImMailBuffer;

enum TImLineType
	{ 
	ECRLFTerminated, 
	EBufferTooSmall, 
	EReceiveBufferFull,
	EReceiveBufferEmpty
	};


class CImLog;
class CImTextServerScript;
class CImskAutoDisconnectTimer;
class CImskIdleTimer;
class CImskErrorDialog;

class TImLinkManObserver : public MLinkManObserver
	{
public:
	virtual TBool CloseActiveRemoteLink ();
	};

class CImTextServerSession : public CMsgActive
	{
public:
	enum TImOperationMode{
		EImServerMode,
		EImClientMode
	};

	IMPORT_C static CImTextServerSession *NewLC (TImOperationMode aMode, RSocketServ &aServerServ);
	IMPORT_C static CImTextServerSession *NewL();
	IMPORT_C static CImTextServerSession *NewL(RSocketServ &aServerServ);
	~CImTextServerSession();

	IMPORT_C void QueueConnect(TRequestStatus& aStatus,const TDesC& anAddressDesc, TInt aPortNum, TCallBack aDisconnectFunction);
	IMPORT_C void QueueConnect(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum);
	IMPORT_C void Disconnect();
	void TimeOut();

	IMPORT_C void QueueReceiveNextTextLine(TRequestStatus &aStatus);
	IMPORT_C TInt Send(const TDesC8& aDesc);
	IMPORT_C TInt Send(TRefByValue<const TDesC8> aFmt,...);
	//async sends
	IMPORT_C void Send(TRequestStatus &aStatus, const TDesC8& aDesc);
	IMPORT_C void Send(TRequestStatus &aStatus, TRefByValue<const TDesC8> aFmt,...);

	IMPORT_C TInt SendReceive(const TDesC8& aDesc);
	IMPORT_C TImLineType GetCurrentTextLine(TDes8&);
	IMPORT_C TInt Receive(TDes8& rDes);
	IMPORT_C void Receive(TRequestStatus &aStatus, TDes8& rDes);

	IMPORT_C const TDesC& LocalName();
	IMPORT_C void ReceiveBinaryData(TRequestStatus &aStatus, TDes8& rDes,TInt aLen);	

	IMPORT_C void LogText(const TDesC8& aString);						// write string into log file
	IMPORT_C void LogError(const TDesC8& aString,const TInt aError);		// write string and integer into log file

private:
	CImTextServerSession();
	void ConstructL(TImOperationMode aMode, RSocketServ &aServerServ);

	void OpenAndReadResourceFileL();

	TInt Open();
	void SocketConnect();
	void QueueReceiveNextDataPacket();
	void Close();

	void CreateLogFile(TInt aPortNum);
	void OpenScriptFile(TInt aPortNum);

	void DoRunL();
	void DoComplete(TInt& );						// Cleanup code
	void DoCancel();
	void Accept(TRequestStatus& aStatus,RSocket& aServSocket);

	enum TImSocketState
		{
		EImClosed, 
		EImResolve, 
		EImConnect, 
		EImSendReceive 
		};

	enum TImSendReceiveState
		{ 
		EImInactive, 
		EImSending, 
		EImReceiving, 
		EImReceivingBinaryData 
		};
private:
	RSocket							iSocket;
	RSocketServ						iServ;
	RSocketServ*					iServerServ;
	RHostResolver					iHostResolver;
	TInt							iMode;

	TNameEntry						iHostent;
	TInt							iPortNum;
	TPtrC							iAddressDesc;

	TImMailBuffer					iReceive;
	TSockXfrLength					iLen;
	TImSocketState					iState;
	TImSendReceiveState				iSendReceive;

	HBufC8*							iBuffer;
	TBufC8<2>						iCarriageLineFeed;
	TImLineType						iCurrentLineType;

	CImTextServerScript*			iScript;
	CImLog*							iLog;
	TBuf<KImskIPAddressLen>			iLocalName;

	TDes8*							iBinaryDataBuffer;	// used by function ReceiveBinaryData()

	CImskIdleTimer					*iIdleTimer;
	CImskAutoDisconnectTimer		*iAutoDisconnectTimer;
	TImLinkManObserver				iLinkManObserver;
	TBool							iLinkOff;

	RFs								iFs;
	HBufC*							iTimeoutTitleString;
	HBufC*							iTimeoutTextString;

friend class CImTextServer;
	};


/***

class CImTextServer : public CActive
	{
public:
	IMPORT_C static CImTextServer* NewL(TUint32 aAddress,TInt aPort, TInt aCount);
	IMPORT_C static CImTextServer* NewLC(TUint32 aAddress,TInt aPort, TInt aCount);

	IMPORT_C static CImTextServer* NewL(TInt aPort, TInt aCount);
	IMPORT_C static CImTextServer* NewLC(TInt aPort, TInt aCount);
	~CImTextServer();
	
	IMPORT_C void CreateNewTextServerSession(TRequestStatus &aStatus, CImTextServerSession **aSession); 
	IMPORT_C const TDesC& LocalName();
	IMPORT_C  RSocket& GetNewServerSession();

	RSocketServ						iServ;
	RSocket							iBlankSocket;
	RSocket							iSocket;
private:
	enum TState 
		{
		ESvrIdle,
		ESvrListening,
		ESvrAccepting,
		ESvrConnecting
		};

	CImTextServer();
	void ConstructL(TInt aPort, TUint32 aAddress, TInt aCount);
	void RunL();
	void DoCancel();
	void ChangeState(TInt aS);

private:
	RSocket							iTextSocket;
	TSockAddr*						iServAddr;

	TRequestStatus*					iParentStatus;
	TInt							iPort;
	TInt							iState;		
	TBuf<KImskIPAddressLen>			iLocalName;

friend class CImTextServerSession;
	};

*******/

#endif
