// FRMTVIEW.H
//
// Copyright (c) 1997-1999 Symbian Ltd. All rights reserved.
//

#if !defined(__FRMTVIEW_H__)
#define __FRMTVIEW_H__

#if !defined(__E32STD_H__)
#include <e32std.h>
#endif
#if !defined(__E32BASE_H__)
#include <e32base.h>
#endif
#if !defined(__W32STD_H__)
#include <w32std.h>
#endif
#if !defined(__FRMTLAY_H__)
#include <frmtlay.h>
#endif
#if !defined(__FRMFRAME_H__)
#include <frmframe.h>
#endif

//
// Internal class - NOT part of interface
// 

class RScreenDisplay
	{
public:
	enum TClippingRects
		{
		EFClipTextArea=0x0001,
		EFClipLineCursor=0x0002,
		EFClipViewRect=0x0008,
		EFClipInvalid=0x0200,
		EFClipAllFlags=0xffff
		};
public:
	RScreenDisplay(TDrawTextLayoutContext* const aDrawTextLayoutContext); 
	void Close();
	void Destroy();
	inline void SetWindowsServer(RWsSession *aSession) {iSession=aSession;}
	inline void SetWindowGroup(RWindowGroup *aWin) {iGroupWin=aWin;}
	void SetWindow(RWindow *aWin);
	void SetGraphicsDeviceL(CBitmapDevice *aGd);
	void CreateContextL();
	void SetInvalidRect(const TRect& aRect);
	void SetInvalidRect(TInt aHeight);
	void SetInvalidRectHorizontal(TInt aWidth);
	void SetRects(TUint aRects);
	inline TRect LineCursorMargin() const;
	inline TPoint TopLeftTextArea() const;
	inline TBool IsLineCursor() const;
	void AddRects(TUint aRects);
	void SubRects(TUint aRects);
	TRect ClippingRect();	
	void ResetClippingRect();	
	void Scroll(TRect aRect,const TPoint& aBy);
	void Flush();
	void ClearRect(const TRect& aRect,const TRgb *aBackColor=NULL);
	void InvertRect(TRect aRect,const TRgb aInvertColor);
	void SetTextCursor(TPoint aPos, const TTextCursor &aCursor);
	void RemoveTextCursor();
	void BlastBitmap(const TPoint& aPoint,const CFbsBitmap* aBitmap,const TRect& aRect);
	void DrawPictureFrame(TFrameOverlay* aPictureFrame,const TRect& aLineRect);
	void Invalidate(TRect aRect);
	void ActivateContext();
	void ActivateContext(CGraphicsContext *aGc);
	void DectivateContext();
	void DectivateContext(CGraphicsContext *aGc);
private:
	void DestroyContexts();
#if defined(TIMING_CODE)
public:
	class TTestTimingCode* iTestTimingCode;
#endif
private:
	RWsSession *iSession;
	RWindowGroup *iGroupWin;
	RWindow *iWin;
	CBitmapContext *iGc;
	CBitmapDevice *iGd;
	TDrawTextLayoutContext* const iDrawTextLayoutContext;
	TUint iRects;
	TRect iInvalidRect;
#if defined(TIMING_CODE)
public:
	inline void SetTimingFlags(TUint aFlags) {iTimingFlags=aFlags;}
	TUint iTimingFlags;
	inline void SetHandle(CWindowGc *aGc,RWsSession *aWs) {iTGc=aGc;iWs=aWs;}
	CWindowGc *iTGc;
	RWsSession *iWs;
#endif
	};

//
// Internal class - NOT part of interface
// 

