/**************************************************************
 *
 * 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_xmloff.hxx"

#ifndef _XMLOFF_XMLEVENTIMPORTHELPER_HXX
#include "XMLEventImportHelper.hxx"
#endif
#include <tools/debug.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include "xmloff/xmlerror.hxx"

using ::rtl::OUString;
using ::com::sun::star::xml::sax::XAttributeList;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;

XMLEventImportHelper::XMLEventImportHelper() :
	aFactoryMap(),
	pEventNameMap(new NameMap()),
	aEventNameMapList()
{
}


XMLEventImportHelper::~XMLEventImportHelper()
{
	// delete factories
	FactoryMap::iterator aEnd = aFactoryMap.end();
	for(FactoryMap::iterator aIter = aFactoryMap.begin();
		aIter != aEnd;
		aIter++ )
	{
		delete aIter->second;
	}
	aFactoryMap.clear();

	// delete name map
	delete pEventNameMap;
}

void XMLEventImportHelper::RegisterFactory(
	const OUString& rLanguage,
	XMLEventContextFactory* pFactory )
{
	DBG_ASSERT(pFactory != NULL, "I need a factory.");
	if (NULL != pFactory)
	{
		aFactoryMap[rLanguage] = pFactory;
	}
}

void XMLEventImportHelper::AddTranslationTable(
	const XMLEventNameTranslation* pTransTable )
{
	if (NULL != pTransTable)
	{
		// put translation table into map
		for(const XMLEventNameTranslation* pTrans = pTransTable;
			pTrans->sAPIName != NULL;
			pTrans++)
		{
			XMLEventName aName( pTrans->nPrefix, pTrans->sXMLName );

			// check for conflicting entries
			DBG_ASSERT(pEventNameMap->find(aName) == pEventNameMap->end(),
					   "conflicting event translations");

			// assign new translation
			(*pEventNameMap)[aName] =
				OUString::createFromAscii(pTrans->sAPIName);
		}
	}
	// else? ignore!
}

void XMLEventImportHelper::PushTranslationTable()
{
	// save old map and install new one
	aEventNameMapList.push_back(pEventNameMap);
	pEventNameMap = new NameMap();
}

void XMLEventImportHelper::PopTranslationTable()
{
	DBG_ASSERT(aEventNameMapList.size() > 0,
			   "no translation tables left to pop");
	if ( !aEventNameMapList.empty() )
	{
		// delete current and install old map
		delete pEventNameMap;
		pEventNameMap = aEventNameMapList.back();
		aEventNameMapList.pop_back();
	}
}


SvXMLImportContext* XMLEventImportHelper::CreateContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	const Reference<XAttributeList> & xAttrList,
	XMLEventsImportContext* rEvents,
	const OUString& rXmlEventName,
	const OUString& rLanguage)
{
	SvXMLImportContext* pContext = NULL;

	// translate event name form xml to api
	OUString sMacroName;
	sal_uInt16 nMacroPrefix =
		rImport.GetNamespaceMap().GetKeyByAttrName( rXmlEventName,
														&sMacroName );
	XMLEventName aEventName( nMacroPrefix, sMacroName );
	NameMap::iterator aNameIter = pEventNameMap->find(aEventName);
	if (aNameIter != pEventNameMap->end())
	{
		OUString aScriptLanguage;
		sal_uInt16 nScriptPrefix = rImport.GetNamespaceMap().
				GetKeyByAttrName( rLanguage, &aScriptLanguage );
		if( XML_NAMESPACE_OOO != nScriptPrefix )
			aScriptLanguage = rLanguage ;

		// check for factory
		FactoryMap::iterator aFactoryIterator =
			aFactoryMap.find(aScriptLanguage);
		if (aFactoryIterator != aFactoryMap.end())
		{
			// delegate to factory
			pContext = aFactoryIterator->second->CreateContext(
				rImport, nPrefix, rLocalName, xAttrList,
				rEvents, aNameIter->second, aScriptLanguage);
		}
	}

	// default context (if no context was created above)
	if( NULL == pContext )
	{
		pContext = new SvXMLImportContext(rImport, nPrefix, rLocalName);

        Sequence<OUString> aMsgParams(2);

        aMsgParams[0] = rXmlEventName;
        aMsgParams[1] = rLanguage;

        rImport.SetError(XMLERROR_FLAG_ERROR | XMLERROR_ILLEGAL_EVENT,
                         aMsgParams);

	}

	return pContext;
}
