// EIKAPP.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <s32file.h>
#include <eikapp.h>
#include <coemain.h>
#include <eikenv.h>
#include <eikdef.hrh>
#include <bautils.h>
#include <coeutils.h>
#include <apgicnfl.h>
#include <apfdef.h>

class CEikApplication::CExtra : public CBase
	{
public:
	enum
		{
		EFlagAllWindowsMustBeBackedUpWindows=0x01
		};
public:
	TApaAppCapabilityBuf* iCapabilityBuf;
	TUint iFlags;
	};

EXPORT_C CEikApplication::CEikApplication()
	{}

EXPORT_C CEikApplication::~CEikApplication()
	{
    iCoeEnv->DeleteResourceFile(iResourceFileOffset);
	if (iExtra!=NULL)
		{
		delete iExtra->iCapabilityBuf;
		delete iExtra;
		}
	}

void CEikApplication::ParseWithAppName(TParse& aParse,const TDesC& aFileName) const
	{
	TFileName libPath=AppFullName();
	aParse.Set(aFileName,&libPath,NULL);
	}

EXPORT_C TFileName CEikApplication::ResourceFileName() const
	{ // !! needs to cope with multi-lingual apps
	TParse parse;
	ParseWithAppName(parse,_L(".rsc"));
	TFileName name=parse.FullName();
	BaflUtils::NearestLanguageFile(iEikonEnv->FsSession(),name);
	return name;
	}

EXPORT_C TFileName CEikApplication::BitmapStoreName() const
	{ // !! needs to cope with multi-lingual apps
	TParse parse;
	ParseWithAppName(parse,_L(".mbm"));
	TFileName name=parse.FullName();
	BaflUtils::NearestLanguageFile(iEikonEnv->FsSession(),name);
	return name;
	}

EXPORT_C CApaDocument* CEikApplication::CreateDocumentL(CApaProcess* aProcess)
	{
	iProcess=aProcess;
	return(CreateDocumentL());
	}

EXPORT_C void CEikApplication::PreDocConstructL()
	{
	iCoeEnv=CCoeEnv::Static();
	TFileName* fileName=new(ELeave) TFileName;
	CleanupStack::PushL(fileName);
	*fileName=ResourceFileName();
	if (fileName->Length())
    	iResourceFileOffset=iCoeEnv->AddResourceFileL(*fileName);
	TRAPD(err,ReadCaptionNameL());
	if (err!=KErrNotFound)
		User::LeaveIfError(err); // !! loss of contextual information
	else
		{
		*fileName=AppFullName();
		TParsePtrC parse(*fileName);
		iCaption=parse.Name();
		}
	CleanupStack::PopAndDestroy(); // fileName
	if (iExtra==NULL)
		{
		iExtra=new(ELeave) CExtra;
		}
	else
		{
		delete iExtra->iCapabilityBuf;
		iExtra->iCapabilityBuf=NULL;
		}
	iExtra->iCapabilityBuf=new(ELeave) TApaAppCapabilityBuf();
	CApaAppInfoFileReader* reader=NULL;
	TRAPD(ret,reader=OpenAppInfoFileL());
	if (ret==KErrNone)
		{
		reader->Capability(*iExtra->iCapabilityBuf);
		delete reader;
		}
	}

void CEikApplication::ReadCaptionNameL()
	{
	CApaAppInfoFileReader* reader=OpenAppInfoFileLC();
	iCaption=reader->CaptionL(User::Language());
	CleanupStack::PopAndDestroy(); // reader
	}

EXPORT_C void CEikApplication::GetDefaultDocumentFileName(TFileName& aDocumentName) const
	{
	TApaAppCaption candidate=iCaption;
	if (iResourceFileOffset)
	    {
		iCoeEnv->ReadResource(candidate,EDefaultNameResourceOffset+iResourceFileOffset);
		if (!candidate.Length())
			{
			aDocumentName.Zero();
			return;
			}
		}
	TParse parse;
	parse.Set(candidate,&aDocumentName,NULL);
	aDocumentName=parse.FullName();
	}

EXPORT_C CApaAppInfoFileReader* CEikApplication::OpenAppInfoFileLC() const
	{
	TParse parser;
	TFileName name(AppFullName());
	parser.SetNoWild(KAppInfoFileExtension,&name,NULL); // *.aif CApaAppInfoFileReader* 
	CApaAppInfoFileReader* reader=CApaAppInfoFileReader::NewLC(parser.FullName(),AppDllUid());
	return reader;
	}

EXPORT_C CDictionaryStore* CEikApplication::OpenIniFileLC(RFs& aFs) const
// Opens the applications ini file if it exists, otherwise creates a new one
// The ini file is located on KIniFileDrive (c:), in the same directory as the app dll
	{
	// get the path of the ini file
	TParse parser;
	SetToIniFileNameL(parser);
	// ensure that all directories in the path exist 
	aFs.MkDirAll(parser.FullName()); // ignore the error //
	// open the ini file if it exists, otherwise create a new one
	CDictionaryStore* inifile=NULL;
	// if first attempt to open ini fails because of corrupt file, delete it and try again.
	TRAPD(err,inifile=CDictionaryFileStore::OpenL(aFs,parser.FullName(),AppDllUid()));
	if (err==KErrNone)
		CleanupStack::PushL(inifile);
	else if (err==KErrEof || err==KErrCorrupt)
		{
		User::LeaveIfError(aFs.Delete(parser.FullName()));
		inifile=CDictionaryFileStore::OpenLC(aFs,parser.FullName(),AppDllUid());
		err=KErrNone;
		}
	User::LeaveIfError(err);
	return inifile;
	}

EXPORT_C void CEikApplication::SetToIniFileNameL(TParse& aParser) const
// The ini file is located on KIniFileDrive (c:), in the same directory as the app dll
	{
	const TPtrC cDrive=_L("C:");
	TFileName* appFullName=new(ELeave) TFileName(AppFullName());
	CleanupStack::PushL(appFullName);
	User::LeaveIfError(aParser.SetNoWild(KIniFileExtension,&cDrive,appFullName));
	CleanupStack::PopAndDestroy(); // appFullName
	}

EXPORT_C void CEikApplication::SetAllWindowsMustBeBackedUpWindowsL(TBool aAllWindowsMustBeBackedUpWindows)
	{
	if (iExtra==NULL)
		{
		iExtra=new(ELeave) CExtra;
		}
	if (aAllWindowsMustBeBackedUpWindows)
		{
		iExtra->iFlags|=CExtra::EFlagAllWindowsMustBeBackedUpWindows;
		}
	else
		{
		iExtra->iFlags&=~CExtra::EFlagAllWindowsMustBeBackedUpWindows;
		}
	}

EXPORT_C TBool CEikApplication::AllWindowsMustBeBackedUpWindows() const
	{
	return (iExtra!=NULL) && (iExtra->iFlags&CExtra::EFlagAllWindowsMustBeBackedUpWindows);
	}

EXPORT_C void CEikApplication::Capability(TDes8& aInfo)const
	{
	TApaAppCapability::CopyCapability(aInfo,*iExtra->iCapabilityBuf);
	}

EXPORT_C void CEikApplication::Reserved_1()
	{}

