// TXTETEXT.H
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#if !defined(__TXTETEXT_H__)
#define __TXTETEXT_H__

#if !defined(__E32STD_H__)
#include <e32std.h>
#endif
#if !defined(__E32BASE_H__)
#include <e32base.h>
#endif

#if !defined(__FLDSET_H__)
#include <fldset.h>
#endif

#if !defined(__S32STD_H__)
#include <S32std.h>
#endif

//
// Classes declared in this file
class TEtextComponentInfo;
class CEditableText;
	class CPlainText;
//
// Classes referenced
class CParaFormatLayer;
class CCharFormatLayer;
class MTextFieldFactory;
class CTextFieldSet;
class CTextField;
class TFindFieldInfo;
struct SInlineEditData;
class MFepGetterOfFormatOfFepInlineText;
class TCharFormat;


const TUid KEditableTextUid8={268435548};
const TUid KPlainTextFieldDataUid={268435555};
const TUid KPlainTextCharacterDataUid8={268435556};
const TUid KClipboardUidTypePlainText8={268435507};

const TUid KEditableTextUid16={268450334};
const TUid KPlainTextCharacterDataUid16={268450341};
const TUid KClipboardUidTypePlainText16={268450333};

#if defined(_UNICODE)
	#define KClipboardUidTypePlainText KClipboardUidTypePlainText16
	#define KPlainTextCharacterDataUid KPlainTextCharacterDataUid16
	#define KEditableTextUid KEditableTextUid16
#else
	#define KClipboardUidTypePlainText KClipboardUidTypePlainText8
	#define KPlainTextCharacterDataUid KPlainTextCharacterDataUid8
	#define KEditableTextUid KEditableTextUid8
#endif

//

const TInt KMaxFieldBufferSize=0x14;


//
// Declares the minimal behaviour that derived classes must provide.

