// EIKIRDA.H
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//
       
#if !defined(__EIKIRDA_H__)
#define __EIKIRDA_H__

#if !defined(__EIKDIALG_H__)
#include <eikdialg.h>
#endif

#if !defined(__IR_SOCK_H__)
#include <ir_sock.h>
#endif

#if !defined(__BADESCA_H__)
#include <badesca.h>
#endif

#if !defined(__EIKCFDLG_H__)
#include <eikcfdlg.h>
#endif

//
// class CEikIrMain	- Abstract
//

class CEikProgressInfo;
class MEikIrObserver;
class CEikIrActive;
class CEikIrMain : public CEikDialog
	{
public:
	enum TType
		{ ESender, EReceiver };
public:
	IMPORT_C ~CEikIrMain();
	inline TType Type() const { return iType; }
	inline void SetIrObserver(MEikIrObserver* aIrObserver) { iIrObserver=aIrObserver; }
protected: // virtual
    virtual void PreLayoutDynInitL();
	virtual TBool OkToExitL(TInt aButtonId); // from CEikDialog
	virtual void HandleUserCancelL();
	virtual void HandleTransferCompleteL();
	virtual void HandleIrError(TInt aError);
	virtual void HandleProgressUpdateL() =0;
protected:
	friend class CEikIrActive;
	CEikIrMain(TType aType) : iType(aType) {}
	void ConstructL();
	//
	void SetTopLabel(TInt aResId);
	void SetTopLabel(TDesC& aDes);
	void SetBottomLabel(TInt aResId);
	void SetBottomLabel(TDesC& aDes);
	void ClearBottomLabel();
	const CFont* BestFontForText(const TDesC& aDes);
	void SetLabel(TInt aResId, const TDesC& aDes);
	//
	TInt LoadIrTinyTPProtocol();
	//
	CEikProgressInfo* Progress() const;
	void MakeProgressBarVisible(TBool aVisible);
	void MakeSendImageVisible(TBool aVisible);
	void MakeRecvImageVisible(TBool aVisible);
	// IAS stuff
	TInt RegisterIASClasses();
	void IASQueryVersion1(TRequestStatus& aStatus);
	TInt IASResponseGetRemotePort();
private:
	void DisableRemoteLink();
	void ReEnableRemoteLink();
protected:
	TType iType;
	CEikIrActive* iActive;
	RSocketServ iSockServ;
	HBufC8* iBuf;	
	TPtr8* iBufPtr;
	MEikIrObserver* iIrObserver;
	// relevant bits of TProtocolDesc & TIrdaSockAddr
	TUint iAddrFamily;
	TUint iSockType;
	TUint iProtocol;
	TUint iRemoteDevAddr;
	// IAS stuff
	RNetDatabase iNetDb;
	TIASQuery iIASQuery;
	TIASResponse iIASResponse;
	};

//
// class CEikIrSender - Abstract
//

class CEikIrSender : public CEikIrMain
	{
public:
	IMPORT_C ~CEikIrSender();
protected: // virtual
	virtual void HandleProgressUpdateL();
    virtual void PreLayoutDynInitL();
	virtual TBool NegotiateL(TRequestStatus& aStatus)=0;
	virtual void ReadChunkL(TInt aLength)=0;
protected:
	friend class CEikIrActive;
	CEikIrSender()	: CEikIrMain(CEikIrMain::ESender) {}
	TInt Discover(TRequestStatus &aStatus); // used by iActive
	void Connect(TRequestStatus& aStatus);
	void AllocatePacketBufferL();
	void NegotiationComplete();
	void DoSendL(TRequestStatus& aStatus);
	void RequestDisconnectIndication(TRequestStatus& aStatus);
	TInt HandleDiscovery(TRequestStatus &aStatus);
	TInt DoDiscovery(TInt anErr);
	TBool ParseAck() const;
protected:
	RSocket iSender;
	TUint iNumToSend;
	TUint iNumSent;
	TNameEntry iLog;
	THostName iHostName;
	RHostResolver	iHostRslv;
	TInt	iDiscoverAttempts;
	TUint iRemotePort;
	};

//
// class CEikIrReceiver	- Abstract
//

class CEikIrReceiver : public CEikIrMain
	{
public:
	IMPORT_C ~CEikIrReceiver();
protected: // virtual
	//virtual void HandleIrErrorL(TInt aError);
	virtual void HandleProgressUpdateL();
    virtual void PreLayoutDynInitL();
	virtual TBool NegotiateL(TRequestStatus& aStatus)=0;
	virtual void WriteChunkL()=0;
protected:
	friend class CEikIrActive;
	CEikIrReceiver()	: CEikIrMain(CEikIrMain::EReceiver) {}
	TInt Initialize();
	void WaitToBeDiscovered(TRequestStatus& aStatus);
	void WaitForConnect(TRequestStatus& aStatus);
	void AllocatePacketBufferL();
	void ReadNumToRecvFromDes(const TDesC8& aDes);
	void NegotiationComplete();
	void DoReceiveL(TRequestStatus& aStatus);
protected:
	TUint iNumToRecv;
	TUint iNumRecvd;
	TNameEntry iLog;
	RSocket iListener;
	RSocket iReader;
	};

