/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_l10ntools.hxx"
#include <stdio.h>
#include <tools/string.hxx>
#include <tools/fsys.hxx>

// local includes
#include "export.hxx"
#include "cfgmerge.hxx"
#include "tokens.h"
#include "utf8conv.hxx"

extern "C" { int yyerror( char * ); }
extern "C" { int YYWarning( char * ); }

// defines to parse command line
#define STATE_NON  		0x0001
#define STATE_INPUT		0x0002
#define STATE_OUTPUT	0x0003
#define STATE_PRJ		0x0004
#define STATE_ROOT		0x0005
#define STATE_MERGESRC	0x0006
#define STATE_ERRORLOG	0x0007
#define STATE_UTF8		0x0008
#define STATE_LANGUAGES	0X0009
#define STATE_ISOCODE99	0x000A
#define STATE_FORCE		0x000B

// set of global variables
sal_Bool bEnableExport;
sal_Bool bMergeMode;
sal_Bool bErrorLog;
sal_Bool bForce;
sal_Bool bUTF8;
ByteString sPrj;
ByteString sPrjRoot;
ByteString sInputFileName;
ByteString sActFileName;
ByteString sFullEntry;
ByteString sOutputFile;
ByteString sMergeSrc;
String sUsedTempFile;

CfgParser *pParser;

