// TPRGI.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <eikenv.h>
#include <coecntrl.h>
#include <eikappui.h>
#include <basched.h>
#include <e32keys.h>
#include <eikdef.h>
#include <eikprogi.h>
#include <eikbutb.h>
#include <eikdialg.h>
#include <eikmenup.h>
#include <eikmenu.hrh>
#include <eikdialg.hrh>
#include <eiktbar.h>
#include <eikdoc.h>
#include <eikapp.h>
#include <eikapp.h>
#include <eikdoc.h>
#include <s32std.h>

#include <eikcmds.hrh>
#include "tprgi.hrh"
#include <tprgi.rsg>

const TUid KUidTPrgiApp={225};

struct TTimerModel
	{
	TInt iHundredths;
	TInt iIncrement;
	TBool iRunning;
	TInt iWhichBars;
public:
	void ExternalizeL(RWriteStream& aStream) const;
	void InternalizeL(RReadStream& aStream);
	};

void TTimerModel::ExternalizeL(RWriteStream& aStream) const
	{
	aStream.WriteInt8L(iHundredths);
	aStream.WriteInt8L(iIncrement);
	aStream.WriteInt8L(iRunning);
	aStream.WriteInt8L(iWhichBars);
	}

void TTimerModel::InternalizeL(RReadStream& aStream)
	{
	iHundredths=aStream.ReadInt8L();
	iIncrement=aStream.ReadInt8L();
	iRunning=aStream.ReadInt8L();
	iWhichBars=aStream.ReadInt8L();
	}

enum TBorderType
	{
	EBorderSingle,
	EBorderShallowRaised,
	EBorderDeepRaised,
	EBorderOutlinedRaised,
	EBorderShallowSunken,
	EBorderDeepSunken,
	EBorderNone
	};
	
struct TBarModel
	{
	CEikProgressInfo::SInfo iInfo;
	CEikProgressInfo::SLayout iLayout;
	TBorderType iBorder;
	TBool iChanged;
public:
	void ExternalizeL(RWriteStream& aStream) const;
	void InternalizeL(RReadStream& aStream);
	};

void TBarModel::ExternalizeL(RWriteStream& aStream) const
	{
	aStream.WriteInt8L(iInfo.iTextType);
	aStream.WriteInt8L(iInfo.iSplitsInBlock);
	aStream.WriteInt16L(iInfo.iFinalValue);
	aStream.WriteInt16L(iInfo.iWidth);
	aStream.WriteInt16L(iInfo.iHeight);
	aStream<<iLayout.iFillColor;
	aStream<<iLayout.iEmptyColor;
	aStream<<iLayout.iFillTextColor;
	aStream<<iLayout.iEmptyTextColor;
	aStream.WriteInt8L(iLayout.iGapBetweenBlocks);
	aStream.WriteInt8L(iBorder);
	}

void TBarModel::InternalizeL(RReadStream& aStream)
	{
	iInfo.iTextType=(TEikProgressTextType)aStream.ReadInt8L();
	iInfo.iSplitsInBlock=aStream.ReadInt8L();
	iInfo.iFinalValue=aStream.ReadInt16L();
	iInfo.iWidth=aStream.ReadInt16L();
	iInfo.iHeight=aStream.ReadInt16L();
	aStream>>iLayout.iFillColor;
	aStream>>iLayout.iEmptyColor;
	aStream>>iLayout.iFillTextColor;
	aStream>>iLayout.iEmptyTextColor;
	iLayout.iGapBetweenBlocks=aStream.ReadInt8L();
	iBorder=(TBorderType)aStream.ReadInt8L();
	}

//
// class CTestContainer - definition
//

class CTestContainer : public CCoeControl
    {
public:
    void ConstructL(const TRect& aRect);
    ~CTestContainer();
	void IncrementBarsAndDraw(TInt aIncrement,TInt aMask=0xff);
	inline TRgb BackgroundColor() const { return(iBackground); }
	void SetBackgroundColor(TRgb aBackground);
	void ResetAllValues();
	void GetBarModels(TBarModel* aModel) const;
	void SetBarModelsL(TBarModel* aModel);
private: // framework
    void Draw(const TRect& aRect) const;
    TInt CountComponentControls() const;
    CCoeControl* ComponentControl(TInt aIndex) const;
private: // new functions
    void CreateProgressBarsL();
private:
    CEikProgressInfo* iPBar[KNumberOfBars];
	TBorderType iBorder[KNumberOfBars];
	TRgb iBackground;
    };