class TCursor
	{
public:
	enum TCursors
		{
		EFNeitherCursor=0,
		EFTextCursor=0x0001,
		EFLineCursor=0x0002,
		EFBothCursors=EFTextCursor|EFLineCursor
		};
	enum TVisibility
		{
		EFCursorInvisible=0,
		EFCursorVisible,
		EFCursorFlashing
		};
private:
	enum
		{
		EFLineCursorToLabelGap=2,
		EFTextCursorWidth=3,		// In Pixels
		EFTextCursorInvertColor=0xffffff  
		};	
public:
	inline TCursor(TCursorPosition& aCursorPos,RScreenDisplay& aDisplay);
	void SetLineCursorBitmap(const CFbsBitmap* aLineCursorBitmap);
	inline TUint LineCursorVisibility();
	inline TUint TextCursorVisibility();
	void SetVisibilityL(TUint aLineCursor,TUint aTextCursor);
	void SetPendingTextCursor(TInt aHeightInPixels, TInt aAscentInPixels);
	void SetWidthTypeL(TInt aWidth,TTextCursor::EType aType);
	void MatchCursorHeightToAdjacentChar(TBool aBasedOnCharBefore=ETrue);
	void DrawL(TUint aCursors);
	void UpdateSteadyCursor();
private:
	inline TCursor& operator=(TCursor& /*aLHS*/) {return *this;}
	void DrawL(TUint aCursors,TBool aIncludeSteady);
	void DrawLineCursor(TInt aHeight);
	void RemoveLineCursor();
	void DrawFlashingTextCursor(TPoint aBasePoint);
	void RemoveFlashingTextCursor();
	void ToggleSteadyTextCursor(TBool aMakeVisible,TPoint aBasePoint);
private:
	RScreenDisplay& iDisplay;
	TCursorPosition& iCursorPos;
	TUint iLineCursor;
	TUint iTextCursor;
	const CFbsBitmap* iLineCursorBitmap;	// Owned by user of CTextView
	TInt iTextCursorHeight;
	TInt iTextCursorAscent;
	TBool iDefaultTextCursor;
	TBool iBasedOnCharBefore;
	TBool iFlashingCursorCurrentlyVisible;
	TBool iSteadyCursorCurrentlyVisible;
	TRect iSteadyCursorLocation;
	TInt iCursorWidth;
	TTextCursor::EType iCursorType;
	};

