// TCONS0.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <basched.h>
#include <eikenv.h>
#include <coecntrl.h>
#include <eikappui.h>
#include <e32keys.h>
#include <eikmenup.h>
#include <eikmenu.hrh>
#include <eikdef.h>
#include <eikconso.h>
#include <eikfontd.h>
#include <eikapp.h>
#include <eikdoc.h>
#include <eikon.rsg>

#include "tcons0.hrh"
#include <tcons0.rsg>

enum TMessageControlFontStyle
    {
    EStyleElementBold=EMenuCommandBold,
    EStyleElementItalic=EMenuCommandItalic,
    EStyleElementInverse=EMenuCommandInverse,
    EStyleElementUnderline=EMenuCommandUnderline,
    EStyleElementColor=EMenuCommandColor
    };

// 
// CSimpleConsole
//

class CConsoleControl : public CCoeControl
	{
public:
	CConsoleControl() {}
	~CConsoleControl();
	void ConstructL(TInt aFlags);
	void ConstructL(TPoint aLeftTop,const TSize& aSize,TInt aFlags);
    TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
    void HandlePointerEventL(const TPointerEvent& aPointerEvent);
	void DynInitMenuPaneL(TInt aMenuId,CEikMenuPane* aMenuPane);
    void HandleCommandL(TInt aCommand);
    void ActivateL();
protected:
    void FocusChanged(TDrawNow aDrawNow);
private:
    void ToggleFontStyleAndRedrawL(TMessageControlFontStyle aStyleElement);
private:
	CEikConsoleScreen* iConsole;
	TInt iAllPrintable,iScrollLock,iIgnoreCursor,iHideCursor;
	TDesC* iSelBufPtr;
	TInt iSmallScreen;
	TInt iHighCursor;
	};

CConsoleControl::~CConsoleControl()
	{
	delete iSelBufPtr; // forget selection
	delete iConsole;
	}

void CConsoleControl::ConstructL(TInt aFlags)
	{
    CreateWindowL();
    Window().SetShadowDisabled(ETrue);
    Window().SetBackgroundColor(KRgbGray);
    EnableDragEvents();
    SetExtentToWholeScreenL();
	SetBlank();
    iConsole=new(ELeave) CEikConsoleScreen;
	iConsole->ConstructL(_L("TEST"),aFlags);
	iConsole->SetHistorySizeL(10,10);
	}

void CConsoleControl::ConstructL(TPoint aTopLeft,const TSize& aSize,TInt aFlags)
	{
    CreateWindowL();
    Window().SetShadowDisabled(ETrue);
    Window().SetBackgroundColor(KRgbGray);
    EnableDragEvents();
    SetExtentToWholeScreenL();
	SetBlank();
    iConsole=new(ELeave) CEikConsoleScreen;
	iConsole->ConstructL(_L("TEST"),aTopLeft,aSize,aFlags,EEikConsWinInChars);
	iConsole->SetHistorySizeL(10,10);
	}

void CConsoleControl::ActivateL()
	{
	CCoeControl::ActivateL();
	iConsole->SetKeepCursorInSight(TRUE);

	TInt i;
	for(i=0;i<16;i++)
		{
		iConsole->SetAtt(15-i,i);
		iConsole->Write(_L("1234567890 The Quick Brown Fox Jumped Over The Lazy Dog\n"));
		}
	iConsole->Write(_L("\nPress F9 for Menu...\nUse arrows to move cursor,\nSHIFT-arrows to select...\n"));
	iConsole->FlushChars();
	iConsole->DrawCursor();
	iConsole->SetAtt(ATT_NORMAL);
	}