//
// class CTimerDialog
//

class CTimerDialog : public CEikDialog
	{
public:
	CTimerDialog(TTimerModel* aModel);
private: // framework
	void PreLayoutDynInitL();
	TBool OkToExitL(TInt aButtonId);
private:
	TTimerModel* iModel;
	};

CTimerDialog::CTimerDialog(TTimerModel* aModel)
	{
	iModel=aModel;
	}

void CTimerDialog::PreLayoutDynInitL()
	{
	SetNumberEditorValue(ETPrgiTimerDlgHundredths,iModel->iHundredths);
	SetNumberEditorValue(ETPrgiTimerDlgIncrement,iModel->iIncrement);
	TInt commandId=ETPrgiTimerDlgActOn1;
	TInt mask=0x01;
	TInt whichBars=iModel->iWhichBars;
	while (commandId<ETPrgiTimerDlgActOn1+KNumberOfBars)
		{
		if (whichBars&mask)
			SetCheckBoxState(commandId,CEikButtonBase::ESet);
		commandId++;
		mask<<=1;
		}
	}

TBool CTimerDialog::OkToExitL(TInt /*aButtonId*/)
	{
	iModel->iHundredths=NumberEditorValue(ETPrgiTimerDlgHundredths);
	iModel->iIncrement=NumberEditorValue(ETPrgiTimerDlgIncrement);
	TInt whichBars=0;
	TInt mask=0x01;
	TInt commandId=ETPrgiTimerDlgActOn1;
	while (commandId<ETPrgiTimerDlgActOn1+KNumberOfBars)
		{
		if (CheckBoxState(commandId))
			whichBars|=mask;
		commandId++;
		mask<<=1;
		}
	iModel->iWhichBars=whichBars;
	return(ETrue);
	}

//
// class CPrgiTimer
//

class CPrgiTimer : public CTimer
	{
public:
	CPrgiTimer();
	void ConstructL(TTimerModel* aModel,CTestContainer *aContainer);
	void AdjustRunningState();
private: // internal use
	void Queue();
private: // from CActive
	void RunL();
private:
	TTimerModel* iModel;
	CTestContainer* iContainer;
	};

CPrgiTimer::CPrgiTimer() : CTimer(EActivePriorityClockTimer)
	{
	}

void CPrgiTimer::ConstructL(TTimerModel* aModel,CTestContainer *aContainer)
	{
    CTimer::ConstructL();
	CActiveScheduler::Add(this);
	iModel=aModel;
	iContainer=aContainer;
	if (iModel->iRunning)
		Queue();
	}

void CPrgiTimer::AdjustRunningState()
	{
	TBool running=iModel->iRunning;
	if (running)
		Queue();
	else
		Cancel();
	}

void CPrgiTimer::RunL()
	{
	iContainer->IncrementBarsAndDraw(iModel->iIncrement,iModel->iWhichBars);
	Queue();
	}

void CPrgiTimer::Queue()
	{
	After(10000 * iModel->iHundredths);
	}

//
// class CColorDialog
//

class CColorDialog : public CEikDialog
	{
public:
	CColorDialog(TRgb* aColor,TBarModel* aModel);
private: // framework
	void PreLayoutDynInitL();
	void HandleControlStateChangeL(TInt aControlId);
	TBool OkToExitL(TInt aButtonId);
private: // internal
	void SetBarValues();
	void GetBarValues();
private:
	TRgb* iColor;
	TBarModel* iModel;
	TBarModel* iCurrentModel;
	TBool iChangePending;
	};

CColorDialog::CColorDialog(TRgb* aColor,TBarModel* aModel)
	{
	iColor=aColor;
	iModel=aModel;
	}

void CColorDialog::PreLayoutDynInitL()
	{
	SetGraySelectorColor(ETPrgiColorDlgBackground,*iColor);
	SetBarValues();
	}

void CColorDialog::SetBarValues()
	{
	TInt bar=ChoiceListCurrentItem(ETPrgiColorDlgBarNumber);
	iCurrentModel=iModel+bar;
	TInt index=ETPrgiColorDlgFill;
	TRgb* color=(&iCurrentModel->iLayout.iFillColor);
	while (index<=ETPrgiColorDlgEmptyText)
		SetGraySelectorColor(index++,*color++);
	}

