/*
* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*
*/


#ifndef __PKGFILEPARSER_H__
#define __PKGFILEPARSER_H__

#ifdef WIN32
#ifdef _STLP_INTERNAL_WINDOWS_H
#define __INTERLOCKED_DECLARED
#endif
#include <windows.h>
#endif

#include <iostream>

#include <sstream>
#include <string>
#include <list>
#include <map>
#undef _L

#include "pkglanguage.h"

typedef class PkgParser PKGPARSER, *PPKGPARSER;

//Data structures for pkg file parsing
#define EOF_TOKEN			0
#define NUMERIC_TOKEN		1
#define ALPHA_TOKEN			2
#define QUOTED_STRING_TOKEN	3
#define AND_TOKEN			4
#define OR_TOKEN			5
#define NOT_TOKEN			6
#define EXISTS_TOKEN		7
#define DEVCAP_TOKEN		8
#define APPCAP_TOKEN		9
#define GE_TOKEN			10
#define LE_TOKEN			11
#define NE_TOKEN			12
#define IF_TOKEN			13
#define ELSEIF_TOKEN		14
#define ELSE_TOKEN			15
#define ENDIF_TOKEN			16
#define TYPE_TOKEN			17
#define KEY_TOKEN			18
#define LAST_TOKEN			18

#define MAX_STRING 255

typedef union _tag_VARIANTVAL
{
	TInt32 iNumber;					// numeric value, e.g. 100
	char iString[MAX_STRING];	// string value, e.g. "crystal"
}VARIANTVAL;

//Data structures to store the pkg file contents
/**
Supported package body statements
*/
typedef enum cmd_type {IF, ELSEIF, ELSE, ENDIF, INSTALLFILE, PACKAGE} CMD_TYPE;

/**
Structure to store the language details
*/
typedef struct _tag_LangList
{
	string iLangName;  // Language Name
	TUint32 iLangCode; // Language code
	TUint32 iDialectCode; // Dialect code
}LANG_LIST, *PLANG_LIST;

/**
Structure to store the package file header details
*/
typedef struct _tag_Pkgheader
{
	list<string> iPkgNames;
	TUint32 iPkgUID;
	TInt iMajorVersion;
	TInt iMinorVersion;
	TInt iBuildVersion;
	string iPkgType;
}PKG_HEADER, *PPKG_HEADER;

/**
Structure to store the installable file list
*/
typedef struct _tag_InstallFileList
{
	TInt iLangDepFlag;
	TInt iPkgFlag;
	list<string> iSourceFiles;
	string iDestFile;
}INSTALLFILE_LIST, *PINSTALLFILE_LIST;

/**
Structure to store the package body details
*/
typedef struct _tag_CmdBlock
{
	CMD_TYPE iCmdType; // Command type
	string iCmdExpr; // Expression
	PINSTALLFILE_LIST iInstallFileList; // Installable file details
}CMD_BLOCK, *PCMD_BLOCK;

typedef list<PLANG_LIST> LANGUAGE_LIST;
typedef list<string> SISFILE_LIST, FILE_LIST;
typedef list<PCMD_BLOCK> CMDBLOCK_LIST;

/** 
class PkgParser
	Parses the package file generated by DUMPSIS tool

@internalComponent
@released
*/
class PkgParser
{
public:
	PkgParser(const string& aFile);
	~PkgParser();

	void ParsePkgFile();
	void GetEmbeddedSisList(SISFILE_LIST& embedSisList);
	void GetInstallOptions(FILE_LIST& aOptions);
	void GetLanguageList(LANGUAGE_LIST& langList);
	void GetHeader(PKG_HEADER& pkgHeader);
	void GetCommandList(CMDBLOCK_LIST& cmdList);
	const char* GetPkgFileName(){
		return iPkgFileName.c_str();
	}

private:
	bool OpenFile();
	void DeleteAll(); 
	
	const char* iPkgFileContent ;
	TUint iContentPos ;
	string iContentStr  ;

	LANGUAGE_LIST iLangList;
	PKG_HEADER iPkgHeader;
	SISFILE_LIST iEmbedSisFiles;
	FILE_LIST iInstallOptions;
	CMDBLOCK_LIST iPkgBlock;

	string iPkgFileName;

	//Parser Methods
	void AddLanguage(const string& aLang, TUint32 aCode, TUint32 aDialect);
	 
	void GetNextChar() ;
	inline char GetCurChar() const {
		return iPkgFileContent[iContentPos] ;
	}
	void GetNextToken();
	bool GetStringToken();
	TUint16 ParseEscapeChars();
	void GetAlphaNumericToken();
	bool IsNumericToken();
	void GetNumericToken();
	void ParseEmbeddedBlockL ();
	void ParseCommentL();
	inline void ExpectToken(TInt aToken) { 
		if (iToken!=aToken) 
			ParserError("Unexpected Token"); 
	}
	void ParseHeaderL();
	void ParseLanguagesL();
	void ParseFileL();
	void ParsePackageL();
	void ParseIfBlockL();
	void ParseLogicalOp(string& aExpression);
	void ParseRelation(string& aExpression);
	void ParseUnary(string& aExpression);
	void ParseFactor(string& aExpression);
	void ParseOptionsBlockL();
	void ParsePropertyL();
	void ParseVendorNameL();
	void ParseLogoL();
	void ParseDependencyL();
	void ParseVersion();
	void ParseVendorUniqueNameL();
	void ParseTargetDeviceL();

	//Parser Attributes 
	TInt iToken;
	VARIANTVAL iTokenVal;
	TInt iLineNumber;

	void ParserError(const char* aMsg);
 
};
 
#endif //__PKGFILEPARSER_H__