void CConsoleControl::DynInitMenuPaneL(TInt aMenuId,CEikMenuPane* aMenuPane)
	{
	if (aMenuId==R_CONS_OPTIONS_MENU)
		{
		if ( iConsole->Att() & ATT_COLORMASK )
			aMenuPane->SetItemButtonState(EMenuCommandColor,EEikMenuItemSymbolOn);
		else
			{
			if ( iConsole->Att() & ATT_BOLD )
				aMenuPane->SetItemButtonState(EMenuCommandBold,EEikMenuItemSymbolOn);
			if ( iConsole->Att() & ATT_INVERSE )
				aMenuPane->SetItemButtonState(EMenuCommandInverse,EEikMenuItemSymbolOn);
			if ( iConsole->Att() & ATT_ITALIC )
				aMenuPane->SetItemButtonState(EMenuCommandItalic,EEikMenuItemSymbolOn);
			if ( iConsole->Att() & ATT_UNDERLINE )
				aMenuPane->SetItemButtonState(EMenuCommandUnderline,EEikMenuItemSymbolOn);
			}
		}
	
	if (aMenuId==R_CONS_SPECIAL_MENU)
		{
		if (iHighCursor)
			aMenuPane->SetItemButtonState(EMenuCursorSize,EEikMenuItemSymbolOn);
		if (iSmallScreen)
			aMenuPane->SetItemButtonState(EMenuScreenSize,EEikMenuItemSymbolOn);
		}

	if (aMenuId==R_CONS_TOOLS_MENU)
		{
		if (iHideCursor)
			aMenuPane->SetItemButtonState(EMenuCommandHideCursor,EEikMenuItemSymbolOn);
		if (iIgnoreCursor)
			aMenuPane->SetItemButtonState(EMenuCommandIgnoreCursor,EEikMenuItemSymbolOn);
		if (iScrollLock)
			aMenuPane->SetItemButtonState(EMenuCommandScrollLock,EEikMenuItemSymbolOn);
		if (iAllPrintable)
			aMenuPane->SetItemButtonState(EMenuCommandPrintable,EEikMenuItemSymbolOn);
		}

	}

void CConsoleControl::HandleCommandL(TInt aCommand)
    {
    switch (aCommand)
        {
    
	case EMenuCommandFileExit:
		CBaActiveScheduler::Exit();

	case EMenuCommandEditCopy			:
		{
		TRect range = iConsole->Selection();	// get current selected range		
		if (iSelBufPtr) delete iSelBufPtr;		// forget previous selection
		iSelBufPtr = iConsole->RetrieveL(range);
		if (iSelBufPtr)
			{
			TBuf<32> msg;
			msg.Format(_L("%d bytes copied"),iSelBufPtr->Length());
			iEikonEnv->InfoMsg(msg);
			}
		else 
			iEikonEnv->InfoMsg(_L("Nothing to copy..."));
		}
		break;
	case EMenuCommandEditPaste			:
		iConsole->SelectCursor(); // forget current selection...
		if (iSelBufPtr)
			{
			iConsole->Write(*iSelBufPtr);
			iConsole->FlushChars();
			TBuf<32> msg;
			msg.Format(_L("%d bytes pasted"),iSelBufPtr->Length());
			iEikonEnv->InfoMsg(msg);
			}
		else
			{
			iEikonEnv->InfoMsg(_L("Nothing to paste..."));
			}
		break;
		
	case EMenuCommandBold:
    case EMenuCommandItalic:
    case EMenuCommandUnderline:
	case EMenuCommandInverse:
    case EMenuCommandColor:
        ToggleFontStyleAndRedrawL((TMessageControlFontStyle)aCommand);
        break;

	case EMenuScreenSize:
		{
		iSmallScreen = !iSmallScreen;
		if (iSmallScreen)
			iConsole->ConsoleControl()->SetExtentL( TPoint(40,20), TSize(560,200) );
		else
			iConsole->ConsoleControl()->SetExtentL( TPoint(0,0), TSize(640,240) );
		}
		break;
	case EMenuCursorSize:
		{
		iHighCursor = !iHighCursor;
		if (iHighCursor)
			iConsole->SetCursorHeight(100);
		else
			iConsole->SetCursorHeight(20);
		}
		break;

	case EMenuFontDialog:
		{
		TCharFormat charFormat;
		charFormat.iFontSpec = iConsole->Font();
		TCharFormatMask dummy;
		CEikFontDialog* dialog=new(ELeave) CEikFontDialog(charFormat,dummy);
		if (dialog->ExecuteLD(R_EIK_DIALOG_FONT))
			{
			charFormat.iFontSpec.iTypeface.SetIsProportional(EFalse);
			iConsole->SetFontL(charFormat.iFontSpec);
			}
		}
        break;

	case EMenuCommandHideCursor:
		iHideCursor=!iHideCursor;
		if (iHideCursor)
			iConsole->HideCursor();
		else
			iConsole->DrawCursor();
		break;
    case EMenuCommandIgnoreCursor:
		iConsole->SetKeepCursorInSight(iIgnoreCursor);
		iIgnoreCursor=!iIgnoreCursor;
		break;
    case EMenuCommandScrollLock:
		iScrollLock=!iScrollLock;
		iConsole->SetScrollLock(iScrollLock);
		break;
    case EMenuCommandPrintable:
		iAllPrintable=!iAllPrintable;
		iConsole->SetAllPrintable(iAllPrintable);
		break;
		

    case EMenuScrollNone:
		iConsole->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff,CEikScrollBarFrame::EOff);
        break;
    case EMenuScrollHor:
		iConsole->SetScrollBarVisibilityL(CEikScrollBarFrame::EAuto,CEikScrollBarFrame::EOff);
        break;
    case EMenuScrollVert:
		iConsole->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff,CEikScrollBarFrame::EAuto);
        break;
   	case EMenuScrollBoth:
		iConsole->SetScrollBarVisibilityL(CEikScrollBarFrame::EAuto,CEikScrollBarFrame::EAuto);
        break;

	case EMenuCommandLongLine			:
		TBuf<256> str;
		for (TInt i=0; i<9; i++)
			{
			TBuf<32> tmp;
			tmp.Format(_L("%d abcdefghijklmnopqrstuvwxyz"),i);
			str+=tmp;
			}
		iConsole->Write(str);
		iConsole->FlushChars();
        break;
		}
    }

