// EIKHOPBT.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <eikhopbt.h>
#include <eikopbut.h>
#include <barsread.h>
#include <eiklabel.h>
#include <eikenv.h>
#include <coedef.h>

enum {	EEikButtonArrayGranularity=5 };
const TInt KEikButtonSize=8;


EXPORT_C CEikLabeledOptionButton::~CEikLabeledOptionButton()
	{
	delete iButton;
	delete iLabel;
	}
						
EXPORT_C CEikLabeledOptionButton::CEikLabeledOptionButton()
	{
	__DECLARE_NAME(_S("CEikLabeledOptionButton"));
	}

EXPORT_C CEikLabeledOptionButton::CEikLabeledOptionButton(TInt aId,TBool aTextOnRight)
	{
	iTextOnRight=aTextOnRight;
	iId=aId;
	SetBehavior(EEikButtonLatches);
	}

EXPORT_C void CEikLabeledOptionButton::ConstructL(const CCoeControl& aContainer,TEikButtonCoordinator& aCoordinator,const TDesC& aText)
	{
	SetContainerWindowL(aContainer);
	SetCoordinator(&aCoordinator);
	iButton=new(ELeave) CEikOptionButton;
	iButton->ConstructL();
	iButton->SetContainerWindowL(*this);

	iLabel=new(ELeave) CEikLabel;
	iLabel->SetContainerWindowL(*this);
	iLabel->SetFont(iEikonEnv->NormalFont());
	iLabel->SetTextL(aText);
	iLabel->SetAllMarginsTo(1);
	iLabel->SetAlignment(EHCenterVCenter);

	TSize buttonSize=iButton->MinimumSize();
	iButton->SetSizeL(buttonSize);

	TSize labelSize=iLabel->MinimumSize();
	labelSize.iHeight=(buttonSize.iHeight>labelSize.iHeight)? buttonSize.iHeight: labelSize.iHeight ;
	iLabel->SetSizeL(TSize(iLabel->MinimumSize().iWidth,labelSize.iHeight));

	SetSizeL(TSize(labelSize.iWidth+buttonSize.iWidth,labelSize.iHeight));
	}					

//EXPORT_C CEikLabel* CEikLabeledOptionButton::Label()
//	 {
//	 return iLabel;
//	 }

EXPORT_C const TInt CEikLabeledOptionButton::Id()
	{
	return iId;
	}

EXPORT_C void CEikLabeledOptionButton::SizeChangedL()
	{
	TPoint point=Position();
	TSize labelSize=iLabel->Size();
	TSize buttonSize=iButton->Size();
	if (iTextOnRight)
		{
		iButton->SetExtentL(point,buttonSize);
		point.iX+=buttonSize.iWidth;
		iLabel->SetExtentL(point,labelSize);
		}
	else
		{
		iLabel->SetExtentL(point,labelSize);
		point.iX+=labelSize.iWidth;
		iButton->SetExtentL(point,buttonSize);
		}
	}

EXPORT_C TSize CEikLabeledOptionButton::MinimumSize()
	{
	return Size();
	}
													   
EXPORT_C void CEikLabeledOptionButton::StateChanged()
	{
	CopyDrawStateTo(iButton);
	}

EXPORT_C TInt CEikLabeledOptionButton::CountComponentControls() const
	{
	return (2);
	}

EXPORT_C CCoeControl* CEikLabeledOptionButton::ComponentControl(TInt aIndex) const
	{
	return (aIndex==0) ? (CCoeControl*)iButton : (CCoeControl*)iLabel;
	}

//
/////////////////////////////  class CEikHorOptionButtonList///////////////////////////
//

EXPORT_C CEikHorOptionButtonList::CEikHorOptionButtonList()
	{}

EXPORT_C void CEikHorOptionButtonList::ConstructL()
	{
	iButtonId=-1;
	iOptionButtonArray=new(ELeave) CArrayFixFlat<CEikLabeledOptionButton*> (EEikButtonArrayGranularity);
	}

EXPORT_C CEikHorOptionButtonList::CEikHorOptionButtonList(TInt aInterButtonSpacing,TBool aTextOnRight)
	:iTextOnRight(aTextOnRight),
	iInterButtonSpacing(aInterButtonSpacing)
	{}

EXPORT_C CEikHorOptionButtonList::~CEikHorOptionButtonList()
	{
	if (iOptionButtonArray)
		{
		for (TInt i=0;i<iOptionButtonArray->Count();++i)
			delete (*iOptionButtonArray)[i];
		delete iOptionButtonArray;
		}
	}

EXPORT_C void CEikHorOptionButtonList::Reserved_1()	//reserved by coecontrol
	{
	}									  

EXPORT_C void CEikHorOptionButtonList::Reserved_2()	//reserved by coecontrol
	{
	}									  

EXPORT_C void CEikHorOptionButtonList::HandleControlEventL(CCoeControl* /*aControl*/,TCoeEvent aEvent)
	{
	if (aEvent==EEventStateChanged)
		{
		if(iButtonId!=LabeledButtonId()) 
			{
			iButtonId=LabeledButtonId();
			ReportEventL(aEvent);
			}
		}
	else
		ReportEventL(aEvent);
	}