extern "C" {
// the whole interface to lexer is in this extern "C" section

/*****************************************************************************/
extern char *GetOutputFile( int argc, char* argv[])
/*****************************************************************************/
{
	bEnableExport   = sal_False;
	bMergeMode      = sal_False;
	bErrorLog       = sal_True;
	bForce          = sal_False;
	bUTF8           = sal_True;
    sPrj            = "";
	sPrjRoot        = "";
	sInputFileName  = "";
	sActFileName    = "";

	sal_uInt16 nState = STATE_NON;
	sal_Bool bInput = sal_False;

	// parse command line
	for( int i = 1; i < argc; i++ ) {
        ByteString sSwitch( argv[ i ] );
        sSwitch.ToUpperAscii();
        
        if ( sSwitch == "-I" ) {
			nState = STATE_INPUT; // next token specifies source file
		}
		else if ( sSwitch == "-O" ) {
			nState = STATE_OUTPUT; // next token specifies the dest file
		}
		else if ( sSwitch == "-P" ) {
			nState = STATE_PRJ; // next token specifies the cur. project
		}
		else if ( sSwitch == "-R" ) {
			nState = STATE_ROOT; // next token specifies path to project root
		}
		else if ( sSwitch == "-M" ) {
			nState = STATE_MERGESRC; // next token specifies the merge database
		}
		else if ( sSwitch == "-E" ) {
			nState = STATE_ERRORLOG;
			bErrorLog = sal_False;
		}
		else if ( sSwitch == "-UTF8" ) {
			nState = STATE_UTF8;
			bUTF8 = sal_True;
		}
		else if ( sSwitch == "-NOUTF8" ) {
			nState = STATE_UTF8;
			bUTF8 = sal_False;
		}
		else if ( sSwitch == "-F" ) {
			nState = STATE_FORCE;
			bForce = sal_True;
		}
        else if ( sSwitch == "-L" ) {
			nState = STATE_LANGUAGES;
		}
		else if ( sSwitch.ToUpperAscii() == "-ISO99" ) {
			nState = STATE_ISOCODE99;
		}
		else {
			switch ( nState ) {
				case STATE_NON: {
					return NULL;	// no valid command line
				}
				case STATE_INPUT: {
					sInputFileName = argv[ i ];
					bInput = sal_True; // source file found
				}
				break;
				case STATE_OUTPUT: {
					sOutputFile = argv[ i ]; // the dest. file
				}
				break;
				case STATE_PRJ: {
					sPrj = ByteString( argv[ i ]);
//					sPrj.ToLowerAscii(); // the project
				}
				break;
				case STATE_ROOT: {
					sPrjRoot = ByteString( argv[ i ]); // path to project root
				}
				break;
				case STATE_MERGESRC: {
					sMergeSrc = ByteString( argv[ i ]);
					bMergeMode = sal_True; // activate merge mode, cause merge database found
				}
				break;
				case STATE_LANGUAGES: {
					Export::sLanguages = ByteString( argv[ i ]);
				}
				break;
			}
		}
	}

	if ( bInput ) {
		// command line is valid
		bEnableExport = sal_True;
		char *pReturn = new char[ sOutputFile.Len() + 1 ];
		strcpy( pReturn, sOutputFile.GetBuffer());  // #100211# - checked
		return pReturn;
	}

	// command line is not valid
	return NULL;
}
/*****************************************************************************/
int InitCfgExport( char *pOutput , char* pFilename )
/*****************************************************************************/
{
	// instanciate Export
	ByteString sOutput( pOutput );
	ByteString sFilename( pFilename );
    Export::InitLanguages();

	if ( bMergeMode )
		pParser = new CfgMerge( sMergeSrc, sOutputFile, sFilename );
  	else if ( sOutputFile.Len()) 
		pParser = new CfgExport( sOutputFile, sPrj, sActFileName );
	
	return 1;
}

/*****************************************************************************/
int EndCfgExport()
/*****************************************************************************/
{
	delete pParser;

	return 1;
}

void removeTempFile(){
    if( !sUsedTempFile.EqualsIgnoreCaseAscii( "" ) ){
        DirEntry aTempFile( sUsedTempFile );
        aTempFile.Kill();
    }
}
extern const char* getFilename()
{
	return sInputFileName.GetBuffer(); 
}
/*****************************************************************************/
extern FILE *GetCfgFile()
/*****************************************************************************/
{
	FILE *pFile = 0;
    // look for valid filename
	if ( sInputFileName.Len()) {
        if( Export::fileHasUTF8ByteOrderMarker( sInputFileName ) ){
            DirEntry aTempFile = Export::GetTempFile();
            DirEntry aSourceFile( String( sInputFileName , RTL_TEXTENCODING_ASCII_US ) );
            aSourceFile.CopyTo( aTempFile , FSYS_ACTION_COPYFILE );
            String sTempFile = aTempFile.GetFull();
            Export::RemoveUTF8ByteOrderMarkerFromFile( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ) );
            pFile = fopen( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ).GetBuffer(), "r" );
            sUsedTempFile = sTempFile;
        }else{
            // able to open file?
            pFile = fopen( sInputFileName.GetBuffer(), "r" );
            sUsedTempFile = String::CreateFromAscii("");
        }
		if ( !pFile ){
			fprintf( stderr, "Error: Could not open file %s\n",
				sInputFileName.GetBuffer());
            exit( -13 );
        }
		else {
			// this is a valid file which can be opened, so
			// create path to project root
			DirEntry aEntry( String( sInputFileName, RTL_TEXTENCODING_ASCII_US ));
			aEntry.ToAbs();
			sFullEntry= ByteString( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
			aEntry += DirEntry( String( "..", RTL_TEXTENCODING_ASCII_US ));
			aEntry += DirEntry( sPrjRoot );
			ByteString sPrjEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );

			// create file name, beginnig with project root
			// (e.g.: source\ui\src\menue.src)
//			printf("sFullEntry = %s\n",sFullEntry.GetBuffer());
            sActFileName = sFullEntry.Copy( sPrjEntry.Len() + 1 );
//            printf("sActFileName = %s\n",sActFileName.GetBuffer());    

			sActFileName.SearchAndReplaceAll( "/", "\\" );

			return pFile;
		}
	}
	// this means the file could not be opened
	return NULL;
}

/*****************************************************************************/
int WorkOnTokenSet( int nTyp, char *pTokenText )
/*****************************************************************************/
{
	pParser->Execute( nTyp, pTokenText );

	return 1;
}


/*****************************************************************************/
int SetError()
/*****************************************************************************/
{
	return 1;
}

/*****************************************************************************/
int GetError()
/*****************************************************************************/
{
	return 0;
}
}

//
// class CfgStackData
//

CfgStackData* CfgStack::Push( const ByteString &rTag, const ByteString &rId )
{ 
    CfgStackData *pD = new CfgStackData( rTag, rId ); 
    Insert( pD, LIST_APPEND ); 
    return pD; 
}
            
//
// class CfgStack
//

/*****************************************************************************/
CfgStack::~CfgStack()
/*****************************************************************************/
{
	for ( sal_uLong i = 0; i < Count(); i++ )
		delete GetObject( i );
}