//
// class CEikIrDataSender
//

class CEikIrDataSender : public CEikIrSender
	{
public:
	IMPORT_C ~CEikIrDataSender();
	IMPORT_C static CEikIrDataSender* NewL();
	IMPORT_C void SendLD(CBufBase* aData);
private:
	CEikIrDataSender() : CEikIrSender() {}
private:
    virtual void PreLayoutDynInitL();
	virtual TBool NegotiateL(TRequestStatus& aStatus);
	virtual void ReadChunkL(TInt aLength);
private:
	enum TNegotiationStage
		{
		ESendSize,
		ESizeSentQueueReadAck,
		EAckReceived
		};
private:
	TNegotiationStage iNegStage;
	CBufBase* iData;
	};

//
// class CEikIrDataReceiver
//

class CEikIrDataReceiver : public CEikIrReceiver
	{
public:
	IMPORT_C ~CEikIrDataReceiver();
	IMPORT_C static CEikIrDataReceiver* NewL();
	IMPORT_C void ReceiveLD(CBufBase* aData);
private:
	CEikIrDataReceiver() : CEikIrReceiver() {}
private:
    virtual void PreLayoutDynInitL();
	virtual TBool NegotiateL(TRequestStatus& aStatus);
	virtual void WriteChunkL();
private:
	TBool ParseFirstPacket();
private:
	enum TNegotiationStage
		{
		EQueueReadNumToRecv,
		EGotNumToRecvSendAck,
		EAckSent
		};
private:
	TNegotiationStage iNegStage;
	TBool iAckNSent;
	CBufBase* iData;
	};

//
// class CEikIrFileSender
//

class CEikIrFileSender : public CEikIrSender
	{
public:
	IMPORT_C ~CEikIrFileSender();
	IMPORT_C static CEikIrFileSender* NewL();
	IMPORT_C void SendLD(const TFullName& aFileName, const TDesC* aTargetPath=NULL);
private:
	CEikIrFileSender() : CEikIrSender() {}
private:
    virtual void PreLayoutDynInitL();
	virtual TBool NegotiateL(TRequestStatus& aStatus);
	virtual void ReadChunkL(TInt aLength);
private:
	void CopyTargetPathL(const TDesC* aTargetPath);
private:
	enum TNegotiationStage
		{
		ESendFileNameAndDetails,
		EFileNameAndDetailsSentQueueReadAck,
		EAckReceived
		};
private:
	RFs* iFs;
	RFile iFile;
	TParse iParse;
	HBufC* iTargetPath;
	TNegotiationStage iNegStage;
	};

//
// class CEikIrFileReceiver
//

class CEikIrFileReceiver : public CEikIrReceiver
	{
public:
	IMPORT_C ~CEikIrFileReceiver();
	IMPORT_C static CEikIrFileReceiver* NewL();
	IMPORT_C void ReceiveLD(const TDesC& aPath);
	IMPORT_C void ReceiveLD(); // assumes full target path is being sent
	IMPORT_C void FileName(TDes& aFileName) const;
private:
	CEikIrFileReceiver() : CEikIrReceiver() {}
private:
    virtual void PreLayoutDynInitL();
	virtual TBool NegotiateL(TRequestStatus& aStatus);
	virtual void WriteChunkL();
	virtual void HandleUserCancelL();
	virtual void HandleTransferCompleteL();
private:
	TBool ParseFirstPacketL();
	void ParseFileNameAndDetailsL(const TDesC8& aNameAndDetails);
	TBool CheckFreeSpaceL();
	void FindUniqueFileNameL(TFileName& aName);
	TBool CheckFileExists();
	TBool QueryRenameFileL(TFileName& aNewFileName);
private:
	enum TNegotiationStage
		{
		EQueueReadFileNameAndDetails,
		EGotFileNameAndDetailsSendAck,
		EAckSent
		};
	enum TFileRecFlags	{ EFullPathNameSupplied=1, ETempNameUsed=2, EAckNSent=4, EFileOpened=8 };
private:
	RFs* iFs;
	RFile iFile;
	TParse iParse;
	TUint iFileAtt;
	TTime iFileModified;
	TNegotiationStage iNegStage;
	TUint iFileRecFlags;
	HBufC* iRemoteFileName;
	};

//
// class CEikIrMultipleFileSender
//

