// FEPBASE.H
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#if !defined(__FEPBASE_H__)
#define __FEPBASE_H__

#if !defined(__E32STD_H__)
#include <E32STD.H>
#endif

#if !defined(__E32BASE_H__)
#include <E32BASE.H>
#endif

#if !defined(__F32FILE_H__)
#include <F32FILE.H>
#endif

#if !defined(__BRDCST_H__)
#include <BRDCST.H>
#endif

class TFepOnOrOffKeyData
	{
public:
	inline TFepOnOrOffKeyData(TUint aCharacterCodeForFoldedMatch, TUint aModifierMask, TUint aModifierValues) :iCharacterCodeForFoldedMatch(aCharacterCodeForFoldedMatch), iModifierMask(aModifierMask), iModifierValues(aModifierValues) {}
	inline TUint CharacterCodeForFoldedMatch() const {return iCharacterCodeForFoldedMatch;}
	inline TUint ModifierMask() const {return iModifierMask;}
	inline TUint ModifierValues() const {return iModifierValues;}
private:
	TUint iCharacterCodeForFoldedMatch;
	TUint iModifierMask;
	TUint iModifierValues;
	};

class RWriteStream;
class RReadStream;

class CFepGenericGlobalSettings : public CBase
	{
public:
	IMPORT_C static CFepGenericGlobalSettings* NewL(const TFepOnOrOffKeyData& aDefaultOnKeyData, const TFepOnOrOffKeyData& aDefaultOffKeyData, TBool aDefaultIsOn);
	IMPORT_C static CFepGenericGlobalSettings* NewLC(const TFepOnOrOffKeyData& aDefaultOnKeyData, const TFepOnOrOffKeyData& aDefaultOffKeyData, TBool aDefaultIsOn);
	IMPORT_C virtual ~CFepGenericGlobalSettings();
	IMPORT_C TFepOnOrOffKeyData OnKeyData() const;
	IMPORT_C void SetOnKeyData(const TFepOnOrOffKeyData& aOnKeyData);
	IMPORT_C TFepOnOrOffKeyData OffKeyData() const;
	IMPORT_C void SetOffKeyData(const TFepOnOrOffKeyData& aOffKeyData);
	IMPORT_C TBool IsOn() const;
	IMPORT_C void SetIsOn(TBool aIsOn);
	IMPORT_C void StoreChangesL();
	IMPORT_C void RefreshL();
private:
	CFepGenericGlobalSettings(const TFepOnOrOffKeyData& aDefaultOnKeyData, const TFepOnOrOffKeyData& aDefaultOffKeyData, TBool aDefaultIsOn);
	void ConstructL();
	static void WriteOnOrOffKeyDataToStreamL(const TFepOnOrOffKeyData& aOnOrOffKeyData, RWriteStream& aStream);
	static void ReadOnOrOffKeyDataFromStreamL(TFepOnOrOffKeyData& aOnOrOffKeyData, RReadStream& aStream);
private:
	CBrdBroadcastServerSession* iBroadcastServerSession;
	TFepOnOrOffKeyData iDefaultOnKeyData;
	TFepOnOrOffKeyData iDefaultOffKeyData;
	TBool iDefaultIsOn;
	TFepOnOrOffKeyData iOnKeyData;
	TFepOnOrOffKeyData iOffKeyData;
	TBool iIsOn;
	};

class MCoeFepObserver
	{
public:
	virtual void HandleStartOfTransactionL()=0;
private:
	IMPORT_C virtual void MCoeFepObserver_Reserved_1();
	IMPORT_C virtual void MCoeFepObserver_Reserved_2();
	};

IMPORT_C void FepObserverHandleStartOfTransactionL(MCoeFepObserver& aFepObserver);