/*****************************************************************************/
ByteString CfgStack::GetAccessPath( sal_uLong nPos )
/*****************************************************************************/
{
	if ( nPos == LIST_APPEND )
		nPos = Count() - 1;

	ByteString sReturn;
	for ( sal_uLong i = 0; i <= nPos; i++ ) {
		if ( i )
			sReturn += ".";
		sReturn += GetStackData( i )->GetIdentifier();
	}

	return sReturn;
}

/*****************************************************************************/
CfgStackData *CfgStack::GetStackData( sal_uLong nPos )
/*****************************************************************************/
{
	if ( nPos == LIST_APPEND )
		nPos = Count() - 1;

	return GetObject( nPos );
}

//
// class CfgParser
//

/*****************************************************************************/
CfgParser::CfgParser()
/*****************************************************************************/
				: pStackData( NULL ),
				bLocalize( sal_False )
{
}

/*****************************************************************************/
CfgParser::~CfgParser()
/*****************************************************************************/
{
}


/*****************************************************************************/
sal_Bool CfgParser::IsTokenClosed( const ByteString &rToken )
/*****************************************************************************/
{
	return rToken.GetChar( rToken.Len() - 2 ) == '/';
}

/*****************************************************************************/
void CfgParser::AddText(
	ByteString &rText,
	const ByteString &rIsoLang,
	const ByteString &rResTyp
)
/*****************************************************************************/
{
		sal_uInt16 nTextLen = 0;
		while ( rText.Len() != nTextLen ) {
			nTextLen = rText.Len();
			rText.SearchAndReplaceAll( "\n", " " );
			rText.SearchAndReplaceAll( "\r", " " );
			rText.SearchAndReplaceAll( "\t", " " );
			rText.SearchAndReplaceAll( "  ", " " );
		}
		pStackData->sResTyp = rResTyp;
        WorkOnText( rText, rIsoLang );

        pStackData->sText[ rIsoLang ] = rText;
}


/*****************************************************************************/
void CfgParser::WorkOnRessourceEnd()
/*****************************************************************************/
{
}

/*****************************************************************************/
int CfgParser::ExecuteAnalyzedToken( int nToken, char *pToken )
/*****************************************************************************/
{
	ByteString sToken( pToken );

	if ( sToken == " " || sToken == "\t" )
		sLastWhitespace += sToken;

	ByteString sTokenName;
	ByteString sTokenId;

	sal_Bool bOutput = sal_True;

	switch ( nToken ) {
		case CFG_TOKEN_PACKAGE:
		case CFG_TOKEN_COMPONENT:
		case CFG_TOKEN_TEMPLATE:
		case CFG_TOKEN_CONFIGNAME:
		case CFG_TOKEN_OORNAME:
		case CFG_TOKEN_OORVALUE:
		case CFG_TAG:
		case ANYTOKEN:
		case CFG_TEXT_START:
		{
			sTokenName = sToken.GetToken( 1, '<' ).GetToken( 0, '>' ).GetToken( 0, ' ' );

	  		if ( !IsTokenClosed( sToken )) {
				ByteString sSearch;
				switch ( nToken ) {
					case CFG_TOKEN_PACKAGE:
						sSearch = "package-id=";
					break;
					case CFG_TOKEN_COMPONENT:
						sSearch = "component-id=";
					break;
					case CFG_TOKEN_TEMPLATE:
						sSearch = "template-id=";
					break;
					case CFG_TOKEN_CONFIGNAME:
						sSearch = "cfg:name=";
					break;
					case CFG_TOKEN_OORNAME:
						sSearch = "oor:name=";
						bLocalize = sal_True;
					break;
					case CFG_TOKEN_OORVALUE:
						sSearch = "oor:value=";
					break;
					case CFG_TEXT_START: {
						if ( sCurrentResTyp != sTokenName ) {
							WorkOnRessourceEnd();
                            ByteString sCur;
                            for( unsigned int n = 0; n < aLanguages.size(); n++ ){
                                sCur = aLanguages[ n ];
                                pStackData->sText[ sCur ] = ByteString("");
                            }
                     	}
						sCurrentResTyp = sTokenName;

						ByteString sTemp = sToken.Copy( sToken.Search( "xml:lang=" ));
						sCurrentIsoLang = sTemp.GetToken( 1, '\"' ).GetToken( 0, '\"' );

						if ( sCurrentIsoLang == NO_TRANSLATE_ISO )
							bLocalize = sal_False;

						pStackData->sTextTag = sToken;

						sCurrentText = "";
					}
					break;
				}
				if ( sSearch.Len()) {
					ByteString sTemp = sToken.Copy( sToken.Search( sSearch ));
					sTokenId = sTemp.GetToken( 1, '\"' ).GetToken( 0, '\"' );
				}
				pStackData = aStack.Push( sTokenName, sTokenId );

				if ( sSearch == "cfg:name=" ) {
					ByteString sTemp( sToken );
					sTemp.ToUpperAscii();
					bLocalize = (( sTemp.Search( "CFG:TYPE=\"STRING\"" ) != STRING_NOTFOUND ) &&
						( sTemp.Search( "CFG:LOCALIZED=\"sal_True\"" ) != STRING_NOTFOUND ));
				}
			}
			else if ( sTokenName == "label" ) {
				if ( sCurrentResTyp != sTokenName ) {
					WorkOnRessourceEnd();
                    ByteString sCur;
                    for( unsigned int n = 0; n < aLanguages.size(); n++ ){
                        sCur = aLanguages[ n ];
                        pStackData->sText[ sCur ] = ByteString("");
                    }
        		}
				sCurrentResTyp = sTokenName;
			}
		}
		break;
		case CFG_CLOSETAG:
			sTokenName = sToken.GetToken( 1, '/' ).GetToken( 0, '>' ).GetToken( 0, ' ' );
		   	if ( aStack.GetStackData() && ( aStack.GetStackData()->GetTagType() == sTokenName )) {
				if ( ! sCurrentText.Len())
					WorkOnRessourceEnd();
				aStack.Pop();
				pStackData = aStack.GetStackData();
			}
			else {
				ByteString sError( "Missplaced close tag: " );
                ByteString sInFile(" in file ");
                sError += sToken;
                sError += sInFile;
                sError += sFullEntry;
				Error( sError );
                exit ( 13 );
			}
		break;

		case CFG_TEXTCHAR:
			sCurrentText += sToken;
			bOutput = sal_False;
		break;

		case CFG_TOKEN_NO_TRANSLATE:
			bLocalize = sal_False;
		break;
	}

	if ( sCurrentText.Len() && nToken != CFG_TEXTCHAR ) {
		AddText( sCurrentText, sCurrentIsoLang, sCurrentResTyp );
		Output( sCurrentText );
		sCurrentText = "";
		pStackData->sEndTextTag = sToken;
	}

	if ( bOutput )
		Output( sToken );

	if ( sToken != " " && sToken != "\t" )
		sLastWhitespace = "";

	return 1;
}

