// IMCVFILT.H
//
// Copyright (c) 1998 Symbian Ltd.  All rights reserved. 
//

#if !defined(__IMCVFILT_H__)
#define __IMCVFILT_H__

#if !defined(__S32BUF_H__)
#include <s32buf.h>
#endif

#if !defined(__S32STOR_H__)
#include <s32stor.h>
#endif

#if !defined (__IMCVDATA_H__)
#include "imcvdata.h"
#endif

#if !defined (__TXTRICH_H__)
#include <txtrich.h>
#endif

#if !defined (__IMCVCONV_H__)
#include "imcvconv.h"
#endif

#if !defined (__MIUTATCH_H__)
#include <miutatch.h>
#endif

#if !defined (__IMCVTEXT_H__)
#include "imcvtext.h"
#endif

enum TImBodyConvAlgorithm
	{
	ENoAlgorithm,
//	EMimeAlgorithm,
	EQPEncode,
	EQPDecode,
	EQPDecodeTextAttach,
	EBase64Encode,
	EBase64Decode,
	EBase64DecodeBodyText,
	EUUEncode,
	EUUDecode
	};
	
// Used in CImSendConvert
enum TImSendEncoding 
	{ 
	ESendNoAlgorithm,
	ESendMimeAlgorithm
	};	

struct SAttachmentInfo
	{
	TInt iSize;
	TFileName iName;
	TFileName iPath;
	};

//////////////////////////////////////////////////////////////////////////////////////////////
// MimeHeader stuff starts here
//////////////////////////////////////////////////////////////////////////////////////////////

class CImMimeSend: public CBase
	{
public:
	static CImMimeSend* NewL(TImSendEncoding anAlgorithm, TDesC8* aCharset);
	static CImMimeSend* NewLC(TImSendEncoding anAlgorithm, TDesC8* aCharset);
	~CImMimeSend();

	TInt HeaderNextLine(TDes8& rOutputLine, TInt& rPaddingCount);
	TInt BodyHeaderNextLine(TDes8& rOutputLine, TInt& rPaddingCount);
	void SetAttachments(TInt aNumberOfAttachments);
	void CalcBoundaryStringL();
	TDesC8& GetBoundaryString();

private:
	CImMimeSend( TDesC8* aCharset);
	void ConstructL(TImSendEncoding anAlgorithm);

private:
	enum{KBoundaryStringLength = 55};

	enum TMimeHeaderState		// Defines the state order of the TMimeSend object... !! DO NOT CHANGE THE ORDER !!
		{
		EMimeVersion = 0,		// 0
		EContentType,
		EBoundaryString,
		ETransferEncoding,
		EContentLanguage,
		ECRLF,
		EEndOfBodyHeader
		};

private:
	inline TInt CRLFLine(TDes8& rOutputLine);
	inline TInt BlankLine(TDes8& rOutputLine);
	inline TInt MimeVersion(TDes8& rOutputLine);
	inline TInt HeaderContentType(TDes8& rOutputLine);
	inline TInt TransferEncoding(TDes8& rOutputLine);
	inline TInt Boundary(TDes8& rOutputLine);
	inline TInt ContentLanguage(TDes8& rOutputLine);

private:
	TInt iHeaderState;
	TImSendEncoding iAlgorithm;
	TImConvert* iImConvert;
	HBufC8* iBoundaryString;
	TInt iNumberOfAttachments;
	TDesC8* iCharset;
	};

//////////////////////////////////////////////////////////////////////////////////////////////
// Body stuff starts here
//////////////////////////////////////////////////////////////////////////////////////////////
class CImBodyConversion : public CBase
	{
public:
	virtual TInt NextLine(TDes8& rOutputLine, TInt& rPaddingCount)=0;
	virtual ~CImBodyConversion();
	IMPORT_C void SetSource(CRichText* aSource, CImConvertCharconv* aConv, 
							TDesC8* aCharset, TInt aBodySize);

protected:
	CRichText* iRichTextBody;
	CImConvertCharconv* iConverter;
	TBool iUseRichText;
	TInt iBodySize;
	TInt iPos;
	TDesC8* iCharset;

	inline TBool IsBreakable(TUint8 aChar);
	static inline TBool IsEOL(TUint8 aChar);
	static inline TUint8 ReplacementChar(TUint8 aControlChar);
	static inline TBool IsPlain(TUint8 aChar);
	};

// encapsulation of identity encoding, except that the text is broken into 78-character lines.
class CImNoEncode : public CImBodyConversion
	{
public:
	CImNoEncode();
	TInt NextLine( TDes8& rOutputLine, TInt& rPaddingCount );	

protected:
	TBool SmartBreak( TInt aCurrentLineLength, const TUint8* pSource, TInt aMaxLineLength );
	};

// encapsulation of Quoted-printable encoding
class CImQPEncode : public CImBodyConversion
	{
public:
	IMPORT_C CImQPEncode( );
	IMPORT_C void EncodeLine( const TDesC8& aInputLine, TDes8& rOutputLine, TInt& rPaddingCount );
	IMPORT_C TInt NextLine( TDes8& rOutputLine, TInt& rPaddingCount );	// For Richtext objects set with SetBody()
private:
	TInt NextLine( const TDesC8& aInputLine, TDes8& rOutputLine, TInt& rPaddingCount );
protected:
	TBool SmartBreak( TInt aCurrentLineLength, const TUint8* pSource, TInt aMaxLength);
	TInt iMaxLength;
	};