void CColorDialog::GetBarValues()
	{
	if (!iChangePending)
		return;
	TInt index=ETPrgiColorDlgFill;
	TRgb* color=(&iCurrentModel->iLayout.iFillColor);
	while (index<=ETPrgiColorDlgEmptyText)
		*color++=GraySelectorColor(index++);
	iCurrentModel->iChanged=ETrue;
	iChangePending=EFalse;
	}

void CColorDialog::HandleControlStateChangeL(TInt aControlId)
	{
	switch (aControlId)
		{
	case ETPrgiColorDlgBackground:
		return;
	default:
		iChangePending=ETrue;
		return;
	case ETPrgiColorDlgBarNumber:
		GetBarValues();
		SetBarValues();
		}
	}

TBool CColorDialog::OkToExitL(TInt /*aButtonId*/)
	{
	*iColor=GraySelectorColor(ETPrgiColorDlgBackground);
	GetBarValues();
	return(ETrue);
	}

//
// class CSizesDialog
//

class CSizesDialog : public CEikDialog
	{
public:
	CSizesDialog(TBarModel* aModel);
private: // framework
	void PreLayoutDynInitL();
	void HandleControlStateChangeL(TInt aControlId);
	TBool OkToExitL(TInt aButtonId);
private: // internal
	void FindIfHeightsAreDefaults();
	void SetHeightsForDefaults();
	void SetBarValues();
	void GetBarValues();
	TInt FontIndex(const CFont* aFont) const;
	const CFont* FontFromIndex(TInt aFontIndex) const;
	static TInt DefaultHeight(const CFont* aFont);
private:
	TBarModel* iModel;
	TBarModel* iCurrentModel;
	TBool iUseDefaultHeight[KNumberOfBars];
	TBool* iCurrentUseDefaultHeight;
	};

CSizesDialog::CSizesDialog(TBarModel* aModel)
	{
	iModel=aModel;
	}

void CSizesDialog::PreLayoutDynInitL()
	{
	FindIfHeightsAreDefaults();
	SetBarValues();
	}

TInt CSizesDialog::DefaultHeight(const CFont* aFont)
	{ // static
	return(aFont->HeightInPixels()+1);
	}

TInt CSizesDialog::FontIndex(const CFont* aFont) const
	{
	if (aFont==iEikonEnv->NormalFont())
		return(0);
	if (aFont==iEikonEnv->TitleFont())
		return(1);
	if (aFont==iEikonEnv->LegendFont())
		return(2);
	return(3);
	}

const CFont* CSizesDialog::FontFromIndex(TInt aFontIndex) const
	{
	switch (aFontIndex)
		{
	case 0:
		return(iEikonEnv->NormalFont());
	case 1:
		return(iEikonEnv->TitleFont());
	case 2:
		return(iEikonEnv->LegendFont());
		}
	return(iEikonEnv->AnnotationFont());
	}

void CSizesDialog::FindIfHeightsAreDefaults()
	{
	TBarModel* model=iModel;
	TBool* useDefaultHeight=(&iUseDefaultHeight[0]);
	for (TInt ii=0; ii<KNumberOfBars; ii++, model++, useDefaultHeight++)
		*useDefaultHeight=(model->iInfo.iHeight==DefaultHeight(model->iLayout.iFont));
	}

void CSizesDialog::SetHeightsForDefaults()
	{
	TBarModel* model=iModel;
	TBool* useDefaultHeight=(&iUseDefaultHeight[0]);
	for (TInt ii=0; ii<KNumberOfBars; ii++, model++, useDefaultHeight++)
		{
		if (*useDefaultHeight)
			model->iInfo.iHeight=0;
		}
	}

void CSizesDialog::SetBarValues()
	{
	TInt bar=ChoiceListCurrentItem(ETPrgiSizesDlgBarNumber);
	iCurrentModel=iModel+bar;
	iCurrentUseDefaultHeight=(&iUseDefaultHeight[bar]);
	SetChoiceListCurrentItem(ETPrgiSizesDlgFont,FontIndex(iCurrentModel->iLayout.iFont));
	TBool useDefaultHeight=(*iCurrentUseDefaultHeight);
	SetCheckBoxState(ETPrgiSizesDlgDefHeight,useDefaultHeight? CEikButtonBase::ESet: CEikButtonBase::EClear);
	MakeLineVisible(ETPrgiSizesDlgHeight,!useDefaultHeight);
	SetNumberEditorValue(ETPrgiSizesDlgHeight,iCurrentModel->iInfo.iHeight);
	SetNumberEditorValue(ETPrgiSizesDlgWidth,iCurrentModel->iInfo.iWidth);
	SetNumberEditorValue(ETPrgiSizesDlgFinal,iCurrentModel->iInfo.iFinalValue);
	}