/*****************************************************************************/
void CfgExport::Output( const ByteString& rOutput )
/*****************************************************************************/
{
    // Dummy operation to suppress warnings caused by poor class design
    ByteString a( rOutput );
}

/*****************************************************************************/
int CfgParser::Execute( int nToken, char * pToken )
/*****************************************************************************/
{
	ByteString sToken( pToken );

	switch ( nToken ) {
		case CFG_TAG:
			if ( sToken.Search( "package-id=" ) != STRING_NOTFOUND )
				return ExecuteAnalyzedToken( CFG_TOKEN_PACKAGE, pToken );
			else if ( sToken.Search( "component-id=" ) != STRING_NOTFOUND )
				return ExecuteAnalyzedToken( CFG_TOKEN_COMPONENT, pToken );
			else if ( sToken.Search( "template-id=" ) != STRING_NOTFOUND )
				return ExecuteAnalyzedToken( CFG_TOKEN_TEMPLATE, pToken );
			else if ( sToken.Search( "cfg:name=" ) != STRING_NOTFOUND )
				return ExecuteAnalyzedToken( CFG_TOKEN_OORNAME, pToken );
			else if ( sToken.Search( "oor:name=" ) != STRING_NOTFOUND )
				return ExecuteAnalyzedToken( CFG_TOKEN_OORNAME, pToken );
			else if ( sToken.Search( "oor:value=" ) != STRING_NOTFOUND )
				return ExecuteAnalyzedToken( CFG_TOKEN_OORVALUE, pToken );
		break;
	}
	return ExecuteAnalyzedToken( nToken, pToken );
}


/*****************************************************************************/
void CfgParser::Error( const ByteString &rError )
/*****************************************************************************/
{
//	ByteString sError( rError );
//    sError.Append("Error: In file ");
//    sError.Append( sActFileName );
    yyerror(( char * ) rError.GetBuffer());
}


