// TWLDSL.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <eikenv.h>
#include <eikdialg.h>
#include <eikwsel.h>
#include <coecntrl.h>
#include <coecobs.h>
#include <basched.h>
#include <eikappui.h>
#include <e32keys.h>
#include <eikdef.h>
#include <eikhopbt.h>
#include <eikapp.h>
#include <eikdoc.h>
#include <TWLDSL.rsg>
#include "TWLDSL.hrh"
#include <eikwsel.hrh>
#include <eikdialg.hrh>
#include <t32wld.h>

const TInt KMaxNumComponents=8;
const TInt KTestSelectorWidth=15;
const TInt KFirstSelectorPair=0;
const TInt KLastSelectorPair=1;
const TInt KFirstSingleSelector=2;
const TInt KLastSingleSelector=3;
#define KBitmapFileName	_L("z:\\System\\Test\\sunrise.mbm")

//
// class CWorldSelectorPair
//

class CWorldSelectorPair : public CCoeControl , public MCoeControlObserver
	{
public:
	CWorldSelectorPair();
	~CWorldSelectorPair();
	void ConstructL(CCoeControl& aParent);
	virtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
	void FocusChanged(TDrawNow aDrawNow);
public:
	TWldSelect SearchExtent() const;
	void SetSearchExtentL(TWldSelect aSearchExtent);
	void SetFontL(const CFont* aFont);
	const CFont* Font() const;
	CEikWorldController* Controller();
private: // From MCoeControlObserver
	void HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType);
	void Draw(const TRect& aRect) const;
	TInt CountComponentControls() const;
	CCoeControl* ComponentControl(TInt aIndex) const;
private:
	void SizeChangedL();
	TSize MinimumSize();
	void CreateSelectorPairL();
private:
	TInt iNumberOfComponants;
	CCoeControl* iComponants[KMaxNumComponents];
	CCoeControl* iFocusControl;
	TEikBorder iBorder;
	};

CWorldSelectorPair::CWorldSelectorPair() : iBorder(TEikBorder::EDeepSunken)
	{
	__DECLARE_NAME(_S("CWorldSelectorPair"));
	}

CWorldSelectorPair::~CWorldSelectorPair()
	{
	for (TInt ii=0; ii<iNumberOfComponants; ii++)
		delete iComponants[ii];
	}

void CWorldSelectorPair::ConstructL(CCoeControl& aParent)
	{
	SetContainerWindowL(aParent);
	CreateSelectorPairL();
	iFocusControl=iComponants[0];
	TSize size=MinimumSize();
    SetSizeL(size);
	ActivateL();
	}

void CWorldSelectorPair::FocusChanged(TDrawNow aDrawNow)
	{
	if (IsFocused())
		iFocusControl->SetFocus(IsFocused(),aDrawNow);
	}

void CWorldSelectorPair::CreateSelectorPairL()
	{
	TBool hasBorder=EFalse;
	CEikWorldSelector* first=new(ELeave) CEikWorldSelector;
	iComponants[iNumberOfComponants]=first;
	iNumberOfComponants++;
	first->ConstructL(*this,hasBorder);
	first->SetObserver(this);
	CEikWorldSelector* second=new(ELeave) CEikWorldSelector;
	iComponants[iNumberOfComponants]=second;
	iNumberOfComponants++;
	second->ConstructSelectorPairL(*first);
	second->Controller()->SetSelectorWidthInCharacters(KTestSelectorWidth);
	second->SetObserver(this);
	second->SetSearchStateTextL(EWithinCountry,_L("(Locked)"));
	second->SetSearchStateTextL(EWithinWorld,_L("(Worldwide)"));
	}

TSize CWorldSelectorPair::MinimumSize()
	{
	TSize size;
	TSize borderSize=iBorder.SizeDelta();
	TSize firstSelSize=iComponants[0]->MinimumSize();
	TSize secondSelSize=iComponants[1]->MinimumSize();
	size.iHeight=borderSize.iHeight+firstSelSize.iHeight+secondSelSize.iHeight;
	size.iWidth=borderSize.iWidth+((firstSelSize.iWidth>secondSelSize.iWidth)?firstSelSize.iWidth:secondSelSize.iWidth);
	return size;
	}

TKeyResponse CWorldSelectorPair::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
//
// Respond to key presses
//
	{
	if ((iFocusControl==iComponants[0])&&(aKeyEvent.iCode==EKeyDownArrow))
		{
		HandleControlEventL(iComponants[1],MCoeControlObserver::EEventRequestFocus);
		return EKeyWasConsumed;
		}
	else if ((iFocusControl==iComponants[1])&&(aKeyEvent.iCode==EKeyUpArrow))
		{
		HandleControlEventL(iComponants[0],MCoeControlObserver::EEventRequestFocus);
		return EKeyWasConsumed;
		}
	iFocusControl->OfferKeyEventL(aKeyEvent,aType);
	return EKeyWasConsumed;
	}