void CSizesDialog::GetBarValues()
	{
	iCurrentModel->iLayout.iFont=FontFromIndex(ChoiceListCurrentItem(ETPrgiSizesDlgFont));
	iCurrentModel->iInfo.iFinalValue=NumberEditorValue(ETPrgiSizesDlgFinal);
	iCurrentModel->iInfo.iWidth=NumberEditorValue(ETPrgiSizesDlgWidth);
	iCurrentModel->iInfo.iHeight=NumberEditorValue(ETPrgiSizesDlgHeight);
	*iCurrentUseDefaultHeight=CheckBoxState(ETPrgiSizesDlgDefHeight);
	iCurrentModel->iChanged=ETrue;
	}

void CSizesDialog::HandleControlStateChangeL(TInt aControlId)
	{
	switch (aControlId)
		{
	default:
		break;
	case ETPrgiSizesDlgBarNumber:
		GetBarValues();
		SetBarValues();
		break;
	case ETPrgiSizesDlgDefHeight:
		TBool defaultHeight=(CheckBoxState(ETPrgiSizesDlgDefHeight));
		MakeLineVisible(ETPrgiSizesDlgHeight,!defaultHeight);
		}
	}

TBool CSizesDialog::OkToExitL(TInt /*aButtonId*/)
	{
	GetBarValues();
	SetHeightsForDefaults();
	return(ETrue);
	}

//
// class CPresentationDialog
//

class CPresentationDialog : public CEikDialog
	{
public:
	CPresentationDialog(TBarModel* aModel);
private: // framework
	void PreLayoutDynInitL();
	void HandleControlStateChangeL(TInt aControlId);
	TBool OkToExitL(TInt aButtonId);
private: // internal
	void SetBarValues();
	void GetBarValues();
private:
	TBarModel* iModel;
	TBarModel* iCurrentModel;
	};

CPresentationDialog::CPresentationDialog(TBarModel* aModel)
	{
	iModel=aModel;
	}

void CPresentationDialog::PreLayoutDynInitL()
	{
	SetBarValues();
	}

void CPresentationDialog::SetBarValues()
	{
	TInt bar=ChoiceListCurrentItem(ETPrgiPresDlgBarNumber);
	iCurrentModel=iModel+bar;
	SetNumberEditorValue(ETPrgiPresDlgNumBlocks,iCurrentModel->iInfo.iSplitsInBlock);
	SetNumberEditorValue(ETPrgiPresDlgBlockGap,iCurrentModel->iLayout.iGapBetweenBlocks);
	SetChoiceListCurrentItem(ETPrgiPresDlgBorderType,iCurrentModel->iBorder);
	SetChoiceListCurrentItem(ETPrgiPresDlgTextType,iCurrentModel->iInfo.iTextType);
	}

void CPresentationDialog::GetBarValues()
	{
	iCurrentModel->iInfo.iSplitsInBlock=NumberEditorValue(ETPrgiPresDlgNumBlocks);
	iCurrentModel->iLayout.iGapBetweenBlocks=NumberEditorValue(ETPrgiPresDlgBlockGap);
	iCurrentModel->iBorder=(TBorderType)ChoiceListCurrentItem(ETPrgiPresDlgBorderType);
	iCurrentModel->iInfo.iTextType=(TEikProgressTextType)ChoiceListCurrentItem(ETPrgiPresDlgTextType);
	iCurrentModel->iChanged=ETrue;
	}

void CPresentationDialog::HandleControlStateChangeL(TInt aControlId)
	{
	if (aControlId!=ETPrgiPresDlgBarNumber)
		return;
	GetBarValues();
	SetBarValues();
	}

TBool CPresentationDialog::OkToExitL(TInt /*aButtonId*/)
	{
	GetBarValues();
	return(ETrue);
	}

//
// class CTestContainer - implementation
//