class CEditableText : public CBase
	{
public:
	IMPORT_C ~CEditableText(); // added by David Batchelor (4/11/1998) for supporting front-end-processor inline-editing
//	Persistance
	IMPORT_C TStreamId StoreL(CStreamStore& aStore)const;
	IMPORT_C void RestoreL(const CStreamStore& aStore,TStreamId aStreamId);
	// virtual persist functions to be provided:
	virtual void ExternalizeL(RWriteStream& aStream)const;
	virtual void InternalizeL(RReadStream& aStream);
	virtual void StoreComponentsL(CStreamStore& aStore,CStoreMap& aMap)const=0;
	virtual void RestoreComponentsL(const CStreamStore& aStore)=0;
//	Modifier functions
	virtual void Reset()=0;
	virtual void InsertL(TInt aInsertPos,const TChar& aChar)=0;
	virtual void InsertL(TInt aInsertPos,const TDesC& aBuf)=0;
	virtual TBool DeleteL(TInt aPos,TInt aLength)=0;
//	Interrogation functions
	virtual TPtrC Read(TInt aStartPos)const=0;  // The end-of-document character will be present in the view.
	virtual TPtrC Read(TInt aStartPos,TInt aLength)const=0;
	virtual void Extract(TDes& aBuf,TInt aPos=0)const=0;  // Copies doc contents to aBuf, starting at aPos.
	virtual void Extract(TDes& aBuf,TInt aPos,TInt aLength)const=0;
//	Copy/Paste
	virtual void CopyToStoreL(CStreamStore& aStore,CStreamDictionary& aDictionary,TInt aPos,TInt aLength)const=0;
	virtual TInt PasteFromStoreL(const CStreamStore& aStore,const CStreamDictionary& aDictionary,TInt aPos)=0;
//	Utility functions
	virtual TInt WordCount()const=0;
	virtual TInt ParagraphCount()const=0;
	virtual TInt DocumentLength()const=0;  // Returns a character count, excluding the EOD marker.
	//
	// Reset aPos to the char at the start of the para. containing aPos.  Returns the number of chars. skipped.
	virtual TInt ToParagraphStart(TInt& aPos)const=0;  
	//
	inline TBool HasChanged()const;
	virtual void GetWordInfo(TInt aCurrentPos,TInt& aStartPos,TInt& aLength,
						TBool aPictureIsDelimiter,TBool aPunctuationIsDelimiter)const=0;
	IMPORT_C virtual TInt ScanWords(TInt& aPos,TUint& aScanMask)const;
	IMPORT_C virtual TInt ScanParas(TInt& aPos,TUint& aScanMask)const;
	IMPORT_C virtual void SetHasChanged(TBool aHasChanged);
// functions added by David Batchelor (4/11/1998) for supporting front-end-processor inline-editing
	IMPORT_C void StartFepInlineEditL(TBool& aParagraphContainingStartPositionOfInlineTextHasChangedFormat,TInt& aNumberOfCharactersSuccessfullyDeleted,TInt& aNumberOfCharactersSuccessfullyInserted,TInt& aPositionOfInsertionPointInDocument,TInt aNewPositionOfInsertionPointInDocument,const TDesC& aInitialInlineText,TInt aPositionOfInlineTextInDocument,TInt aNumberOfCharactersToHide,MFepGetterOfFormatOfFepInlineText& aGetterOfFormatOfFepInlineText);
	IMPORT_C void UpdateFepInlineTextL(TBool& aParagraphContainingStartPositionOfInlineTextHasChangedFormat,TInt& aNumberOfCharactersSuccessfullyDeleted,TInt& aNumberOfCharactersSuccessfullyInserted,TInt& aPositionOfInsertionPointInDocument,TInt aNewPositionOfInsertionPointInDocument,const TDesC& aNewInlineText);
	IMPORT_C void CommitFepInlineEditL(TBool& aParagraphContainingStartPositionOfInlineTextHasChangedFormat,TInt& aNumberOfCharactersSuccessfullyDeleted,TInt& aNumberOfCharactersSuccessfullyInserted,TInt& aPositionOfInsertionPointInDocument,TInt aNewPositionOfInsertionPointInDocument);
	IMPORT_C void CancelFepInlineEdit(TBool& aParagraphContainingStartPositionOfInlineTextHasChangedFormat,TInt& aNumberOfCharactersSuccessfullyDeleted,TInt& aNumberOfCharactersSuccessfullyInserted,TInt& aPositionOfInsertionPointInDocument,TInt aNewPositionOfInsertionPointInDocument);
protected:
// function added by David Batchelor (4/11/1998) for supporting front-end-processor inline-editing
	IMPORT_C void OverrideFormatOfInlineTextIfApplicable(TPtrC& aView,TCharFormat& aFormat,TInt aStartPos)const;
private:
// friend added by David Batchelor (4/11/1998) for supporting front-end-processor inline-editing
	friend struct SGlobalTextAndInlineEditDataPair;
protected:
	TBool iHasChanged;  // reset on NewL and Restore
public:
	enum TDocumentStorage {EFlatStorage,ESegmentedStorage};
	enum {EDefaultTextGranularity=0x100};
	enum {//  Special character definitions.
		EParagraphDelimiter=0x06,
		ELineBreak=0x07,
		EPageBreak=0x08,
		ETabCharacter=0x09,
		ENonBreakingTab=0x0a,
		ENonBreakingHyphen=0x0b,
		EPotentialHyphen=0x0c,
		ENonBreakingSpace=0x10,
		EPictureCharacter=0x0e,
		EVisibleSpaceCharacter=0x0f
		};
	};


// Provides information relating to the number of components owned by 
// an Editable Text instance.

class TEtextComponentInfo
	{
public:
	IMPORT_C TEtextComponentInfo();
	IMPORT_C TEtextComponentInfo(TInt aFieldCount,TInt aPictureCount,TInt aStyleCount);
public:
	TInt iFieldCount;
	TInt iPictureCount;
	TInt iStyleCount;
	};

	