class CCoeFepParameters : public CBase
	{
public:
	IMPORT_C static CCoeFepParameters* NewL(TUid aApplicationUid, const TDesC& aNameOfApplicationIniFile, const TFepOnOrOffKeyData& aDefaultOnKeyData, const TFepOnOrOffKeyData& aDefaultOffKeyData, TBool aDefaultIsOn, TBool aAllWindowsMustBeBackedUpWindows);
	IMPORT_C static CCoeFepParameters* NewLC(TUid aApplicationUid, const TDesC& aNameOfApplicationIniFile, const TFepOnOrOffKeyData& aDefaultOnKeyData, const TFepOnOrOffKeyData& aDefaultOffKeyData, TBool aDefaultIsOn, TBool aAllWindowsMustBeBackedUpWindows);
	IMPORT_C virtual ~CCoeFepParameters();
	IMPORT_C TUid ApplicationUid() const;
	IMPORT_C TPtrC NameOfApplicationIniFile() const;
	IMPORT_C TFepOnOrOffKeyData DefaultOnKeyData() const;
	IMPORT_C TFepOnOrOffKeyData DefaultOffKeyData() const;
	IMPORT_C TBool DefaultIsOn() const;
	IMPORT_C TBool AllWindowsMustBeBackedUpWindows() const;
private:
	CCoeFepParameters(TUid aApplicationUid, const TFepOnOrOffKeyData& aDefaultOnKeyData, const TFepOnOrOffKeyData& aDefaultOffKeyData, TBool aDefaultIsOn, TBool aAllWindowsMustBeBackedUpWindows);
	void ConstructL(const TDesC& aNameOfApplicationIniFile);
private:
	TUid iApplicationUid;
	HBufC* iNameOfApplicationIniFile;
	TFepOnOrOffKeyData iDefaultOnKeyData;
	TFepOnOrOffKeyData iDefaultOffKeyData;
	TBool iDefaultIsOn;
	TBool iAllWindowsMustBeBackedUpWindows;
	};

struct TKeyEvent;
struct TPointerEvent;
class CCoeControl;

class CCoeFep : public CBase
	{
public:
	enum TEventResponse
		{
		EEventWasNotConsumed,
		EEventWasConsumed
		};
	class MCharacterQueue
		{
	public:
		virtual void AppendCharacterL(TUint aCharacter)=0;
	private:
		IMPORT_C virtual void MCharacterQueue_Reserved_1();
		IMPORT_C virtual void MCharacterQueue_Reserved_2();
		};
public:
	IMPORT_C virtual ~CCoeFep();
	virtual void CancelTransaction()=0;
	// the following functions are to be called by applications that do not always have an active-scheduler running, (e.g. OPLR)
	IMPORT_C TEventResponse OfferKeyEventL(MCharacterQueue& aCharacterQueue, const TKeyEvent& aKeyEvent, TInt aEventCode); // aEventCode would have been of type TEventCode (as defined in W32STD.H), except for the fact that enums cannot be forward declared
	IMPORT_C TEventResponse OfferPointerEventL(MCharacterQueue& aCharacterQueue, const TPointerEvent& aPointerEvent, const CCoeControl* aWindowOwningControl);
	IMPORT_C static TEventResponse OfferAsynchronousEventCompletionL(CCoeFep* aFep, MCharacterQueue& aCharacterQueue); // aFep may be NULL
	virtual void NotifyOfGainingForeground()=0;
	virtual void NotifyOfLosingForeground()=0;
private:
	class CBroadcastReceiver : public CBrdBroadcastServerSessionActiveWrapper
		{
	public:
		static CBroadcastReceiver* NewLC(CBrdBroadcastServerSession& aBroadcastServerSession, TUid aAttributeUid, TUid aApplicationUid, CCoeFep& aFep);
	private:
		CBroadcastReceiver(CBrdBroadcastServerSession& aBroadcastServerSession, TUid aAttributeUid, TUid aApplicationUid, CCoeFep& aFep);
		virtual void HandleBroadcastReceiptL();
	private:
		CCoeFep& iFep;
		};
protected:
	IMPORT_C CCoeFep();
	IMPORT_C void BaseConstructL(TInt aNumberOfAttributeUidsDependedOn, TUid aApplicationUid, const TDesC& aNameOfApplicationIniFile, const TFepOnOrOffKeyData& aDefaultOnKeyData, const TFepOnOrOffKeyData& aDefaultOffKeyData, TBool aDefaultIsOn);
	IMPORT_C void MakeDependentOnAttributeL(TUid aAttributeUid);
	IMPORT_C MCharacterQueue* CharacterQueue(); // the object returned by this function is to be used (if not NULL) instead of simulating the key-event via CCoeEnv
	IMPORT_C void WriteAttributeDataToStreamAtGlobalScopeL(TUid aAttributeUid);
	IMPORT_C void WriteAttributeDataToStreamAtApplicationScopeL(TUid aAttributeUid);
	IMPORT_C void ReadAttributeDataFromStreamL(TUid aAttributeUid);
	IMPORT_C TBool IsTurnedOnByL(TUint aCharacterCode, TUint aModifiers) const;
	IMPORT_C TBool IsTurnedOffByL(TUint aCharacterCode, TUint aModifiers) const;
	IMPORT_C TBool IsOn() const;
private:
	void RefreshOnAndOffKeyDataL();
	void RefreshIsOnL();
	void StoreIsOnL(TBool aIsOn) const;
	void WriteAttributeDataToStreamL(TUid aAttributeUid, TBool aAtGlobalScope);
	static TBool KeyEventMatchesOnOrOffKeyData(TUint aCharacterCode, TUint aModifiers, const TFepOnOrOffKeyData& aOnOrOffKeyData);
	static void SetPointerToCharacterQueueToNull(TAny* aPointerToPointerToCharacterQueue);
	virtual void WriteAttributeDataToStreamL(TUid aAttributeUid, RWriteStream& aStream) const=0;
	virtual void ReadAttributeDataFromStreamL(TUid aAttributeUid, RReadStream& aStream)=0;
	virtual void IsOnHasChangedState()=0;
	virtual TEventResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TInt aEventCode)=0; // aEventCode would have been of type TEventCode (as defined in W32STD.H), except for the fact that enums cannot be forward declared
	virtual TEventResponse OfferPointerEventL(const TPointerEvent& aPointerEvent, const CCoeControl* aWindowOwningControl)=0;
	IMPORT_C virtual void CCoeFep_Reserved_1();
	IMPORT_C virtual void CCoeFep_Reserved_2();