//
// class CfgOutputParser
//

/*****************************************************************************/
CfgOutputParser::CfgOutputParser( const ByteString &rOutputFile )
/*****************************************************************************/
{
	pOutputStream =
		new SvFileStream(
			String( rOutputFile, RTL_TEXTENCODING_ASCII_US ),
			STREAM_STD_WRITE | STREAM_TRUNC
		);
    pOutputStream->SetStreamCharSet( RTL_TEXTENCODING_UTF8 );

	if ( !pOutputStream->IsOpen()) {
		ByteString sError( "ERROR: Unable to open output file: " );
		sError += rOutputFile;
		Error( sError );
		delete pOutputStream;
		pOutputStream = NULL;
        exit( -13 );
	}
}

/*****************************************************************************/
CfgOutputParser::~CfgOutputParser()
/*****************************************************************************/
{
	if ( pOutputStream ) {
		pOutputStream->Close();
		delete pOutputStream;
	}
}

//
// class CfgExport
//

/*****************************************************************************/
CfgExport::CfgExport(
		const ByteString &rOutputFile,
		const ByteString &rProject,
		const ByteString &rFilePath
)
/*****************************************************************************/
				: CfgOutputParser( rOutputFile ),
				sPrj( rProject ),
				sPath( rFilePath )
{
    Export::InitLanguages( false );
    aLanguages = Export::GetLanguages();
}

/*****************************************************************************/
CfgExport::~CfgExport()
/*****************************************************************************/
{
}

/*****************************************************************************/
void CfgExport::WorkOnRessourceEnd()
/*****************************************************************************/
{
	if ( pOutputStream && bLocalize ) {
	if (( pStackData->sText[ ByteString("en-US") ].Len()
        ) ||
			( bForce &&
				( pStackData->sText[ ByteString("de") ].Len() ||
                    pStackData->sText[ ByteString("en-US") ].Len() )))
		{
            ByteString sFallback = pStackData->sText[ ByteString("en-US") ];

            //if ( pStackData->sText[ ByteString("en-US") ].Len())
			//	sFallback = pStackData->sText[ ByteString("en-US") ];

			ByteString sLocalId = pStackData->sIdentifier;
			ByteString sGroupId;
			if ( aStack.Count() == 1 ) {
				sGroupId = sLocalId;
				sLocalId = "";
			}
			else {
				sGroupId = aStack.GetAccessPath( aStack.Count() - 2 );
			}

			ByteString sTimeStamp( Export::GetTimeStamp());

            ByteString sCur;
            for( unsigned int n = 0; n < aLanguages.size(); n++ ){
                sCur = aLanguages[ n ];

					ByteString sText = pStackData->sText[ sCur ];
					if ( !sText.Len())
						sText = sFallback;

                    Export::UnquotHTML( sText );

					ByteString sOutput( sPrj ); sOutput += "\t";
					sOutput += sPath;
					sOutput += "\t0\t";
					sOutput += pStackData->sResTyp; sOutput += "\t";
					sOutput += sGroupId; sOutput += "\t";
					sOutput += sLocalId; sOutput += "\t\t\t0\t";
                    sOutput += sCur;
					sOutput += "\t";

                    sOutput += sText; sOutput += "\t\t\t\t";
					sOutput += sTimeStamp;

                    //if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( sPrj ) ) )
					pOutputStream->WriteLine( sOutput );
			}
		}
	}
}

/*****************************************************************************/
void CfgExport::WorkOnText(
	ByteString &rText,
    const ByteString &rIsoLang
)
/*****************************************************************************/
{
    if( rIsoLang.Len() ) Export::UnquotHTML( rText );
}


//
// class CfgMerge
//

/*****************************************************************************/
CfgMerge::CfgMerge(
	const ByteString &rMergeSource, const ByteString &rOutputFile,
	ByteString &rFilename )
/*****************************************************************************/
				: CfgOutputParser( rOutputFile ),
				pMergeDataFile( NULL ),
				pResData( NULL ),
				bGerman( sal_False ),
				sFilename( rFilename ),
				bEnglish( sal_False )
{
    if ( rMergeSource.Len()){
		pMergeDataFile = new MergeDataFile(
		rMergeSource, sInputFileName  , bErrorLog, RTL_TEXTENCODING_MS_1252, true ); 
        if( Export::sLanguages.EqualsIgnoreCaseAscii("ALL") ){
            Export::SetLanguages( pMergeDataFile->GetLanguages() );
            aLanguages = pMergeDataFile->GetLanguages();
        }
        else aLanguages = Export::GetLanguages();
    }else
        aLanguages = Export::GetLanguages();
}