class CTextView : public CBase
	{
friend class CTestTextView;
public:
	enum TPriorities
		{
		EFBackgroundFormattingPriority=(CActive::EPriorityIdle+CActive::EPriorityLow)/2
		};
	enum		//Parameters to XyPosToDocPosL
		{
		EFFirstCharOnLine=TCursorPosition::EFFirstCharOnLine,
		EFLastCharOnLine=TCursorPosition::EFLastCharOnLine
		};
	enum TBeforeAfter
		{
		EFCharacterBefore=ETrue,
		EFCharacterAfter=EFalse
		};
	enum TDiscard		//Parameter to SetViewL
		{
		EFViewDiscardAllFormat,		//Throw all the format away
		EFViewDontDiscardFormat,		//Dont throw away format until it is know that it is not needed
		EFViewDiscardAllNoRedraw,		//Throws away all format but does not do a redraw
		EFViewDontDiscardFullRedraw			//Dont throw away format until it is know that it is not needed
		};
private:
	enum TDoHorizontalScroll		//Parameter to ViewL()
		{
		EFNoHorizontalScroll=EFalse,
		EFCheckForHorizontalScroll=ETrue
		};
	enum TDrawParameters
		{
		EFDrawAllWindow=CLayoutData::EFLargeNumber  //Must be larger than the pixels height of any window.
		};
	enum TSelectionVisibility
		{
		EFNothingVisible=0x00,
		EFSelectionVisible=0x01,
		EFPictureFrameEnabled=0x02,
		EFEverythingVisible=0x03
		};
	enum THorizontalScrollJump
		{
		EFDefaultHorizontalScrollJump=20	  // In Pixels
#if defined(_DEBUG)
		,EFUnreasonablyLargeHorizontalScrollJump=10000
#endif
		};
	enum TPictureFrameBlobWidths
		{
		EFFrameVisibleBlobWidth=10, // In Pixels
		EFFrameActiveBlobWidth=20
		};
	enum THorizontalScroll
		{
		EFNoPreviousHorizontalScroll=0,
		EFPreviousHorizontalScroll
		};
	enum TMemoryStatus
		{
		EFMemoryOK=EFalse,
		EFOutOfMemory=ETrue,
		EFRecovering			//This is assuming that ETrue!=-1
		};
public:
	//Creation, destruction
	IMPORT_C static CTextView *NewL(CTextLayout *aLayout,const TRect &aDisplay,CBitmapDevice *aGd
		,MGraphicsDeviceMap *aDeviceMap,RWindow *aWin,RWindowGroup *aGroupWin,RWsSession *aSession);		//This calls several of the Set'er functions bellow
	IMPORT_C ~CTextView();

	//Set'er and Get'er functions of global parameters
	IMPORT_C void SetDisplayContextL(CBitmapDevice *aGd,RWindow *aWin
									,RWindowGroup *aGroupWin,RWsSession *aSession);		//If any of these are NULL then they will not be changed
	IMPORT_C void SetLayout(CTextLayout *aLayout);										
	IMPORT_C void SetViewRect(const TRect& aDisplay);
	IMPORT_C void SetMarginWidths(TInt aLabels,TInt aLineCursor);
	IMPORT_C void SetHorizontalScrollJump(TInt aScrollJump);
	IMPORT_C void SetLineCursorBitmap(const CFbsBitmap* aLineCursorBitmap);
	IMPORT_C void SetBackgroundColor(TRgb aColor);
	IMPORT_C void SetTextColorOverride(const TRgb* aOverrideColor=NULL);
	IMPORT_C void SetCursorVisibilityL(TUint aLineCursor,TUint aTextCursor);
	IMPORT_C void SetSelectionVisibilityL(TBool aSelectionVisible);
	IMPORT_C void EnablePictureFrameL(TBool aEnabled);
	IMPORT_C const TRect& ViewRect() const;
	IMPORT_C void MarginWidths(TInt& aLabels,TInt& aLineCursor) const;
	IMPORT_C TInt HorizontalScrollJump() const;
	IMPORT_C TInt LeftTextMargin() const;
 	IMPORT_C void SetLatentXPosition(TInt aLatentX);
	IMPORT_C void SetParagraphFillTextOnly(TBool aFillTextOnly);	// False by default
	IMPORT_C void SetCursorWidthTypeL(TTextCursor::EType aType,TInt aWidth=0);

	//Enquiry of Format statistics
	IMPORT_C TCursorSelection Selection() const;
	IMPORT_C TBool IsPictureFrameSelected(TRect& aPictureFrameRect,TInt& aDocPos) const;
	IMPORT_C TBool GetPictureRectangleL(TInt aDocPos,TRect& aPictureRect
									   ,TBool* const aCanScaleOrCrop=NULL) const;	//Returns ETrue if aDocPos is a picture	in format.
	IMPORT_C TBool GetPictureRectangleL(TPoint aXyPos,TRect& aPictureRect
									   ,TBool* const aCanScaleOrCrop=NULL);	//Returns ETrue if aPoint is a picture	in format.
	IMPORT_C TInt XyPosToDocPosL(TPoint& aPoint);	//aPoint changed to right most point on baseline
	IMPORT_C TBool DocPosToXyPosL(TInt aDocPos,TPoint& aPoint);
	IMPORT_C TRect ParagraphRectL(TInt aDocPos) const;		//Never enters OOM state
	IMPORT_C void CalculateHorizontalExtremesL(TInt& aLeftX,TInt& aRightX,TBool aOnlyVisibleLines);

	//Cursor movement and Selection setting functions
	IMPORT_C void MatchCursorHeightL(const TFontSpec& aFontSpec);
	IMPORT_C void MatchCursorHeightToAdjacentChar(TBeforeAfter aBasedOn=EFCharacterBefore);
	IMPORT_C TPoint SetSelectionL(const TCursorSelection& aSelection);		//Amount of scroll returned
	IMPORT_C void CancelSelectionL();
	IMPORT_C TPoint SetDocPosL(TInt aDocPos,TBool aDragSelectOn=EFalse);
	IMPORT_C TPoint SetXyPosL(TPoint aPos,TBool aDragSelectOn,TRect*& aPictureRect
																		,TInt& aPictureFrameEdges);
	IMPORT_C TPoint MoveCursorL(TCursorPosition::TMovementType& aMovement,TBool aDragSelectOn);

	//Scrolling functions
	IMPORT_C TInt ScrollDisplayL(TCursorPosition::TMovementType aMovement
			,CTextLayout::TAllowDisallow aScrollBlankSpace=CTextLayout::EFDisallowScrollingBlankSpace);		//Returns the amount of scroll that has taken place in the direction of scroll
	IMPORT_C TPoint SetViewLineAtTopL(TInt aLineNo);
	IMPORT_C void ScrollDisplayPixelsL(TInt& aDeltaY);
	IMPORT_C TInt ScrollDisplayLinesL(TInt& aDeltaLines
			,CTextLayout::TAllowDisallow aScrollBlankSpace=CTextLayout::EFDisallowScrollingBlankSpace);
	IMPORT_C TInt ScrollDisplayParagraphsL(TInt& aDeltaParas
			,CTextLayout::TAllowDisallow aScrollBlankSpace=CTextLayout::EFDisallowScrollingBlankSpace);
	IMPORT_C TPoint SetViewL(TInt aDocPos,TInt& aYPos
										,TViewYPosQualifier aYPosQualifier=TViewYPosQualifier()
										,CTextView::TDiscard aDiscardFormat=EFViewDontDiscardFormat);
 	IMPORT_C void SetLeftTextMargin(TInt aLeftMargin);			//Sets absolute horizontal scroll

	//Drawing functions
	IMPORT_C void DrawL(TRect aRect);

	//Notification of changes to document content of formatting
 	IMPORT_C void FormatTextL();
	IMPORT_C TInt HandleCharEditL(TUint aType=CTextLayout::EFCharacterInsert
								  ,TBool aFormatChanged=EFalse);	//Returns the amount of vertical scroll that has already taken place
	IMPORT_C void SetPendingSelection(const TCursorSelection& aSelection);
	IMPORT_C TPoint HandleRangeFormatChangeL(TCursorSelection aSelection,TBool aFormatChanged=EFalse);
	IMPORT_C TPoint HandleInsertDeleteL(TCursorSelection aSelection,TInt aDeletedChars
																	,TBool aFormatChanged=EFalse);
	IMPORT_C void HandleGlobalChangeL(TViewYPosQualifier aYPosQualifier=TViewYPosQualifier());
	IMPORT_C void HandleGlobalChangeNoRedrawL(TViewYPosQualifier aYPosQualifier=TViewYPosQualifier());
	IMPORT_C void HandleAdditionalCharactersAtEndL();
	IMPORT_C void FinishBackgroundFormattingL();
private:
	IMPORT_C static TInt IdleL(TAny *aSelf);
	IMPORT_C CTextView();
	IMPORT_C void ConstructL(CTextLayout *aLayout,const TRect &aDisplay,CBitmapDevice *aGd
		,MGraphicsDeviceMap *aDeviceMap,RWindow *aWin,RWindowGroup *aGroupWin,RWsSession *aSession);
	inline TInt TopViewRect() const;
	inline TBool IsFormatting() const;
	TBool NoMemoryCheckL();
	void StartIdleObject();
	TInt RepostionCursorL();
	inline void DrawWithPreviousHighlight();
	inline void DrawWithCurrentHighlight();
	TBool SelectionVisible() const;
	TInt CalculateBaseLinePos(TInt& aDocPos);
	TInt DrawAfterCursorMoveL(TInt aScrollBy);
	TBool NextLineL();
	void ClearRectAtBottomL(TInt aHeight);
	void ClearRectAtBottom(TInt aHeight);
	void DrawTextL(TInt aFromHeight=0, TInt aToHeight=EFDrawAllWindow);
	void DisplayNewLinesL(TInt aFrom,TInt aTo);
	void DrawCursorL(TUint aCursors=TCursor::EFBothCursors);
	TPoint DoMoveCursorL(TBool aDragSelectOn,TCursorPosition::TMovementType& aMovement
																			,TBool aAllowPictureFrame);
	void ScrollTextL(TInt aScrollY,TInt aFrom=0,TInt aScrollX=0);
	void ScrollRect(TRect& aRect,TInt aScrollY,TInt aFrom=0,TInt aScrollX=0);
	void ScrollRect(TInt aScrollY,TInt& aFrom,TInt& aTo);
	TPoint HandleBlockChangeL(TCursorSelection aSelection,TInt aOldCharsChanged,TBool aFormatChanged);
	void CheckScrollUpL();
	void ClearBottomPartialLineL(const TRect& aBottomLine);
	TInt CheckHorizontalScrollL(TInt aDocPos);
	TInt DoHorizontalScrollDisplayL(TCursorPosition::TMovementType aMovement
																		,CTextLayout::TAllowDisallow aScrollBlankSpace);
	TInt DoScrollDisplayL(TCursorPosition::TMovementType aMovement,CTextLayout::TAllowDisallow aScrollBlankSpace);
	void ScrollDisplayL(TInt aPixels,TInt aHorizPixels=0,TInt aYScrollLimit=EFDrawAllWindow);
	void ScrollUpperDisplayL(TInt aPixels);
	TPoint ViewTopOfLineL(TInt aDocPos,TInt& aYPos
								,CTextView::TDiscard aDiscardFormat=EFViewDontDiscardFormat
								,TDoHorizontalScroll aHorizontalScroll=EFCheckForHorizontalScroll);
	TPoint ViewL(TInt aDocPos,TInt& aYPos,TViewYPosQualifier aYPosQualifier=TViewYPosQualifier()
								,CTextView::TDiscard aDiscardFormat=EFViewDontDiscardFormat
								,TDoHorizontalScroll aHorizontalScroll=EFCheckForHorizontalScroll);
	TPoint DoHandleGlobalChangeL(TViewYPosQualifier aYPosQualifier,CTextView::TDiscard aDiscard);
	void UpdateHighlightL();
	void InvertRangeCheckOrderL(TInt aPos1,TInt aPos2);
	void InvertRangeL(TInt aDocPos1,TInt aDocPos2);
	void InvertPictureFrameL(TInt aPos,TRect* aDrawRect=NULL);
	TBool TrapDocPosToXyPosL(TInt aCharNo,TPoint& aPos);
	void DestroyWindowServerObjects();
	void NoMemoryL(TInt aErr);
	void RecoverNoMemoryL();
	void RecreateWindowServerObjectsL();
	void DisplayLineRangeL(TInt aFrom,TInt aTo);
#if defined(TIMING_CODE)
public:
	TTestTimingCode* iTestTimingCode;
#endif
private:
	CIdle *iWrap;		//This is owned.
	RScreenDisplay iDisplay;
	CTextLayout *iLayout;
	TDrawTextLayoutContext iDrawTextLayoutContext;
	TCursor iCursor;
	TCursorPosition iCursorPos;
	TFrameOverlay* iPictureFrame;
	TMemoryStatus iNoMemory;
	TUint iSelectionVisible;
	TUint iHorizontalScroll;
	TInt iGood;			//Also used for y of cursor when in OOM condition
	TInt iFormattedUpTo;
	TInt iHorizontalScrollJump;
	TInt iHeightNotDrawn;
	CTextView(const CTextView& aRHS);
	CTextView& operator=(const CTextView& aRHS);		//Prevent copying one TextView to another
#if defined(TIMING_CODE)
public:
	inline void SetTimingFlags(TUint aFlags) 
			{iDisplay.SetTimingFlags(aFlags);iLayout->SetTimingFlags(aFlags);iTimingFlags=aFlags;}
	TUint iTimingFlags;
	inline void SetHandle(CWindowGc *aGc,RWsSession *aWs)
			{iDisplay.SetHandle(aGc,iWs);iLayout->SetHandle(aGc,iWs);iGc=aGc;iWs=aWs;}
	inline void SetCallBack(TCallBack aCallBack) {iLayout->SetCallBack(aCallBack);}
	CWindowGc *iGc;
	RWsSession *iWs;
#endif
	};

#include "frmtview.inl"

#endif
