// TMSG.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <e32keys.h>
#include <basched.h>
#include <coecntrl.h>
#include <eikdef.h>
#include <eikenv.h>
#include <eikappui.h>
#include <eikcmds.hrh>
#include <eikapp.h>
#include <eikdoc.h>
#include <eikmsg.h>
#include <tmsg.rsg>
#include "tmsg.hrh"

enum TTMsgPanic
	{
	ETMsgPanicBadCommand
	};

LOCAL_C void Panic(TTMsgPanic aPanic)
	{
	User::Panic(_L("TMsg"), aPanic);
	}

//
// CTstContainer
//

class CTstContainer : public CCoeControl
	{
public:
	CTstContainer();
	void ConstructL(const TRect& aRect);
	~CTstContainer();
	void HandleCommandL(TInt aCommand);
private:
	// framework
	virtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType);
	virtual void HandlePointerEventL(const TPointerEvent& aPointerEvent);
	virtual void Draw(const TRect& aRect) const;
private:
	enum
		{
		EBusyDuration=5*1000000
		};
private:
	CEikInfoMsgWin* iInfoMsgWin;
	CEikBusyMsgWin* iBusyMsgWin;
	CFont* iFont;
	TBuf<64> iText;
	TInt iCounter;
	};

CTstContainer::CTstContainer()
	{
	__DECLARE_NAME(_S("CTstContainer"));
	}

void CTstContainer::ConstructL(const TRect& aRect)
	{
	CreateWindowL();
	EnableDragEvents();
	Window().SetBackgroundColor(TRgb(170, 170, 170));
	iInfoMsgWin=new(ELeave) CEikInfoMsgWin(*iEikonEnv);
	iInfoMsgWin->ConstructL(iEikonEnv->RootWin());
	iBusyMsgWin=new(ELeave) CEikBusyMsgWin(*iEikonEnv);
	iBusyMsgWin->ConstructL(iEikonEnv->RootWin());
	CWsScreenDevice& screenDevice=*iCoeEnv->ScreenDevice();
	TFontSpec fontSpec(_L("Arial"), screenDevice.VerticalPixelsToTwips(20));
	User::LeaveIfError(screenDevice.GetNearestFontInTwips(iFont, fontSpec));
	iText=_L("Type or drag pointer to show event-handling");
	SetRectL(aRect);
	ActivateL();
	}

CTstContainer::~CTstContainer()
	{
	delete iInfoMsgWin;
	delete iBusyMsgWin;
	iCoeEnv->ScreenDevice()->ReleaseFont(iFont);
	}

void CTstContainer::HandleCommandL(TInt aCommand)
	{
	TBuf<128> buffer;
	switch (aCommand)
		{
	case ETMsgCmdDisplayInfoMsgAtBottom:
		buffer.Format(_L("Info-msg, bottom-right, %d"), iCounter);
		iInfoMsgWin->StartDisplay(buffer, EHRightVBottom);
		break;
	case ETMsgCmdDisplayInfoMsgAtTop:
		buffer.Format(_L("Info-msg, top-right, %d"), iCounter);
		iInfoMsgWin->StartDisplay(buffer, EHRightVTop);
		break;
	case ETMsgCmdCancelInfoMsg:
		iInfoMsgWin->CancelDisplay();
		break;
	case ETMsgCmdDisplaySingleBusyMsg:
		buffer.Format(_L("Single busy-msg, bottom-left, %d"), iCounter);
		iBusyMsgWin->StartDisplay(buffer, EHLeftVBottom);
		User::After(EBusyDuration);
		iBusyMsgWin->CancelDisplay();
		break;
	case ETMsgCmdDisplayTwoBusyMsgsInSameCorner:
		buffer.Format(_L("First of 2 busy-msgs, bottom-left, %d"), iCounter);
		iBusyMsgWin->StartDisplay(buffer, EHLeftVBottom);
		User::After(EBusyDuration);
		buffer.Format(_L("Second of 2 busy-msgs, bottom-left, %d"), iCounter);
		iBusyMsgWin->StartDisplay(buffer, EHLeftVBottom);
		User::After(EBusyDuration);
		iBusyMsgWin->CancelDisplay();
		break;
	case ETMsgCmdDisplayTwoBusyMsgsInDifferentCorners:
		buffer.Format(_L("First of 2 busy-msgs, bottom-left, %d"), iCounter);
		iBusyMsgWin->StartDisplay(buffer, EHLeftVBottom);
		User::After(EBusyDuration);
		buffer.Format(_L("Second of 2 busy-msgs, top-left, %d"), iCounter);
		iBusyMsgWin->StartDisplay(buffer, EHLeftVTop);
		User::After(EBusyDuration);
		iBusyMsgWin->CancelDisplay();
		break;
	case ETMsgCmdCancelBusyMsg:
		iBusyMsgWin->CancelDisplay();
		break;
	case EEikCmdExit:
		CBaActiveScheduler::Exit();
		break;
	default:
		Panic(ETMsgPanicBadCommand);
		break;
		}
	++iCounter;
	}

