/**************************************************************
 *
 * 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"
#include "XMLStarBasicContextFactory.hxx"
#include <xmloff/XMLEventsImportContext.hxx>
#include <tools/debug.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>


using namespace ::xmloff::token;

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


XMLStarBasicContextFactory::XMLStarBasicContextFactory() :
	sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType")),
	sLibrary(RTL_CONSTASCII_USTRINGPARAM("Library")),
	sMacroName(RTL_CONSTASCII_USTRINGPARAM("MacroName")),
	sStarBasic(RTL_CONSTASCII_USTRINGPARAM("StarBasic"))
{
}

XMLStarBasicContextFactory::~XMLStarBasicContextFactory()
{
}

SvXMLImportContext* XMLStarBasicContextFactory::CreateContext(
	SvXMLImport& rImport,
	sal_uInt16 p_nPrefix,
	const OUString& rLocalName,
	const Reference<XAttributeList> & xAttrList,
	XMLEventsImportContext* rEvents,
	const OUString& rApiEventName,
	const OUString& /*rApiLanguage*/)
{
	OUString sLibraryVal;
	OUString sMacroNameVal;

	sal_Int16 nCount = xAttrList->getLength();
	for(sal_Int16 nAttr = 0; nAttr < nCount; nAttr++)
	{
		OUString sLocalName;
		sal_uInt16 nPrefix = rImport.GetNamespaceMap().
			GetKeyByAttrName( xAttrList->getNameByIndex(nAttr), &sLocalName );

		if (XML_NAMESPACE_SCRIPT == nPrefix)
		{
//			if (IsXMLToken(sLocalName, XML_LIBRARY))
//			{
//				sLibraryVal = xAttrList->getValueByIndex(nAttr);
//			}
//			if (IsXMLToken(sLocalName, XML_LOCATION))
//			{
//				sLibraryVal = xAttrList->getValueByIndex(nAttr);
//                if ( IsXMLToken( sLibraryVal, XML_APPLICATION ) )
//                    sLibraryVal =
//                        OUString(RTL_CONSTASCII_USTRINGPARAM("StarOffice"));
//			}
//			else
			if (IsXMLToken(sLocalName, XML_MACRO_NAME))
			{
				sMacroNameVal = xAttrList->getValueByIndex(nAttr);
			}
			// else: ingore
		}
		// else: ignore
	}

	const OUString& rApp = GetXMLToken( XML_APPLICATION );
	const OUString& rDoc = GetXMLToken( XML_DOCUMENT );
	if( sMacroNameVal.getLength() > rApp.getLength()+1 &&
		sMacroNameVal.copy(0,rApp.getLength()).equalsIgnoreAsciiCase( rApp ) &&
		':' == sMacroNameVal[rApp.getLength()] )
	{
		sLibraryVal = OUString(RTL_CONSTASCII_USTRINGPARAM("StarOffice"));
		sMacroNameVal = sMacroNameVal.copy( rApp.getLength()+1 );
	}
	else if( sMacroNameVal.getLength() > rDoc.getLength()+1 &&
		sMacroNameVal.copy(0,rDoc.getLength()).equalsIgnoreAsciiCase( rDoc ) &&
		':' == sMacroNameVal[rDoc.getLength()] )
	{
		sLibraryVal = rDoc;
		sMacroNameVal = sMacroNameVal.copy( rDoc.getLength()+1 );
	}

	Sequence<PropertyValue> aValues(3);

	// EventType
	aValues[0].Name = sEventType;
	aValues[0].Value <<= sStarBasic;

	// library name
	aValues[1].Name = sLibrary;
	aValues[1].Value <<= sLibraryVal;

	// macro name
	aValues[2].Name = sMacroName;
	aValues[2].Value <<= sMacroNameVal;

	// add values for event now
	rEvents->AddEventValues(rApiEventName, aValues);

	// return dummy context
	return new SvXMLImportContext(rImport, p_nPrefix, rLocalName);
}