void CWorldSelectorPair::Draw(const TRect& /*aRect*/) const
	{
	iBorder.Draw(SystemGc(),Rect());
	}

void CWorldSelectorPair::HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType)
    {
	if (aEventType!=EEventRequestFocus)
		return;
	TDrawNow drawState=IsFocused()?EDrawNow:ENoDrawNow;
	iFocusControl->SetFocus(EFalse,drawState);
	iFocusControl=aControl;
	iFocusControl->SetFocus(ETrue,drawState);
    }

void CWorldSelectorPair::SizeChangedL()
	{
	TRect rect=iBorder.InnerRect(Rect());
	TPoint pos=rect.iTl;
	TSize size=iComponants[0]->MinimumSize();
	iComponants[0]->SetExtentL(pos,size);
	pos.iY+=size.iHeight;
	size=iComponants[1]->MinimumSize();
	iComponants[1]->SetExtentL(pos,size);
	}


TInt CWorldSelectorPair::CountComponentControls() const
	{
	return iNumberOfComponants;
	}

CCoeControl* CWorldSelectorPair::ComponentControl(TInt aIndex) const
	{
	return(iComponants[aIndex]);
	}

TWldSelect CWorldSelectorPair::SearchExtent() const
	{
	return (((CEikWorldSelector*)iFocusControl)->Controller()->SearchExtent());
	}

void CWorldSelectorPair::SetSearchExtentL(TWldSelect aSearchExtent)
	{
	((CEikWorldSelector*)iFocusControl)->Controller()->SetSearchExtentL(aSearchExtent);
	}

void CWorldSelectorPair::SetFontL(const CFont* aFont)
	{
	((CEikWorldSelector*)iFocusControl)->Controller()->SetFontL(aFont);
	}

const CFont* CWorldSelectorPair::Font() const
	{
	return ((CEikWorldSelector*)iFocusControl)->Controller()->Font();
	}

CEikWorldController* CWorldSelectorPair::Controller()
	{
	return ((CEikWorldSelector*)iFocusControl)->Controller();
	}

class CSimpleControl : public CCoeControl , public MCoeControlObserver
    {
public:
	~CSimpleControl();
    void ConstructL(const TRect& aRect);
	void SetFocusedControl(CCoeControl* aControl);
	CEikWorldSelector* FocusedSelector();
	CWorldSelectorPair* FocusedSelectorPair();
	void SizeChangedL();
private: // framework
	void Draw(const TRect& aRect) const;
	TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
	TInt CountComponentControls() const;
	CCoeControl* ComponentControl(TInt aIndex) const;
	void FocusChanged(TDrawNow aDrawNow);
private: // From MCoeControlObserver
	void HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType);
private:
	void CreateSingleSelectorPairL();
	void CreateCompoundSelectorPairsL();
private:
	TInt iNumberOfComponents;
	CCoeControl* iComponents[KMaxNumComponents];
	CCoeControl* iFocusControl;
	CFbsBitmap* iBitmap;
    };


void CSimpleControl::FocusChanged(TDrawNow aDrawNow)
	{
	iFocusControl->SetFocus(IsFocused(),aDrawNow);
	}

	
CWorldSelectorPair* CSimpleControl::FocusedSelectorPair()
	{
	for (TInt ii=KFirstSelectorPair; ii<=KLastSelectorPair; ii++)
		{
		if (iComponents[ii]==iFocusControl)
			return ((CWorldSelectorPair*)(iFocusControl));
		}
	return NULL;
	}

CEikWorldSelector* CSimpleControl::FocusedSelector()
	{
	for (TInt ii=KFirstSingleSelector; ii<=KLastSingleSelector; ii++)
		{
		if (iComponents[ii]==iFocusControl)
			return ((CEikWorldSelector*)iFocusControl);
		}
	return NULL;
	}

CSimpleControl::~CSimpleControl()
	{
	delete iBitmap;
	for (TInt ii=0; ii<iNumberOfComponents; ii++)
		delete iComponents[ii];
	}

void CSimpleControl::ConstructL(const TRect& aRect)
    {
	iNumberOfComponents=0;
    CreateWindowL();
    Window().SetShadowDisabled(EFalse);
	EnableDragEvents();

	iBitmap=iEikonEnv->CreateBitmapL(KBitmapFileName,0);

	CreateCompoundSelectorPairsL();
	CreateSingleSelectorPairL();

	iFocusControl=iComponents[0];
	iFocusControl->SetFocus(ETrue);
	SetRectL(aRect);
    ActivateL();
    }

TInt CSimpleControl::CountComponentControls() const
	{
	return iNumberOfComponents;
	}