TKeyResponse CTstContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
	{
	iText.Format(_L("Key event: type %d, code %d"), aType, aKeyEvent.iCode);
	DrawNow();
	return EKeyWasConsumed;
	}

void CTstContainer::HandlePointerEventL(const TPointerEvent& aPointerEvent)
	{
	iText.Format(_L("Pointer event: type %d, position (%d, %d)"), aPointerEvent.iType, aPointerEvent.iPosition.iX, aPointerEvent.iPosition.iY);
	DrawNow();
	}

void CTstContainer::Draw(const TRect&) const
	{
	CWindowGc& gc=SystemGc();
	TRect rect=Rect();
	iEikonEnv->FillTexturedRect(rect);
	gc.SetBrushStyle(CGraphicsContext::ENullBrush);
	gc.UseFont(iFont);
	gc.DrawText(iText, rect, iSize.iHeight/2, CGraphicsContext::ECenter);
	}

//
// CTstAppUi
//

class CTstAppUi : public CEikAppUi
	{
public:
	void ConstructL();
	virtual ~CTstAppUi();
private: // framework
	virtual void HandleCommandL(TInt aCommand);
private:
	CTstContainer* iContainer;
	};

void CTstAppUi::ConstructL()
	{
	BaseConstructL();
	CreateHotKeyControlL(R_TMSG_HOTKEYS);
	iContainer=new(ELeave) CTstContainer;
	iContainer->ConstructL(ClientRect());
	AddToStackL(iContainer);
	}

CTstAppUi::~CTstAppUi()
	{
	delete iContainer;
	}

void CTstAppUi::HandleCommandL(TInt aCommand)
	{
	iContainer->HandleCommandL(aCommand);
	}

//
// CTstDocument
//

class CTstDocument : public CEikDocument
	{
public:
	CTstDocument(CEikApplication& aApp): CEikDocument(aApp) { }
private: // from CApaDocument
	CEikAppUi* CreateAppUiL();
	};

CEikAppUi* CTstDocument::CreateAppUiL()
	{
    return(new(ELeave) CTstAppUi);
	}

//
// CTstApplication
//

class CTstApplication : public CEikApplication
	{
private: // from CApaApplication
	CApaDocument* CreateDocumentL();
	TUid AppDllUid() const;
	};

const TUid KUidTstApp={237};

TUid CTstApplication::AppDllUid() const
	{
	return(KUidTstApp);
	}

CApaDocument* CTstApplication::CreateDocumentL()
	{
	return(new(ELeave) CTstDocument(*this));
	}

//
// EXPORTed functions
//

EXPORT_C CApaApplication* NewApplication()
	{
	return(new CTstApplication);
	}

GLDEF_C TInt E32Dll(TDllReason)
	{
	return(KErrNone);
	}