EXPORT_C void CEikHorOptionButtonList::ConstructFromResourceL(TResourceReader& aReader)
	{
	ConstructL();
	iInterButtonSpacing=aReader.ReadInt16();
	iTextOnRight=aReader.ReadInt16();
    TInt optionButtonsGroupId=aReader.ReadInt32();

    TResourceReader reader;
    iCoeEnv->CreateResourceReaderLC(reader,optionButtonsGroupId);
	const TInt count=reader.ReadInt16();
	for (TInt ii=0;ii<count;++ii)
		{
		TInt id=reader.ReadInt16();
		TPtrC text=reader.ReadTPtrC();
		AddOptionButtonL(id,text);
		}
	CleanupStack::PopAndDestroy();
	}

EXPORT_C void CEikHorOptionButtonList::AddOptionButtonL(TInt aId,const TDesC& aText)
	{
	CEikLabeledOptionButton* labeledoptionButton=new(ELeave) CEikLabeledOptionButton(aId,iTextOnRight);
	CleanupStack::PushL(labeledoptionButton);
	labeledoptionButton->ConstructL(*this,iCoordinator,aText);
	labeledoptionButton->SetObserver(this);
	labeledoptionButton->SetNonFocusing();
	iOptionButtonArray->AppendL(labeledoptionButton);
	CleanupStack::Pop();
	}

EXPORT_C  TKeyResponse CEikHorOptionButtonList::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode /*aType*/)
	{
	TInt code=aKeyEvent.iCode;
	if ((code==EKeyUpArrow) || (code==EKeyDownArrow))
		return(EKeyWasNotConsumed);

	TInt count=iOptionButtonArray->Count();
	TInt i=0;
	while (i<count)
		{
		const CEikLabeledOptionButton* button=(*iOptionButtonArray)[i];
		if (button->State()==CEikButtonBase::ESet)
			break;
		i++;
		}
	count--;
	switch (aKeyEvent.iCode)
		{
	case EKeyEnd:
		i=count;
		break;
	case EKeyTab:
	case EKeyRightArrow:
		i=(i==count)? 0:i+1;
		break;
	case EKeyHome:
		i=0;
		break;
	case EKeyLeftArrow:
		i=(i-1<0)? count:i-1;
		break;
	case EKeyUpArrow:
	case EKeyDownArrow:
		return(EKeyWasConsumed); 
	default:
		return (EKeyWasNotConsumed);  
		}
	const TInt id=(*iOptionButtonArray)[i]->Id();
	SetButtonById(id);
	(*iOptionButtonArray)[i]->DrawNow();
	ReportEventL(EEventStateChanged);
	return(EKeyWasConsumed); 
	}
									
EXPORT_C TSize CEikHorOptionButtonList::MinimumSize()
	{
	TInt count=iOptionButtonArray->Count();
	TSize size;
	for (TInt i=0;i<count;++i)
		{
		size.iWidth+=(*iOptionButtonArray)[i]->Size().iWidth;
		TInt height=(*iOptionButtonArray)[i]->Size().iHeight;
		if (height>size.iHeight)
			size.iHeight = height;
		}
	size.iWidth+=iInterButtonSpacing*(count-1);
	return size;
	}

EXPORT_C  void CEikHorOptionButtonList::SizeChangedL()
	{
	TInt count=iOptionButtonArray->Count();
	TPoint point=Position();
	TSize size;
	for (TInt i=0;i<count;i++)
		{
		size=(*iOptionButtonArray)[i]->Size();
		if ((i+1)!=count)
			size.iWidth+=(iInterButtonSpacing);
		(*iOptionButtonArray)[i]->SetExtentL(point,size);
		point.iX+=size.iWidth;
		}
	}

EXPORT_C void CEikHorOptionButtonList::SetButtonById(TInt aId)
	{
	if (iButtonId==aId)
		return;
	iButtonId=aId;
	TInt count=iOptionButtonArray->Count();
	TInt i=0;
	while (i<count)
		{
		if ((*iOptionButtonArray)[i]->Id()==aId)
			{
			(*iOptionButtonArray)[i]->SetState(CEikButtonBase::ESet);
			return;
			}
		i++;
		}
	}

EXPORT_C TInt CEikHorOptionButtonList::LabeledButtonId()
	{
	TInt count=iOptionButtonArray->Count();
	TInt i=0;
	while (i<count)
		{
		if ((*iOptionButtonArray)[i]->State()==CEikButtonBase::ESet)
			return (*iOptionButtonArray)[i]->Id();
		i++;
		}
	return 0;
	}

EXPORT_C TInt CEikHorOptionButtonList::CountComponentControls() const
	{
	return (iOptionButtonArray->Count());
	}

EXPORT_C CCoeControl* CEikHorOptionButtonList::ComponentControl(TInt aIndex) const
	{
	return (*iOptionButtonArray)[aIndex];
	}