CCoeControl* CSimpleControl::ComponentControl(TInt aIndex) const
	{
	return(iComponents[aIndex]);
	}

void CSimpleControl::SetFocusedControl(CCoeControl* aControl)
	{
	iFocusControl = aControl;
	}

void CSimpleControl::Draw(const TRect& /*aRect*/) const
	{
	iEikonEnv->FillTexturedRect(Rect());
	CWindowGc& gc=SystemGc();
	TSize bitmapSize(iBitmap->SizeInPixels());
	TPoint bitmapTopLeft=TPoint(0,0);
	TRect visibleRect(bitmapTopLeft, bitmapSize);
	gc.BitBlt(iPosition, iBitmap, visibleRect);
	}

void CSimpleControl::SizeChangedL()
	{
	TInt deltaY=iSize.iHeight/10;
	TPoint pos(iSize.iWidth/10,deltaY);
	TSize size=iComponents[0]->MinimumSize();
	iComponents[0]->SetExtentL(pos,size);
	pos.iY+=(3*deltaY);
	size=iComponents[1]->MinimumSize();
	iComponents[1]->SetExtentL(pos,size);
	pos.iY+=(3*deltaY);
	size=iComponents[2]->MinimumSize();
	iComponents[2]->SetExtentL(pos,size);
	pos.iY+=(deltaY);
	size=iComponents[3]->MinimumSize();
	iComponents[3]->SetExtentL(pos,size);
	}

void CSimpleControl::CreateSingleSelectorPairL()
	{
	CEikWorldSelector* first=new(ELeave) CEikWorldSelector;
	iComponents[iNumberOfComponents]=first;
	iNumberOfComponents++;
	first->ConstructL(*this);
	first->SetObserver(this);
	CEikWorldSelector* second=new(ELeave) CEikWorldSelector;
	iComponents[iNumberOfComponents]=second;
	iNumberOfComponents++;
	second->ConstructSelectorPairL(*first);
	second->Controller()->SetSelectorWidthInCharacters(KTestSelectorWidth);
	second->Controller()->SetFontL(iEikonEnv->AnnotationFont());
	second->SetObserver(this);
	second->SetSearchStateTextL(EWithinCountry,_L("(Locked)"));
	second->SetSearchStateTextL(EWithinWorld,_L("(Worldwide)"));
	}

void CSimpleControl::CreateCompoundSelectorPairsL()
	{
	CWorldSelectorPair* homeSelector=new(ELeave) CWorldSelectorPair;
	iComponents[iNumberOfComponents]=homeSelector;
	iNumberOfComponents++;
	homeSelector->ConstructL(*this);
	homeSelector->SetObserver(this);
	CWorldSelectorPair* citySelector=new(ELeave) CWorldSelectorPair;
	iComponents[iNumberOfComponents]=citySelector;
	iNumberOfComponents++;
	citySelector->ConstructL(*this);
	citySelector->SetObserver(this);
	}

void CSimpleControl::HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType)
    {
	if (aEventType!=EEventRequestFocus)
		return;
	iFocusControl->SetFocus(EFalse,EDrawNow);
	iFocusControl=aControl;
	iFocusControl->SetFocus(ETrue,EDrawNow);
    }

TKeyResponse CSimpleControl::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
    {
	if (iFocusControl)
		iFocusControl->OfferKeyEventL(aKeyEvent, aType);
    return(EKeyWasConsumed);
    }


class CSimpleAppUi : public CEikAppUi
    {
public:
    void ConstructL();
	~CSimpleAppUi();
	CSimpleControl* Control();
private: // framework
    void HandleCommandL(TInt aCommand);
	void HandleCmdSelectorDialog();
private:
    CSimpleControl* iSimpleControl;
    };

class CEikSelectorDialog : public CEikDialog
	{
public:
	void PreLayoutDynInitL();
	void HandleControlStateChangeL(TInt aControlId);
	TBool OkToExitL(TInt aKeyCode);
	};

void CEikSelectorDialog::PreLayoutDynInitL()
	{
	((CEikHorOptionButtonList*)Control(EDlgSelSearchExtent))->SetButtonById(ESetWithinWorld);
	CSimpleAppUi* appUi=(CSimpleAppUi*)iEikonEnv->EikAppUi(); 
	SWorldSelectorState currentWorldState;
	if (appUi->Control()->FocusedSelector()!=NULL)
		appUi->Control()->FocusedSelector()->Controller()->GetState(currentWorldState);
	else if (appUi->Control()->FocusedSelectorPair()!=NULL)
		appUi->Control()->FocusedSelectorPair()->Controller()->GetState(currentWorldState);
	else
		return;
	((CEikWorldSelector*)Control(EDlgSelCity))->Controller()->SetStateL(currentWorldState);
	TInt id=(currentWorldState.iSearch==EWithinWorld)?ESetWithinWorld:ESetWithinCountry;
	((CEikHorOptionButtonList*)Control(EDlgSelSearchExtent))->SetButtonById(id);
	}


