/*
* Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "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: 
*       Defines the entry point for the console application
*
*/



// disable "identifier was truncated to '255' characters in the browser information" warning
#pragma warning (disable:4786)

#include "Cdl2Lag.h"
#include "LayoutCompilerErr.h"
#include "CodeGenConsts.h"
#include <fstream>
using namespace std;
using namespace CdlCompilerToolkit;

typedef LayoutProcessArgsErr<CdlToLag> CdlToLagArgsErr;


CdlToLag::CdlToLag(ofstream& aLag, const string& aLagName)
: iLag(aLag), iLagName(aLagName)
	{
	}

int CdlToLag::Process(const vector<string>& args)
	{
	if (args.size() < 4)
		throw CdlToLagArgsErr();

	string lagName = args[2];
	ofstream lag;
	CCdlTkFileCleanup temp;
	CdlTkUtil::OpenTempOutput(lag, temp);

	CdlToLag process(lag, lagName);
	process.Start();

	for (unsigned int ii = 3; ii < args.size(); ii++)
		{
		string cdlName = args[ii];
		CCdlTkCdlFileParser parser(cdlName);
		auto_ptr<CCdlTkInterface> iface(parser.LoadAndParse(true));
		process.AddInterface(*iface);
		}

	process.Finish();

	lag.close();
	CdlTkUtil::ExportFile(temp, CdlTkUtil::CurrentDrive()+KDirEpocSysHeader+CdlTkUtil::StripPath(lagName));

	return 0;
	}

void CdlToLag::ShowHelp(ostream& stream)
	{
	stream << "Cdl2Lag <lagName> <CdlNames>" << endl;
	}

void CdlToLag::Start()
	{
	WriteHeader();
	}

void CdlToLag::Finish()
	{
	WriteFooter();
	}

void CdlToLag::AddInterface(CCdlTkInterface& aInterface)
	{
	iInterface = &aInterface;
	WriteInclude();
	CCdlTkApiList& list = iInterface->ApiList();
	for (CCdlTkApiList::iterator pApi = list.begin(); pApi != list.end(); ++pApi)
		{
		WriteMacro(**pApi);
		}
	}

void CdlToLag::WriteHeader()
	{
	iLag << "// " << iLagName << " generated by:" << endl;
	iLag << "// " << CdlTkUtil::CommandLine() << endl;
	string guardName = CdlTkUtil::ToUpper(CdlTkUtil::ToCpp(CdlTkUtil::StripPath(iLagName)));
	iLag << "#if !defined(" << guardName << ")" << endl;
	iLag << "#define " << guardName << endl;
	}

void CdlToLag::WriteInclude()
	{
	iLag << "#include <" << CdlTkUtil::StripPath(iInterface->FileName()) << ".h>" << endl;
	}

void CdlToLag::WriteMacro(CCdlTkApi& aApi)
	{
	string macro = "#define ";
	const string& name = aApi.Name();
	string macroName = name;
	if (aApi.IsFunc() && aApi.AsFunc().Params().size() && aApi.AsFunc().Params()[0].Name() == KParamLineIndex)
		{
		macro += "AKN_LAYOUT_TABLE_";
		}
	else if (aApi.ReturnType() == KTypeWindowLineLayout)
		{
		macro += "AKN_LAYOUT_WINDOW_";
		}
	else if (aApi.ReturnType() == KTypeTextLineLayout)
		{
		macro += "AKN_LAYOUT_TEXT_";
		}
	else if (aApi.ReturnType() == KTypeLayoutTableLimits)
		{
		macro += "AKN_LAYOUT_TABLE_LIMITS_";
		}
	else
		{
		macro += "AKN_LAYOUT_MULTILINE_TEXT_";
		macroName = macroName.substr(KFuncMultiline.length());	// remove "Multiline_"
		}

	macro += macroName + " " + iInterface->NamespaceName() + "::" + name;
	if (aApi.AsFunc().Params().size() == 0)	// was once data only API
		macro += "()";

	iLag << macro << endl;
	}

void CdlToLag::WriteFooter()
	{
	iLag << "#endif" << endl;
	}