private:
	friend CBroadcastReceiver;
private:
	TInt iNumberOfAttributeUidsDependedOn;
	TUid iApplicationUid;
	HBufC* iNameOfApplicationIniFile;
	TFepOnOrOffKeyData iDefaultOnKeyData;
	TFepOnOrOffKeyData iDefaultOffKeyData;
	TBool iDefaultIsOn;
	TFepOnOrOffKeyData iOnKeyData;
	TFepOnOrOffKeyData iOffKeyData;
	TBool iIsOn;
	CBrdBroadcastServerSession* iBroadcastServerSession;
	CArrayFix<CBroadcastReceiver*>* iArrayOfBroadcastReceivers;
	MCharacterQueue* iCharacterQueue;
	TAny* iSpareForFutureUse;
	};

class CFepFastFileAccessor : public CBase
	{
public:
	IMPORT_C static CFepFastFileAccessor* NewL(RFs& aFileServerSession);
	IMPORT_C static CFepFastFileAccessor* NewLC(RFs& aFileServerSession);
	IMPORT_C virtual ~CFepFastFileAccessor();
	IMPORT_C void AddFileL(const TDesC& aFileName);
	IMPORT_C void RemoveFile(const TDesC& aFileName);
	inline void GetData(const TDesC& aFileName, const TUint8*& aData, TInt& aDataLength) const {GetData(aFileName, aData, aDataLength, NULL);}
	inline void GetData(const TDesC& aFileName, const TUint8*& aData, TInt& aDataLength, TBool& aIsRom) const {GetData(aFileName, aData, aDataLength, &aIsRom);}
	IMPORT_C void FileHasChanged(const TDesC& aFileName);
	void ReLoadAllNonRomFilesL();
private:
	enum {EGranularity=5};
	struct SFile
		{
		HBufC* iName;
		TBool iIsRom;
		TUint8* iData;
		TInt iDataLength;
		};
	class CBroadcastReceiver : public CBrdBroadcastServerSessionActiveWrapper
		{
	public:
		enum {EBroadcastUid=0x1000162a};
	public:
		static CBroadcastReceiver* NewL(CBrdBroadcastServerSession& aBroadcastServerSession, CFepFastFileAccessor& aFepFastFileAccessor);
	private:
		CBroadcastReceiver(CBrdBroadcastServerSession& aBroadcastServerSession, CFepFastFileAccessor& aFepFastFileAccessor);
		virtual void HandleBroadcastReceiptL();
	private:
		CFepFastFileAccessor& iFepFastFileAccessor;
		};
private:
	CFepFastFileAccessor(RFs& aFileServerSession);
	void ConstructL();
	IMPORT_C void GetData(const TDesC& aFileName, const TUint8*& aData, TInt& aDataLength, TBool* aIsRom) const;
	void LoadNonRomFileL(SFile& aFile);
	void CloseArrayIfEmpty();
	static void CloseFile(TAny* aFile);
	static void CloseFile(SFile& aFile);
	IMPORT_C virtual void CFepFastFileAccessor_Reserved_1();
	IMPORT_C virtual void CFepFastFileAccessor_Reserved_2();
private:
	RFs& iFileServerSession;
	TInt iArrayLength;
	SFile* iArrayOfFiles;
	CBrdBroadcastServerSession* iBroadcastServerSession;
	CBroadcastReceiver* iBroadcastReceiver;
	};