void CConsoleControl::FocusChanged(TDrawNow aDrawNow)
	{
	iConsole->ConsoleControl()->SetFocus(IsFocused(), aDrawNow); 
	}

void CConsoleControl::ToggleFontStyleAndRedrawL(TMessageControlFontStyle aStyleElement)
    {
    switch (aStyleElement)
        {
    case EStyleElementColor:
		if ( iConsole->Att() & ATT_COLORMASK )	// color?
			iConsole->SetAtt(ATT_NORMAL);	// then set normal
		else								// else
			iConsole->SetAtt(4,11);			// set 4 (darkgray) on 11 (lightgray)
        break;
    case EStyleElementBold:
		// clear color flag (just to be sure) and switch bold flag
		iConsole->SetAtt( (iConsole->Att()&(~ATT_COLORMASK)) ^ ATT_BOLD );
        break;
    case EStyleElementItalic:
		// clear color flag (just to be sure) and switch italic flag
		iConsole->SetAtt( (iConsole->Att()&(~ATT_COLORMASK)) ^ ATT_ITALIC );
        break;
    case EStyleElementInverse:
		// clear color flag (just to be sure) and switch inverse flag
		iConsole->SetAtt( (iConsole->Att()&(~ATT_COLORMASK)) ^ ATT_INVERSE );
        break;
    case EStyleElementUnderline:
		// clear color flag (just to be sure) and switch underline flag
		iConsole->SetAtt( (iConsole->Att()&(~ATT_COLORMASK)) ^ ATT_UNDERLINE );
        break;
        }
    }

void CConsoleControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
    {
	TBuf<128> iMessage;
    iEikonEnv->Format128(iMessage,R_CONS_POINTER_EVENT,aPointerEvent.iType,aPointerEvent.iPosition.iX,aPointerEvent.iPosition.iY);
	iConsole->Write(iMessage);
	iConsole->FlushChars();
    }