void CTestContainer::GetBarModels(TBarModel* aModel) const
	{
	TInt ii=0;
	while (ii<KNumberOfBars)
		{
		CEikProgressInfo* bar=iPBar[ii];
		aModel->iBorder=iBorder[ii++];
		aModel->iInfo=bar->Info();
		aModel->iLayout=bar->Layout();
		aModel->iChanged=EFalse;
		aModel++;
		}
	}

void CTestContainer::SetBarModelsL(TBarModel* aModel)
	{
	for (TInt ii=0; ii<KNumberOfBars; ii++, aModel++)
		{
		if (!aModel->iChanged)
			continue;
		const CEikProgressInfo* oldBar=iPBar[ii];
		const TInt currentValue=oldBar->CurrentValue();
		const TPoint pos=oldBar->Position();
		const TSize size=oldBar->Size();
		CEikProgressInfo* newBar=new(ELeave) CEikProgressInfo(aModel->iInfo);
		delete iPBar[ii];
		iPBar[ii]=newBar; // none of following can actually fail
		iBorder[ii]=aModel->iBorder;
		TEikBorder::TBorderType borderType=TEikBorder::ENone;
		switch (aModel->iBorder)
			{
		case EBorderNone:
			break;
		case EBorderSingle:
			borderType=TEikBorder::ESingleBlack;
			break;
		case EBorderShallowRaised:
			borderType=TEikBorder::EShallowRaised;
			break;
		case EBorderDeepRaised:
			borderType=TEikBorder::EDeepRaised;
			break;
		case EBorderOutlinedRaised:
			borderType=TEikBorder::EDeepRaisedWithOutline;
			break;
		case EBorderShallowSunken:
			borderType=TEikBorder::EShallowSunken;
			break;
		case EBorderDeepSunken:
			borderType=TEikBorder::EDeepSunken;
			break;
			}
		newBar->SetBorder(borderType);
		newBar->SetLayout(aModel->iLayout);
		newBar->SetContainerWindowL(*this);
		newBar->SetPosition(pos);
		newBar->ActivateL();
		newBar->SetAndDraw(currentValue);
		const TSize newSize=newBar->Size();
		if (newSize.iWidth<size.iWidth || newSize.iHeight<size.iHeight)
			DrawDeferred();
		}
	}

void CTestContainer::SetBackgroundColor(TRgb aBackground)
	{
	if (aBackground!=iBackground)
		{
		iBackground=aBackground;
		Window().SetBackgroundColor(aBackground);
		DrawDeferred();
		}
	}
	
void CTestContainer::ConstructL(const TRect& aRect)
    {
    CreateWindowL();
    Window().SetShadowDisabled(ETrue);
    CreateProgressBarsL();
	SetBackgroundColor(KRgbGray);
    SetRectL(aRect);
    ActivateL();
    }

CTestContainer::~CTestContainer()
    {
    for (TInt ii=0; ii<KNumberOfBars; ii++)
        delete(iPBar[ii]);
    }

void CTestContainer::CreateProgressBarsL()
    {
	CEikProgressInfo::SInfo info;
	info.iHeight=0;
	info.iWidth=200;
	info.iFinalValue=240;
	info.iSplitsInBlock=12; 
	info.iTextType=EEikProgressTextNone;
    iPBar[0]=new(ELeave) CEikProgressInfo(info);
    iPBar[0]->SetContainerWindowL(*this);
	iPBar[0]->SetPosition(TPoint(20,20));
	
	info.iHeight=0;
	info.iWidth=240;
	info.iFinalValue=240;
	info.iSplitsInBlock=0;
	info.iTextType=EEikProgressTextNone;
    iPBar[1]=new(ELeave) CEikProgressInfo(info);
    iPBar[1]->SetContainerWindowL(*this);
	iPBar[1]->SetPosition(TPoint(20,70));
	
	info.iHeight=0;
	info.iWidth=280;
	info.iFinalValue=240;
	info.iTextType=EEikProgressTextPercentage;
    iPBar[2]=new(ELeave) CEikProgressInfo(info);
    iPBar[2]->SetContainerWindowL(*this);
	iPBar[2]->SetPosition(TPoint(20,120));

	info.iHeight=0;
	info.iWidth=320;
	info.iFinalValue=10000000;
	info.iTextType=EEikProgressTextFraction;
    iPBar[3]=new(ELeave) CEikProgressInfo(info);
    iPBar[3]->SetContainerWindowL(*this);
	iPBar[3]->SetPosition(TPoint(20,170));
    }

