// EIKHLBX.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <eikenv.h> 
#include <eikhlbx.h>
#include <eiklbx.h>
#include <eikhlbv.h> 
#include <eikhlbm.h>
#include <eikhlbi.h>

//
// class CEikHierarchicalListBox
//

EXPORT_C CEikHierarchicalListBox::CEikHierarchicalListBox()
	{}

EXPORT_C CEikHierarchicalListBox::~CEikHierarchicalListBox()
	{
	if (iHlbxDestroyed)
		*iHlbxDestroyed=ETrue;	
	}

EXPORT_C TKeyResponse CEikHierarchicalListBox::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
	{
	const TInt currentItem=CurrentItemIndex();
	if (aKeyEvent.iCode!=EKeyTab || aKeyEvent.iModifiers&(EModifierShift|EModifierCtrl|EModifierFunc))
		CEikListBox::OfferKeyEventL(aKeyEvent,aType);
	else if (currentItem>-1 && currentItem<HlModel()->NumberOfItems())
		HandleItemSelectionL();
	return(EKeyWasConsumed);
	}

EXPORT_C void CEikHierarchicalListBox::HandlePointerEventL(const TPointerEvent& aPointerEvent)
	{
	TBool destroyed=EFalse;
	iHlbxDestroyed=&destroyed;
	TInt index;
	const TBool overItem=iView->XYPosToItemIndex(aPointerEvent.iPosition,index);
	if (aPointerEvent.iType==TPointerEvent::EButton1Down && overItem)
		iPressedIndex=(index==CurrentItemIndex() ? index : -1);
	TPointerEvent event=aPointerEvent;
	event.iModifiers&=(~EModifierDoubleClick);
	CEikListBox::HandlePointerEventL(event);
	if (destroyed)
		return;
	iHlbxDestroyed=NULL;
	if (aPointerEvent.iType==TPointerEvent::EButton1Up)
		{
		if (overItem && iPressedIndex==index)
			HandleItemSelectionL();
		}
	}

void CEikHierarchicalListBox::HandleItemSelectionL()
	{
	const TInt index=CurrentItemIndex();
	CArrayFix<CHierListItem*>* listArray=HlModel()->HierListArray();
	TBool itemHasChildren=EFalse;
	if ((*listArray)[index]->IsExpanded())
		{
		if (index<HlModel()->NumberOfItems()-1)
			itemHasChildren=((*listArray)[index]->Level()==(*listArray)[index+1]->Level()-1);
		HlModel()->CollapseItem(index);
		}
	else
		{
		HlModel()->ExpandItemL(index);
		CArrayFix<CHierListItem*>* newListArray=HlModel()->HierListArray();
		if (index<newListArray->Count()-1)
			itemHasChildren=((*newListArray)[index]->Level()==(*newListArray)[index+1]->Level()-1);
		}
	iView->CalcDataWidth();
	iView->CalcBottomItemIndex();
	UpdateScrollBarsL();
	if (itemHasChildren)
		((CHierarchicalListBoxView*)iView)->DrawFromItem(index);
	else
		((CHierarchicalListBoxView*)iView)->DrawItem(index);
	ReportListBoxEventL(MEikListBoxObserver::EEventItemActioned);
	}

EXPORT_C CListBoxView* CEikHierarchicalListBox::MakeViewClassInstanceL()
	{
	return (new(ELeave) CHierarchicalListBoxView);
	}

EXPORT_C CHierarchicalListBoxModel* CEikHierarchicalListBox::HlModel() const
	{
	return STATIC_CAST(CHierarchicalListBoxModel*,Model());
	}

EXPORT_C CHierarchicalListBoxView* CEikHierarchicalListBox::HlView() const
	{
	return STATIC_CAST(CHierarchicalListBoxView*,iView);
	}

EXPORT_C CHierarchicalListItemDrawer* CEikHierarchicalListBox::HlDrawer() const
	{
	return STATIC_CAST(CHierarchicalListItemDrawer*,iItemDrawer);
	}

EXPORT_C void CEikHierarchicalListBox::Reserved_1()
	{}

EXPORT_C void CEikHierarchicalListBox::Reserved_2()
	{}

EXPORT_C void CEikHierarchicalListBox::Reserved_3()
	{}