class CEikIrMultipleFileSender : public CEikIrSender
	{
public:
	IMPORT_C ~CEikIrMultipleFileSender();
	IMPORT_C static CEikIrMultipleFileSender* NewL();
	IMPORT_C void SendLD(CDesCArraySeg * aFileNameArray,TInt aEditLength );
private:
	CEikIrMultipleFileSender();
	void ConstructMultipleFileSenderL();
private:
	virtual void HandleProgressUpdateL();
    virtual void PreLayoutDynInitL();
	virtual TBool NegotiateL(TRequestStatus& aStatus);
	virtual void ReadChunkL(TInt aLength);
private:
	void CopyTargetPathL(const TDesC* aTargetPath);
	void MergeFullPaths(TFullName& aFullPath,TInt aDeleteLength);
private:
	enum TNegotiationStage
		{
		ESendNumberOfFiles,
		EReadNumOfFilesAck,
		ENumOfFilesAckReceived,
		ESendFileNameAndDetails,
		EFileNameAndDetailsSentQueueReadAck,
		EAckReceived
		};
private:
	RFs* iFs;
	RFile iFile;
	TParse iParse;
	TNegotiationStage iNegStage;
	TInt iTotalBytesInMultipleFiles;
	TInt iTotalBytesInMultipleFilesTransferred;
	TInt iLastFile;
	CDesCArray* iFileNameArray;
	TInt iNumOfFiles;
	TInt iBytesInFirstFile;// !! probably not needed
	TPath iBaseFolderPath;
	TInt iEditLength;
	TBool iV1Receiver;
	};

//
// class CEikIrMultipleFileReceiver
//

class CEikIrMultipleFileReceiver : public CEikIrReceiver
	{
public:
	IMPORT_C ~CEikIrMultipleFileReceiver();
	IMPORT_C static CEikIrMultipleFileReceiver* NewL();
	IMPORT_C void ReceiveLD(const TDesC& aPath);
	IMPORT_C void FileName(TDes& aFileName) const;
private:
	CEikIrMultipleFileReceiver();
	void ConstructMultipleFileReceiverL();
private:
    virtual void PreLayoutDynInitL();
	virtual TBool NegotiateL(TRequestStatus& aStatus);
	virtual void WriteChunkL();
	virtual void HandleUserCancelL();
	virtual void HandleTransferCompleteL();
	virtual void HandleProgressUpdateL();
private:
	enum TIrMsgState{ENoProceed=0,EProceed,ESingleFileFromV1Machine,};
private:
	TIrMsgState ParseFirstPacketL();
	void ParseFileNameAndDetailsL(const TDesC8& aNameAndDetails);
	void ParseNumOfFilesAndTotalBytesL(const TDesC8& aNumFilesAndTotalBytes);
	TBool CheckFreeSpaceL();
	void FindUniqueFileNameL(TFileName& aName);
	TBool CheckFileExists();
	TBool QueryRenameFileL(TFileName& aTempFileName);
private:
	enum TNegotiationStage
		{
		ESendNumberOfFiles,
		EReadNumOfFilesAck,
		ENumOfFilesAckReceived,
		EQueueReadFileNameAndDetails,
		EGotFileNameAndDetailsSendAck,
		EAckSent
		};
	enum TMulFileRecFlags	{ EFullPathNameSupplied=1, ETempNameUsed=2, EAckNSent=4, EFileOpened=8 , EFileNotDuplicate=16 };
private:
	RFs* iFs;
	RFile iFile;
	TParse iParse;
	TUint iFileAtt;
	TTime iFileModified;
	TNegotiationStage iNegStage;
	TUint iFileRecFlags;
	TFileName iRemoteFileName;
	TInt iTotalBytesInMultipleFiles;
	TInt iTotalBytesInMultipleFilesReceived;
	TInt iLastFile;
	TInt iNumOfFiles;
	CDesCArray* iRemoteFilesAlreadyPresent;
	CDesCArray* iFilesReceivedAsTemps;
	TFileName iReceivingFolderPath;
private:
	class CTimeStampAndFileAttributes:public CBase
		{
	public:
		~CTimeStampAndFileAttributes();
		static CTimeStampAndFileAttributes* NewL();
		void SetL(TTime& aFileModified,TUint& aFileAtt);
		void Get(TInt aIndex,TTime& aFileModified,TUint& aFileAtt) const;
	private:
		void ConstructL();
		CArrayFixSeg<TTime> *iFileModified;
		CArrayFixSeg<TUint> *iFileAtt;
		} ;

private:
	class CTimeStampAndFileAttributes* iFileTimeAtt;

	};

class CEikIrFileSaveAsDialog: public CEikFileSaveAsDialog
	{
public:
	CEikIrFileSaveAsDialog(TDes* aFileName,TDes& aRemoteFileName,const TDesC* aTitle);
private:
	void PreLayoutDynInitL();
private:
	TDes& iRemoteFileName;
	};

#endif