void CTestContainer::ResetAllValues()
	{
	for (TInt ii=0; ii<KNumberOfBars; ii++)
		iPBar[ii]->SetAndDraw(0);
	}

TInt CTestContainer::CountComponentControls() const
    {
    return(KNumberOfBars);
    }

CCoeControl* CTestContainer::ComponentControl(TInt aIndex) const
    {
    return(iPBar[aIndex]);
    }

void CTestContainer::Draw(const TRect& aRect) const
    {
	CWindowGc& gc=SystemGc();
	gc.SetBrushColor(iBackground);
	gc.Clear(aRect);
    }
  
void CTestContainer::IncrementBarsAndDraw(TInt aIncrement,TInt aMask)
	{
	TInt mask=0x01;
	TInt index=0;
	while (index<KNumberOfBars)
		{
		if (aMask&mask)
			iPBar[index]->IncrementAndDraw(aIncrement);
		index++;
		mask<<=1;
		}
	}

//
// CPrgiAppUi
//

class CPrgiAppUi : public CEikAppUi
    {
public:
    ~CPrgiAppUi();
    void ConstructL();
	TStreamId StoreL(CStreamStore& aStore) const;
private: // framework
	void HandleCommandL(TInt aCommand);
	void DynInitMenuPaneL(TInt aMenuId,CEikMenuPane* aMenuPane);
private: // menu commands
	void CmdExitL();
	void CmdTimerL();
	void CmdPause();
	void CmdColorsL();
	void CmdSizesL();
	void CmdPresentationL();
	void CmdReset();
private: // other internal functions
	void ConstructTimerModel();
	void ConstructTimerL();
private:
    CTestContainer* iContainer;
	TTimerModel iTimerModel;
	CPrgiTimer* iTimer;
    };

CPrgiAppUi::~CPrgiAppUi()
    {
    delete(iContainer);
	delete(iTimer);
    }
    
void CPrgiAppUi::ConstructL()
    {
    CEikAppUi::ConstructL();
    iContainer=new(ELeave) CTestContainer;
    iContainer->ConstructL(ClientRect());
    AddToStackL(iContainer);
	ConstructTimerModel();
	ConstructTimerL();
    }

TStreamId CPrgiAppUi::StoreL(CStreamStore& aStore) const
	{
	RStoreWriteStream stream;
	TStreamId streamId=stream.CreateLC(aStore);
	stream<<iTimerModel;
	TBarModel model[KNumberOfBars];
	iContainer->GetBarModels(&model[0]);
	for (TInt ii=0; ii<KNumberOfBars; ii++)
		stream<<model[ii];
	stream<<iContainer->BackgroundColor();
	stream.CommitL();
	CleanupStack::PopAndDestroy(); // stream
	return(streamId);
	}

void CPrgiAppUi::ConstructTimerModel()
	{
	iTimerModel.iHundredths=10;
	iTimerModel.iIncrement=1;
	iTimerModel.iWhichBars=0xff;
	iTimerModel.iRunning=ETrue;
	}

void CPrgiAppUi::ConstructTimerL()
	{
	iTimer=new(ELeave) CPrgiTimer;
	iTimer->ConstructL(&iTimerModel,iContainer);
	}

void CPrgiAppUi::DynInitMenuPaneL(TInt aMenuId,CEikMenuPane* aMenuPane)
	{
	if (aMenuId!=R_TPRG_PROP_MENU)
		return;
	if (!iTimerModel.iRunning)
		aMenuPane->SetItemButtonState(ETPrgiCmdPause,EEikMenuItemSymbolOn);
	}

void CPrgiAppUi::HandleCommandL(TInt aCommand)
	{
	TInt increment=0;
	switch (aCommand)
		{
	case EEikCmdExit:
		CmdExitL();
		break;
	case ETPrgiCmdStepForwards:
		increment=20;
		break;
	case ETPrgiCmdStepBackwards:
		increment=(-20);
		break;
	case ETPrgiCmdJumpForwards:
		increment=60;
		break;
	case ETPrgiCmdJumpBackwards:
		increment=(-60);
		break;
	case ETPrgiCmdTimer:
		CmdTimerL();
		break;
	case ETPrgiCmdPause:
		CmdPause();
		break;
	case ETPrgiCmdColors:
		CmdColorsL();
		break;
	case ETPrgiCmdSizes:
		CmdSizesL();
		break;
	case ETPrgiCmdPresentation:
		CmdPresentationL();
		break;
	case ETPrgiCmdReset:
		CmdReset();
		break;
	default:
		break;
		}
	if (increment)
		iContainer->IncrementBarsAndDraw(increment);
	}