class CFepGlobalDynamicFrequencyTable : public CBase
	{
public:
	typedef TInt (*TCharacterCompareFunction)(TUint aCharacter1, TUint aCharacter2); // returns a negative number if aCharacter1 "comes before" aCharacter2, a positive number if aCharacter2 "comes before" aCharacter1 or zero if they are equivalent
	enum TSortType
		{
		ESortByFrequencyThenByUserDefinedCompareFunction,
		ESortByUserDefinedCompareFunctionThenByFrequency
		};
	class MCharacterArray
		{
	public:
		virtual TInt NumberOfCharacters() const=0;
		virtual TUint CharacterAtIndex(TInt aIndex) const=0;
		virtual void SetCharacterAtIndex(TInt aIndex, TUint aCharacter)=0;
	private:
		IMPORT_C virtual void MCharacterArray_Reserved_1();
		IMPORT_C virtual void MCharacterArray_Reserved_2();
		};
public:
	IMPORT_C static CFepGlobalDynamicFrequencyTable* NewL(TInt aMaximumNumberOfCharacters);
	IMPORT_C static CFepGlobalDynamicFrequencyTable* NewLC(TInt aMaximumNumberOfCharacters);
	IMPORT_C virtual ~CFepGlobalDynamicFrequencyTable();
	IMPORT_C void IncrementFrequencyOfCharacter(TUint aCharacter);
	IMPORT_C void SortL(MCharacterArray& aCharacterArray, TCharacterCompareFunction aUserDefinedCharacterCompareFunction, TSortType aSortType);
	IMPORT_C void Reset();
private:
	struct SSortItem
		{
		TUint iCharacter;
		TInt iCount;
		TInt iOriginalIndex;
		};
	typedef TBool (*TFirstParameterComesBeforeSecondFunction)(const SSortItem& aSortItem1, const SSortItem& aSortItem2, TCharacterCompareFunction aUserDefinedCharacterCompareFunction); // returns a non-zero if aSortItem1 "comes before" aSortItem2
	struct SGlobalData
		{
		struct SArrayOfCharactersOrderedByAge
			{
			TInt iMaximumCount;
			TInt iCount;
			TInt iIndexOfOldest;
			TUint* iArray;
			};
		struct SArrayOfCountedCharactersOrderedByCharacterEncoding
			{
			struct SCountedCharacter
				{
				TUint iCharacter;
				TInt iCount;
				};
			TInt iCount;
			SCountedCharacter* iArray;
			};
		SArrayOfCharactersOrderedByAge iArrayOfCharactersOrderedByAge;
		SArrayOfCountedCharactersOrderedByCharacterEncoding iArrayOfCountedCharactersOrderedByCharacterEncoding;
		};
private:
	CFepGlobalDynamicFrequencyTable();
	void ConstructL(TInt aMaximumNumberOfCharacters);
	void HeapSort(TInt aNumberOfSortItems, SSortItem* aArrayOfSortItems, TFirstParameterComesBeforeSecondFunction aFirstParameterComesBeforeSecondFunction, TCharacterCompareFunction aUserDefinedCharacterCompareFunction);
	TInt IndexInArrayOfCountedCharactersOrderedByCharacterEncoding(TUint aCharacter, TBool& aExists);
	static TBool FirstParameterComesBeforeSecondWhenSortedByFrequencyThenByUserDefinedCompareFunction(const SSortItem& aSortItem1, const SSortItem& aSortItem2, TCharacterCompareFunction aUserDefinedCharacterCompareFunction);
	static TBool FirstParameterComesBeforeSecondWhenSortedByUserDefinedCompareFunctionThenByFrequency(const SSortItem& aSortItem1, const SSortItem& aSortItem2, TCharacterCompareFunction aUserDefinedCharacterCompareFunction);
private:
	RMutex iMutex;
	RChunk iChunk;
	SGlobalData* iGlobalData; // this pointer does not own anything
	TAny* iSpareForFutureUse;
	};