// encapsulation of Quoted-printable decoding
class CImQPDecode : public CBase
	{
public:
	IMPORT_C CImQPDecode();
	IMPORT_C TInt DecodeLine( const TDesC8& anInputLine, TDes8& rOutputLine );	
	IMPORT_C TInt NextLine( const TDesC8& anInputLine, TDes8& rOutputLine, TBool aRichText );	
private:
	static TBool IsDigit( TUint8 aChar );
	};

//////////////////////////////////////////////////////////////////////////////////////////////
// Attachment stuff starts here
//////////////////////////////////////////////////////////////////////////////////////////////
class TImAttachmentFile;


// error states involved in sending attachments etc.
enum TIattErrorCode
	{
	KImAttNoError = 0,
	KImAttFinished = 1
	};

class CImAttachmentConversion : public CBase
	{
public:
	CImAttachmentConversion( RFs& anFs,
							 const CArrayFix<SAttachmentInfo>& anAttachmentList );
	virtual ~CImAttachmentConversion();
	TUint AttachmentsSize( );

	virtual TInt NextLine( TDes8& rOutputLine, TInt& rPaddingCount )=0;
	virtual TInt PrefixNextLine( TDes8& rOutputLine, TInt& rPaddingCount )=0;
	virtual TInt PostfixNextLine( TDes8& rOutputLine, TInt& rPaddingCount )=0;
	virtual TInt BodyHeaderNextLine( TDes8& rOutputLine, TInt& rPaddingCount )=0;

	inline TInt BlankLine( TDes8& rOutputLine, TInt& rPaddingCount );
	inline TInt CRLFLine( TDes8& rOutputLine, TInt& rPaddingCount );

protected:
	enum{KDecodeLineLength = 45};

	enum TImAttachmentSend
		{
		ENextFile = 0,
		EPrefixLines,
		EEncodeFile,
		EPostfixLines,
		EEndOfAttachments,
		ECloseDelimiter,
		ECRLFLine,
		EEnd
		};

protected:
	const RFs& iFs;
	const CArrayFix<SAttachmentInfo>& iAttachmentList;
	TImConvert* iImConvert;
	TImAttachmentFile* iAttachmentFile;
	TBuf8<KDecodeLineLength> iSourceLine;
	
	TInt iFileIndex;		// The following are init'ed in the Ctor list
	TInt iAttachmentState;  // so dont change there order
	TInt iPrefixState;
	TInt iPostfixState;
	
	};

// encapsulation of Base64 encoding
class CImBase64Encode : public CImAttachmentConversion
	{
public:
	CImBase64Encode( RFs& anFs,
					 const CArrayFix<SAttachmentInfo>& anAttachmentList,
					 const TDesC8& aBoundaryString );
	TInt NextLine( TDes8& rOutputLine, TInt& rPaddingCount);	
	TInt PrefixNextLine( TDes8& rOutputLine, TInt& rPaddingCount );
	TInt PostfixNextLine( TDes8& rOutputLine, TInt& rPaddingCount );
	TInt BodyHeaderNextLine( TDes8& rOutputLine, TInt& rPaddingCount );

private:
	enum TImAttachPrefix
		{
		EBoundaryString = 0,
		EContentType,
		ETransferEncoding,
		EDisposition,
		EBlankLine,
		EEndOfPrefix
		};

	enum TImBodyPrefix
		{
		EBBoundaryString = 0,
		EBContentType,
		EBTransferEncoding,
		EBBlankLine,
		EBEndOfPrefix
		};

	enum TImSplitLine
		{
		EFirstLine = 0,
		ESecondLine
		};

private:
	inline TInt Boundary( TDes8& rOutputLine );
	inline TInt AttachContentType( TDes8& rOutputLine );
	inline TInt AttachTransferEncoding( TDes8& rOutputLine );
	inline TInt Description( TDes8& rOutputLine );
	inline TInt Disposition( TDes8& rOutputLine );
	inline TInt BodyHeaderTransferEncoding( TDes8& rOutputLine );
	inline TInt BodyHeaderContentType( TDes8& rOutputLine );

private:
	const TDesC8& iBoundaryString;
	TInt iBodyHeaderState;
	TInt iLine;
	};

// encapsulation of UU encoding
class CImUUEncode : public CImAttachmentConversion
	{
public:
	CImUUEncode( RFs& anFs,
				 const CArrayFix<SAttachmentInfo>& anAttachmentList );
	TInt NextLine( TDes8& rOutputLine, TInt& rPaddingCount );	
	TInt PrefixNextLine( TDes8& rOutputLine, TInt& rPaddingCount );
	TInt PostfixNextLine( TDes8& rOutputLine, TInt& rPaddingCount );
	inline TInt BodyHeaderNextLine( TDes8& /*rOutputLine*/, TInt& /*rPaddingCount*/ ); //returns 0

private:
	enum TImBodyPrefix
		{
		EInvertedComma = 0,
		EEndString,
		EEndOfPostfix
		};
	};

#include "imcvfilt.inl"
#include "imcvqp.inl"

#endif