TKeyResponse CConsoleControl::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
    {
	if (aType!=EEventKey)
		return(EKeyWasConsumed);
    TInt modifiers=aKeyEvent.iModifiers;
    TInt code=aKeyEvent.iCode;
    if (code==CTRL('e'))
        CBaActiveScheduler::Exit();


	TRect range = iConsole->Selection(); // get current selected range
	switch (code)
		{
		case EKeyUpArrow:
			iConsole->Up();
			if (modifiers & EModifierShift)
				{
				range.iTl = iConsole->CursorPos();
				iConsole->SetSelection(range); 
				}
			else
				iConsole->SelectCursor(); 
			break;
		case EKeyDownArrow:
			iConsole->Down();
			if (modifiers & EModifierShift)
				{
				range.iTl = iConsole->CursorPos();
				iConsole->SetSelection(range); 
				}
			else
				iConsole->SelectCursor(); 
			break;
		case EKeyLeftArrow:
			iConsole->Left();
			if (modifiers & EModifierShift)
				{
				range.iTl = iConsole->CursorPos();
				iConsole->SetSelection(range); 
				}
			else
				iConsole->SelectCursor(); 
			break;
		case EKeyRightArrow:
			iConsole->Right();
			if (modifiers & EModifierShift)
				{
				range.iTl = iConsole->CursorPos();
				iConsole->SetSelection(range); 
				}
			else
				iConsole->SelectCursor(); 
			break;
		case EKeyEnter: 
			if (!iAllPrintable)
				{
				iConsole->Cr();
				iConsole->Lf();
				}
			break;
		default:
			{
			iConsole->SelectCursor();	// forget previous selection
			TBuf<1> chr;
			chr.Format(_L("%c"),code);
			iConsole->Write(chr);
			iConsole->FlushChars();
			}
			break;
		}
    return(EKeyWasConsumed);
    }

//
// CSimpleAppUi
//

class CSimpleAppUi : public CEikAppUi
    {
public:
    void ConstructL();
	void CreateConsoleL(TInt aFlags);
	~CSimpleAppUi();
private: // framework
    void HandleCommandL(TInt aCommand);
	void DynInitMenuPaneL(TInt aMenuId,CEikMenuPane* aMenuPane);
private:
	CConsoleControl* iConsole;
 	TInt iBackedUp;
	};

void CSimpleAppUi::ConstructL()
    {
    BaseConstructL();
	CreateConsoleL(CEikConsoleScreen::ENoInitialCursor);
    }

void CSimpleAppUi::CreateConsoleL(TInt aFlags)
	{
	TBuf<30> msg;
	if (iBackedUp)
		msg=_L("Using a backed up window");
	else
		msg=_L("Using a normal window");
	iEikonEnv->InfoMsg(msg);
	iConsole=new(ELeave) CConsoleControl;
	iConsole->ConstructL(aFlags);
//	iConsole->ConstructL(TPoint(4,4),TSize(60,16),aFlags);
    AddToStackL(iConsole);
	iConsole->ActivateL();
	}

CSimpleAppUi::~CSimpleAppUi()
	{
    delete(iConsole);
	}

void CSimpleAppUi::DynInitMenuPaneL(TInt aMenuId,CEikMenuPane* aMenuPane)
	{
	if (aMenuId==R_CONS_SPECIAL_MENU)
		{
		if (iBackedUp)
			aMenuPane->SetItemButtonState(EMenuWindowType,EEikMenuItemSymbolOn);
		}
	iConsole->DynInitMenuPaneL(aMenuId, aMenuPane);
    }

void CSimpleAppUi::HandleCommandL(TInt aCommand)
	{
	switch (aCommand)
		{
	case EMenuWindowType:
		{
		iBackedUp = !iBackedUp;
		RemoveFromStack(iConsole);
		delete iConsole;
		TInt flags=0;
		if (iBackedUp)
			flags|=CEikConsoleScreen::EUseBackedUpWindow;
		CreateConsoleL(flags);
		}
		break;
	default:
		iConsole->HandleCommandL(aCommand);
		}
	}

//
// CSimpleDocument
//

class CSimpleDocument : public CEikDocument
	{
public:
	CSimpleDocument(CEikApplication& aApp): CEikDocument(aApp) { }
private: // from CApaDocument
	CEikAppUi* CreateAppUiL();
	};

CEikAppUi* CSimpleDocument::CreateAppUiL()
	{
    return(new(ELeave) CSimpleAppUi);
	}

//
// CSimpleApplication
//

class CSimpleApplication : public CEikApplication
	{
private: // from CApaApplication
	CApaDocument* CreateDocumentL();
	TUid AppDllUid() const;
	};

const TUid KUidSimpleApp={227};

TUid CSimpleApplication::AppDllUid() const
	{
	return(KUidSimpleApp);
	}

CApaDocument* CSimpleApplication::CreateDocumentL()
	{
	return(new(ELeave) CSimpleDocument(*this));
	}

//
// EXPORTed functions
//

EXPORT_C CApaApplication* NewApplication()
	{
	return(new CSimpleApplication);
	}

GLDEF_C TInt E32Dll(TDllReason)
	{
	return(KErrNone);
	}