// Provides storage of unformatted text only and basic text services, including fields;
// most importantly text scanning routines.

typedef CArrayFix<TInt> TPageTable;
class CPlainText : public CEditableText
	{
public:
	enum TTextOrganisation {EOrganiseByParagraph,EOrganiseByLine};
	enum {
		EScanBackwards=0x01,
		EScanStayIfBoundary=0x02,
		EScanToUnitStart=0x04,
		EScanToUnitEnd=0x08,
		EScanJoinDelimiters=0x10,
		EScanPictureIsDelimiter=0x20,
		EScanPunctuationIsDelimiter=0x40  // hyphen & apostrophe are *never* word delimiters
		};


	enum TScanDataEnd{EScanEndOfData=-1};
public:
	IMPORT_C static CPlainText* NewL(TDocumentStorage aStorage=ESegmentedStorage,TInt aDefaultTextGranularity=EDefaultTextGranularity);
	IMPORT_C static CPlainText* NewL(const CStreamStore& aStore,TStreamId aStreamId,
									 MTextFieldFactory* aFieldFactory=NULL,
									 TDocumentStorage aStorage=ESegmentedStorage);
	IMPORT_C virtual ~CPlainText();
	//
	// Primary Persist functions
	IMPORT_C virtual void StoreComponentsL(CStreamStore& aStore,CStoreMap& aMap)const;
	IMPORT_C virtual void RestoreComponentsL(const CStreamStore& aStore);
	IMPORT_C virtual void ExternalizeL(RWriteStream& aStream)const;
	IMPORT_C virtual void InternalizeL(RReadStream& aStream);
	//
	// Secondary Persist functions
	//
	// write out a length count in front of the text stream
	IMPORT_C void ExternalizePlainTextL(RWriteStream& aStream)const;  // Save just text (no fields)
	IMPORT_C void InternalizePlainTextL(RReadStream& aStream);
	//
	// do not write the length count; the client is responsible for this
	IMPORT_C void ExternalizePlainTextNoLengthCountL(RWriteStream& aStream)const;
	IMPORT_C void InternalizePlainTextL(RReadStream& aStream,TInt aLength); // aLength = characters, not bytes
	//
	// import and export text delimited by CRs and LFs
	IMPORT_C void ImportTextL(TInt aPos,RReadStream& aInput,TTextOrganisation aTextOrganisation,
							  TInt aMaxOutputChars = KMaxTInt,TInt aMaxInputChars = KMaxTInt,
							  TInt* aOutputChars = NULL,TInt* aInputChars = NULL);
	IMPORT_C void ExportTextL(TInt aPos,RWriteStream& aOutput,TTextOrganisation aTextOrganisation,
							  TInt aMaxOutputChars = KMaxTInt,TInt aMaxInputChars = KMaxTInt,
							  TInt aMaxLineLength = KMaxTInt,
							  TInt* aOutputChars = NULL,TInt* aInputChars = NULL) const;
	//
	//
	IMPORT_C void StoreFieldComponentsL(CStreamStore& aStore,CStoreMap& aMap)const;
	IMPORT_C void RestoreFieldComponentsL(const CStreamStore& aStore);
	IMPORT_C void ExternalizeFieldDataL(RWriteStream& aStream)const;  // Save just field data
	IMPORT_C void InternalizeFieldDataL(RReadStream& aStream);
	//
	// Modifier functions
	IMPORT_C virtual void Reset();
	IMPORT_C virtual void InsertL(TInt aPos,const TChar& aChar);
	IMPORT_C virtual void InsertL(TInt aPos,const TDesC& aBuf);
	IMPORT_C virtual TBool DeleteL(TInt aPos,TInt aLength);
	IMPORT_C virtual TInt ImportTextFileL(TInt aPos,const TDes& aFileName,TTextOrganisation aTextOrganisation);
	IMPORT_C virtual void ExportAsTextL(const TDes& aFileName,TTextOrganisation aTextOrganisation,TInt aLineWrap)const;
	//
	// Interrogation functions
	IMPORT_C virtual TPtrC Read(TInt aStartPos)const;
	IMPORT_C virtual TPtrC Read(TInt aStartPos,TInt aLength)const;
	IMPORT_C virtual void Extract(TDes& aBuf,TInt aPos=0)const;
	IMPORT_C virtual void Extract(TDes& aBuf,TInt aPos,TInt aLength)const;
	//
	// Copy/Paste
	IMPORT_C virtual void CopyToStoreL(CStreamStore& aStore,CStreamDictionary& aDictionary,TInt aPos,TInt aLength)const;
	IMPORT_C virtual TInt PasteFromStoreL(const CStreamStore& aStore,const CStreamDictionary& aDictionary,TInt aPos);
	//
	// Utility functions
	IMPORT_C void SetPageTable(TPageTable* aPageTable);  // Links etext to a page table.
	IMPORT_C TInt PageContainingPos(TInt aPos)const;
	IMPORT_C virtual TInt DocumentLength()const;
 	IMPORT_C virtual TInt WordCount()const;
	IMPORT_C virtual TInt ParagraphCount()const;
	IMPORT_C virtual TInt ToParagraphStart(TInt& aPos)const;
	IMPORT_C virtual TInt CharPosOfParagraph(TInt& aLength,TInt aParaOffset)const;
	IMPORT_C virtual TInt ParagraphNumberForPos(TInt& aPos)const;
	IMPORT_C virtual void GetWordInfo(TInt aCurrentPos,TInt& aStartPos,TInt& aLength,
						TBool aPictureIsDelimiter,TBool aPunctuationIsDelimiter)const;
	IMPORT_C virtual TInt ScanWords(TInt& aPos,TUint& aScanMask)const;
	IMPORT_C virtual TInt ScanParas(TInt& aPos,TUint& aScanMask)const;
	IMPORT_C virtual TEtextComponentInfo ComponentInfo()const;
	//
	// Field functions
	IMPORT_C void SetFieldFactory(MTextFieldFactory* aFactory);
	inline const MTextFieldFactory* FieldFactory()const;
	IMPORT_C CTextField* NewTextFieldL(TUid aFieldType)const;
	IMPORT_C void InsertFieldL(TInt aPos,CTextField* aField,TUid aFieldType);  // insert & evaluate field
	IMPORT_C virtual void UpdateFieldL(TInt aPos);  // updates the field at aPos
	// finds number of fields in range. Includes the field containing aPos, if applicable
	// aInfo is set to the first field in the range (if any are found)
	IMPORT_C void UpdateAllFieldsL(); 
	IMPORT_C TInt FieldCount() const;
	IMPORT_C const CTextField* TextField(TInt aPos)const;
	IMPORT_C TBool FindFields(TInt aPos) const; // returns ETrue if aPos is in a field (matching right)
	IMPORT_C TBool FindFields(TFindFieldInfo& aInfo,TInt aPos,TInt aRange=0) const;
	IMPORT_C TBool RemoveField(TInt aPos);  // remove the field at aPos 
	IMPORT_C TBool ConvertFieldToText(TInt aPos);  // convert field at aPos to plain text (no update first)
	IMPORT_C void ConvertAllFieldsToText(); //  convert all fields to plain text (doesn't update first)
protected:
	IMPORT_C CPlainText();
	IMPORT_C void ConstructL(TDocumentStorage aStorage=ESegmentedStorage,TInt aDefaultTextGranularity=EDefaultTextGranularity);
	IMPORT_C void ConstructL(const CStreamStore& aStore,TStreamId aStreamId,MTextFieldFactory* aFieldFactory,TDocumentStorage aStorage=ESegmentedStorage);
	IMPORT_C void DoConstructL(TDocumentStorage aStorage,TInt aDefaultTextGranularity,MTextFieldFactory* aFieldFactory=NULL);
	void DoExtract(TDes& aBuf,TInt aPos,TInt aLength)const;
	IMPORT_C void PtInsertL(TInt aInsertPos,const TDesC& aBuf);
	IMPORT_C void DoPtInsertL(TInt aPos,const TDesC& aBuf);
	IMPORT_C TBool DoPtDelete(TInt aPos,TInt aLength);
	void InsertL(TInt aPos,const CPlainText* aText);
	//
	// Streaming
	IMPORT_C void DoExternalizeFieldDataL(RWriteStream& aStream)const;
	IMPORT_C void DoInternalizeFieldDataL(RReadStream& aStream);
	IMPORT_C void DoExternalizePlainTextL(RWriteStream& aStream)const;
	IMPORT_C void DoInternalizePlainTextL(RReadStream& aStream);
	void DoCopyPlainTextToStreamL(RWriteStream& aStream,TInt aPos,TInt aLength)const;
	//	
	TStreamId DoCopyToStoreL(CStreamStore& aStore,CStreamDictionary& aDictionary,TInt aPos,TInt aLength)const;
	TInt DoPasteFromStoreL(const CStreamStore& aStore,TStreamId aStreamId,TInt aPos);
	void CopyComponentsL(CStreamStore& aStore,CStoreMap& aMap,TInt aPos,TInt aLength)const;
	void PasteComponentsL(const CStreamStore& aStore,TInt aPos);
	void CopyToStreamL(RWriteStream& aStream,TInt aPos,TInt aLength)const;
	//
	// Utility functions
	inline static void ConsumeAdornmentL(RReadStream& aStream);
	inline static TUid UidFromStreamL(RReadStream& aStream);
protected:
	enum {EImportBufSize=512};
	enum {EBiggestCharacterPaste=0x100000};  // 1M characters
	enum TUnitOfText{EUnitIsWord,EUnitIsParagraph};
	struct SScanData
		{
		TInt pos;  // Current character position
		TInt oldPos;  // Old character position
		TText* buf;  // Address of data (unicode sensitive)
		TInt currentSegLen;  // Number of characters left in segment
		TInt totalBufLen;  // Number of unread characters
		TInt delta;  // Specifies current scan direction
		TUint32 scanMask;  // Bitmask containing the scan settings
		enum{EInsideUnit=0x10000000,EStopEnd=0x20000000,EStopBegin=0x40000000,EIsDelimiter=0x80000000};
		};
private:
	CPlainText(const CPlainText& aPlainTextDoc);
	CPlainText& operator=(const CPlainText& aPlainTextDoc);
	TInt PasteFromStreamL(RReadStream& aStream,TInt aPos);
	//
	void InsertEodL();
	void InitScanControl(TInt& aPos,TUint& aScanMask,TUnitOfText aContext,SScanData& aScanData)const;
	void InitScanData(TInt aPos,SScanData& aScanData)const;
	void KillFieldSet();
	TInt CountUnits(TUnitOfText aContext)const;
	TInt ScanUnit(TInt& aPos,TUnitOfText aContext,SScanData& aScanData)const;
	TBool TestForDelimiter(TUnitOfText aContext,SScanData& aScanData)const;
	TBool GetChar(SScanData& aScanData,TChar& aChar)const;
	void UpdatePageTable(TInt aPos,TInt aLength);
	inline TBool FieldSetPresent()const;
	void CreateFieldSetL(TInt aDocumentLength);
protected:
	CBufBase* iByteStore;  // Handle on document storage class.
	TSwizzle<CTextFieldSet> iFieldSet;  // Handle on field storage class
	TPageTable* iPageTable;  // may be NULL.  Only ever used.
	//
	MTextFieldFactory* iFieldFactory;  // temporary handle to field factory during restoration.

	__DECLARE_TEST;
	};


#include <txtetext.inl>

#endif
