// EIKEMBAL.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <eikenv.h>
#include <eikfutil.h>
#include <barsread.h>
#include <apgcli.h>
#include <apffndr.h>
#include <apgaplst.h>
#include <apsserv.h>
#include <eikembal.h>
#include <eikdoc.h>
#include <eikon.rsg>


const TInt KMaxRetries=5;

//
// class CEikEmbeddableAppList
//

EXPORT_C CEikEmbeddableAppList::CEikEmbeddableAppList()
	: CArrayFixFlat<TApaAppInfo>(4)
	{
	}

EXPORT_C CEikEmbeddableAppList::~CEikEmbeddableAppList()
	{
	}

EXPORT_C void CEikEmbeddableAppList::ConstructL()
	{
	TInt ret=GetAppListL();
	TInt count=0;
	while (ret==RApaLsSession::EAppListInvalid && count++<KMaxRetries)
		ret=GetAppListL();
	if (ret==RApaLsSession::EAppListInvalid)
		User::Leave(KErrGeneral);
	User::LeaveIfError(ret);
	SortAppListL();
	}

TInt CEikEmbeddableAppList::GetAppListL()
	{
	// open a list server session
	RApaLsSession ls;
	User::LeaveIfError(ls.Connect());
	//
	// get the app list piece by piece
	TInt ret=0;
	TRAPD(err,ret=DoGetAppListL(ls));
	ls.Close(); 
	return (err!=KErrNone)? err : ret;
	}

TInt CEikEmbeddableAppList::DoGetAppListL(RApaLsSession& aLs)
	{
	// get the app list piece by piece
	User::LeaveIfError(aLs.GetEmbeddableApps());
	TApaAppInfo info;
	TInt ret=aLs.GetNextApp(info);
	TApaAppCapabilityBuf buf;
	while (ret==KErrNone)
		{
		aLs.GetAppCapability(buf,info.iUid);
		TApaAppCapability capability=buf();
		if(!capability.iAppIsHidden)
			AppendL(info);
		ret = aLs.GetNextApp(info);
		}
	if (ret!=RApaLsSession::ENoMoreAppsInList && ret!=RApaLsSession::EAppListInvalid)
		User::Leave(ret);
	return ret;	
	}

const TInt KEikAppSortUidBase=-1024;
const TInt KEikAppSortUidLimit=0;

void CEikEmbeddableAppList::SortAppListL()
	{
	TResourceReader reader;
	CEikonEnv::Static()->CreateResourceReaderLC(reader,R_EIK_ARRAY_FILE_SORT_TABLE);
	CEikFileSortTable* sortTable=new(ELeave) CEikFileSortTable;
	CleanupStack::PushL(sortTable);
	sortTable->ConstructFromResourceL(reader);

	const TInt count=Count();
	for (TInt i=0;i<count;i++)
		{
		TApaAppInfo* pEntry=&(*this)[i];
		TInt index;
		TKeyArrayFix key(0,ECmpTInt);
		if (sortTable->Find(pEntry->iUid,key,index)==KErrNone)
			{
			pEntry->iUid=TUid::Uid(index+KEikAppSortUidBase);
			}
		}

	TKeyArrayFix key(_FOFF(TApaAppInfo,iUid),ECmpTInt);
	Sort(key); // Ignore return codes from Sort()

	for (TInt j=0;j<count;j++)
		{
		TApaAppInfo* pEntry=&(*this)[j];
		TInt index=pEntry->iUid.iUid;
		if (index>=KEikAppSortUidBase && index<KEikAppSortUidLimit)
			{
			pEntry->iUid=(*sortTable)[index-KEikAppSortUidBase];
			}
		}

	CleanupStack::PopAndDestroy(2); // reader, sortTable
	}

EXPORT_C TInt CEikEmbeddableAppList::MdcaCount() const
	{
	return Count();
	}

EXPORT_C TPtrC CEikEmbeddableAppList::MdcaPoint(TInt aIndex) const
	{
	return (*this)[aIndex].iCaption;
	}

EXPORT_C CEikDocument* CEikEmbeddableAppList::CreateEmbeddedDocumentL(TInt aIndex,CApaProcess* aProcess)
	{
	TApaAppInfo info = (*this)[aIndex];
	CApaDocument* newDoc=aProcess->AddNewDocumentL(info.iFullName,info.iUid);
	return ((CEikDocument*)newDoc);
	}