/*****************************************************************************/
CfgMerge::~CfgMerge()
/*****************************************************************************/
{
	delete pMergeDataFile;
	delete pResData;
}

/*****************************************************************************/
void CfgMerge::WorkOnText(
	ByteString &rText,
    const ByteString& nLangIndex
)
/*****************************************************************************/
{

    if ( pMergeDataFile && bLocalize ) {
		if ( !pResData ) {
			ByteString sLocalId = pStackData->sIdentifier;
			ByteString sGroupId;
			if ( aStack.Count() == 1 ) {
				sGroupId = sLocalId;
				sLocalId = "";
			}
			else {
				sGroupId = aStack.GetAccessPath( aStack.Count() - 2 );
			}

			ByteString sPlatform( "" );

			pResData = new ResData( sPlatform, sGroupId , sFilename );
			pResData->sId = sLocalId;
			pResData->sResTyp = pStackData->sResTyp;
		}

        //if ( nLangIndex.EqualsIgnoreCaseAscii("de") )
		//	bGerman = sal_True;
		if (( nLangIndex.EqualsIgnoreCaseAscii("en-US") ))
			bEnglish = sal_True;

		PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrysCaseSensitive( pResData );
		if ( pEntrys ) {
			ByteString sContent;
            pEntrys->GetText( sContent, STRING_TYP_TEXT, nLangIndex );
            
			if ( Export::isAllowed( nLangIndex ) &&
				( sContent != "-" ) && ( sContent.Len()))
			{
#ifdef MERGE_SOURCE_LANGUAGES 
                    if( nLangIndex.EqualsIgnoreCaseAscii("de") || nLangIndex.EqualsIgnoreCaseAscii("en-US") )
                        rText = sContent;
#endif
                Export::QuotHTML( rText );
			}
		}
	}
}

/*****************************************************************************/
void CfgMerge::Output( const ByteString& rOutput )
/*****************************************************************************/
{
	if ( pOutputStream )
		pOutputStream->Write( rOutput.GetBuffer(), rOutput.Len());
}

sal_uLong CfgStack::Push( CfgStackData *pStackData )
{ 
    Insert( pStackData, LIST_APPEND ); 
    return Count() - 1; 
}

/*****************************************************************************/
void CfgMerge::WorkOnRessourceEnd()
/*****************************************************************************/
{

	if ( pMergeDataFile && pResData && bLocalize && (( bEnglish ) || bForce )) {
		PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrysCaseSensitive( pResData );
		if ( pEntrys ) {
            ByteString sCur;

            for( unsigned int n = 0; n < aLanguages.size(); n++ ){
                sCur = aLanguages[ n ];

				ByteString sContent;
                pEntrys->GetText( sContent, STRING_TYP_TEXT, sCur , sal_True );
                if ( 
                    // (!sCur.EqualsIgnoreCaseAscii("de") )    &&
					( !sCur.EqualsIgnoreCaseAscii("en-US") ) &&

					( sContent != "-" ) && ( sContent.Len()))
				{
                    
					ByteString sText = sContent;
                    Export::QuotHTML( sText );

					ByteString sAdditionalLine( "\t" );

					ByteString sTextTag = pStackData->sTextTag;
					ByteString sTemp = sTextTag.Copy( sTextTag.Search( "xml:lang=" ));

					ByteString sSearch = sTemp.GetToken( 0, '\"' );
					sSearch += "\"";
					sSearch += sTemp.GetToken( 1, '\"' );
					sSearch += "\"";

					ByteString sReplace = sTemp.GetToken( 0, '\"' );
					sReplace += "\"";
                    sReplace += sCur;
					sReplace += "\"";

					sTextTag.SearchAndReplace( sSearch, sReplace );

					sAdditionalLine += sTextTag;
					sAdditionalLine += sText;
					sAdditionalLine += pStackData->sEndTextTag;

					sAdditionalLine += "\n";
					sAdditionalLine += sLastWhitespace;

					Output( sAdditionalLine );
				}
			}
		}
	}
	delete pResData;
	pResData = NULL;
	bGerman = sal_False;
	bEnglish = sal_False;
}