void CPrgiAppUi::CmdExitL()
	{
	SaveAnyChangesL();
	CBaActiveScheduler::Exit();
	}

void CPrgiAppUi::CmdSizesL()
	{
	TBarModel model[KNumberOfBars];
	iContainer->GetBarModels(&model[0]);
	CEikDialog* dialog=new(ELeave) CSizesDialog(&model[0]);
	if (dialog->ExecuteLD(R_TPRG_DLG_SIZES))
		{
		iContainer->SetBarModelsL(&model[0]);
		SetDocChanged();
		}
	}

void CPrgiAppUi::CmdPresentationL()
	{
	TBarModel model[KNumberOfBars];
	iContainer->GetBarModels(&model[0]);
	CEikDialog* dialog=new(ELeave) CPresentationDialog(&model[0]);
	if (dialog->ExecuteLD(R_TPRG_DLG_PRESENTATION))
		{
		iContainer->SetBarModelsL(&model[0]);
		SetDocChanged();
		}
	}

void CPrgiAppUi::CmdTimerL()
	{
	CEikDialog *dialog=new(ELeave) CTimerDialog(&iTimerModel);
	if (dialog->ExecuteLD(R_TPRG_DLG_TIMER))
		SetDocChanged();
	}

void CPrgiAppUi::CmdPause()
	{
	if (iTimerModel.iRunning)
		iTimerModel.iRunning=EFalse;
	else
		iTimerModel.iRunning=ETrue;
	iToolBand->SetButtonStateOn(ETPrgiCmdPause,!iTimerModel.iRunning);
	iTimer->AdjustRunningState();
	SetDocChanged();
	}

void CPrgiAppUi::CmdColorsL()
	{
	TRgb color=iContainer->BackgroundColor();
	TBarModel model[KNumberOfBars];
	iContainer->GetBarModels(&model[0]);
	CEikDialog *dialog=new(ELeave) CColorDialog(&color,&model[0]);
	if (dialog->ExecuteLD(R_TPRG_DLG_COLORS))
		{
		iContainer->SetBackgroundColor(color);
		iContainer->SetBarModelsL(&model[0]);
		SetDocChanged();
		}
	}

void CPrgiAppUi::CmdReset()
	{
	iContainer->ResetAllValues();
	}

//
// CPrgiDocument
//

class CPrgiDocument : public CEikDocument
	{
public:
	CPrgiDocument(CEikApplication& aApp): CEikDocument(aApp) { }
private: // from CApaDocument
	CEikAppUi* CreateAppUiL();
	void StoreL(CStreamStore& aStore,CStreamDictionary& aStreamDic) const;
private: // internal use
	CPrgiAppUi* PrgiAppUi() const { return((CPrgiAppUi*)iAppUi); }
	};

void CPrgiDocument::StoreL(CStreamStore& aStore,CStreamDictionary& aStreamDic) const
	{
	if (!iAppUi)
		return;
	TStreamId streamId=PrgiAppUi()->StoreL(aStore);
	aStreamDic.AssignL(KUidTPrgiApp,streamId);
	}
	
CEikAppUi* CPrgiDocument::CreateAppUiL()
	{
    return(new(ELeave) CPrgiAppUi);
	}

//
// CPrgiApplication
//

class CPrgiApplication : public CEikApplication
	{
private: // from CApaApplication
	CApaDocument* CreateDocumentL();
	TUid AppDllUid() const;
	};

TUid CPrgiApplication::AppDllUid() const
	{
	return(KUidTPrgiApp);
	}

CApaDocument* CPrgiApplication::CreateDocumentL()
	{
	return(new(ELeave) CPrgiDocument(*this));
	}

//
// EXPORTed functions
//

EXPORT_C CApaApplication* NewApplication()
	{
	return(new CPrgiApplication);
	}

GLDEF_C TInt E32Dll(TDllReason)
	{
	return(KErrNone);
	}