class TCharFormat;

class MFepGetterOfFormatOfFepInlineText // to be overridden by front-end processors wishing to do inline editing
	{
public:
	virtual void GetFormatOfFepInlineText(TCharFormat& aFormat, TInt& aNumberOfCharactersWithSameFormat, TInt aPositionOfCharacter) const=0;
private:
	IMPORT_C virtual void MFepGetterOfFormatOfFepInlineText_Reserved_1();
	IMPORT_C virtual void MFepGetterOfFormatOfFepInlineText_Reserved_2();
	};

class MFepItemSupportingFepInlineEditing // to be overridden by text-editors
	{
public:
	virtual void StartFepInlineEditL(const TDesC& aInitialInlineText, TInt aPositionOfInsertionPointInInlineText, MFepGetterOfFormatOfFepInlineText& aGetterOfFormatOfFepInlineText)=0;
	virtual void UpdateFepInlineTextL(const TDesC& aNewInlineText, TInt aPositionOfInsertionPointInInlineText)=0;
	virtual void CommitFepInlineEditL()=0;
	virtual void CancelFepInlineEdit()=0;
	virtual void GetFormatBeforeInsertionPointForFepInlineEdit(TCharFormat& aFormat) const=0;
	virtual void GetFormatAfterInsertionPointForFepInlineEdit(TCharFormat& aFormat) const=0;
private:
	IMPORT_C virtual void MFepItemSupportingFepInlineEditing_Reserved_1();
	IMPORT_C virtual void MFepItemSupportingFepInlineEditing_Reserved_2();
	};

class MFepItemSupportingFepContextInformation // to be overridden by text-editors
	{
public:
	virtual void GetFepContextTextBeforeInsertionPoint(TDes& aTextBeforeInsertionPoint) const=0;
	virtual void GetFepContextTextAfterInsertionPoint(TDes& aTextAfterInsertionPoint) const=0;
	virtual TInt FepContextLengthOfSelection() const=0;
	virtual void GetFepContextSelection(TDes& aSelection) const=0;
private:
	IMPORT_C virtual void MFepItemSupportingFepContextInformation_Reserved_1();
	IMPORT_C virtual void MFepItemSupportingFepContextInformation_Reserved_2();
	};

class MCoeFepAwareItem // to be overridden by text-editors
	{
public:
	virtual TBool IsFocused() const=0;
	virtual MFepItemSupportingFepInlineEditing* ItemSupportingFepInlineEditing()=0;
	virtual MFepItemSupportingFepContextInformation* ItemSupportingFepContextInformation()=0;
private:
	IMPORT_C virtual void MCoeFepAwareItem_Reserved_1();
	IMPORT_C virtual void MCoeFepAwareItem_Reserved_2();
	};

IMPORT_C TBool FepAwareItemIsFocused(const MCoeFepAwareItem& aFepAwareItem);

#endif