void CEikSelectorDialog::HandleControlStateChangeL(TInt aControlId)
	{
	if (aControlId==EDlgSelSearchExtent)
		{
		TInt id=((CEikHorOptionButtonList*)Control(aControlId))->LabeledButtonId();
		TWldSelect searchState=(id==ESetWithinCountry)?EWithinCountry:EWithinWorld;
		((CEikWorldSelector*)Control(EDlgSelCity))->Controller()->SetSearchExtentL(searchState);
		}
	}


TBool CEikSelectorDialog::OkToExitL(TInt aButtonId)
	{
	if (aButtonId==EEikBidOk)
		{
		SWorldSelectorState currentWorldState;
		(((CEikWorldSelector*)Control(EDlgSelCity))->Controller()->GetState(currentWorldState));
		TPtrC city=currentWorldState.iCity;
		TPtrC country=currentWorldState.iCountry;
		TBuf<80> buf=_L("City: ");
		buf.Append(city);
		buf.Append(_L(" Country: "));
		buf.Append(country);
		iEikonEnv->InfoMsg(buf);
		CSimpleAppUi* appUi=(CSimpleAppUi*)iEikonEnv->EikAppUi(); 
		if (appUi->Control()->FocusedSelector()!=NULL)
			appUi->Control()->FocusedSelector()->Controller()->SetStateL(currentWorldState);
		else if (appUi->Control()->FocusedSelectorPair()!=NULL)
			appUi->Control()->FocusedSelectorPair()->Controller()->SetStateL(currentWorldState);
		}
	return ETrue;
	}

//
// class CSimpleControl
//


//
// CSimpleAppUi
//

void CSimpleAppUi::ConstructL()
    {
	BaseConstructL();
	iSimpleControl=new(ELeave) CSimpleControl;
	//If test control is set to the whole screen 
	//it will cover the tool bar - hence ClientRect()
	iSimpleControl->ConstructL(ClientRect());
    AddToStackL(iSimpleControl);
    }

CSimpleAppUi::~CSimpleAppUi()
	{
    delete iSimpleControl;
	}

CSimpleControl* CSimpleAppUi::Control()
	{
	return iSimpleControl;
	}

void CSimpleAppUi::HandleCommandL(TInt aCommand)
    {
    switch (aCommand)
        {
   case ECmdExit:							
        CBaActiveScheduler::Exit();
        break;
    case ECmdSelectorDialog:
		HandleCmdSelectorDialog();
        break;
	case ECmdChangeFont:
		{
		if (iSimpleControl->FocusedSelector()!=NULL)
			{
			CFbsFont* font=(CFbsFont*)iEikonEnv->NormalFont();
			if (font==iSimpleControl->FocusedSelector()->Controller()->Font())
				font=(CFbsFont*)iEikonEnv->AnnotationFont();
			iSimpleControl->FocusedSelector()->Controller()->SetFontL(font);
			iSimpleControl->SizeChangedL();
			iSimpleControl->DrawNow();
			}
		else if (iSimpleControl->FocusedSelectorPair()!=NULL)
			{
			CFbsFont* font=(CFbsFont*)iEikonEnv->NormalFont();
			if (font==iSimpleControl->FocusedSelectorPair()->Font())
				font=(CFbsFont*)iEikonEnv->AnnotationFont();
			iSimpleControl->FocusedSelectorPair()->SetFontL(font);
			iSimpleControl->SizeChangedL();
			iSimpleControl->DrawNow();
			}
		}
		break;
	case ECmdChangeSearchExtent:
		{
		if (iSimpleControl->FocusedSelector()!=NULL)
			{
			TWldSelect searchExtent=EWithinCountry;
			if (iSimpleControl->FocusedSelector()->Controller()->SearchExtent()==EWithinCountry)
				searchExtent=EWithinWorld;
			iSimpleControl->FocusedSelector()->Controller()->SetSearchExtentL(searchExtent);
			}
		else if (iSimpleControl->FocusedSelectorPair()!=NULL)
			{
			TWldSelect searchExtent=EWithinCountry;
			if (iSimpleControl->FocusedSelectorPair()->SearchExtent()==EWithinCountry)
				searchExtent=EWithinWorld;
			iSimpleControl->FocusedSelectorPair()->SetSearchExtentL(searchExtent);
			}
		}
		break;
	default:
		break;
		}
    }

void CSimpleAppUi::HandleCmdSelectorDialog()
	{
	CEikDialog* dialog=new(ELeave) CEikSelectorDialog();
	dialog->ExecuteLD(R_TWLD_SELECTOR_DIALOG);
	}

//
// 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={231};

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);
	}
