/**************************************************************
 *
 * 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 "XMLAutoTextEventImport.hxx"
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/xml/sax/XAttributeList.hpp>
#include <com/sun/star/document/XEventsSupplier.hpp>
#include <com/sun/star/uno/XInterface.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include "XMLAutoTextContainerEventImport.hxx"
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include <tools/debug.hxx>

using namespace ::com::sun::star;

using ::rtl::OUString;
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Type;
using ::com::sun::star::uno::XInterface;
using ::com::sun::star::uno::RuntimeException;
using ::com::sun::star::uno::Exception;
using ::com::sun::star::xml::sax::XAttributeList;
using ::com::sun::star::document::XEventsSupplier;
using ::com::sun::star::container::XNameReplace;
using ::com::sun::star::lang::XMultiServiceFactory;
using ::xmloff::token::IsXMLToken;
using ::xmloff::token::XML_AUTO_TEXT_EVENTS;

const sal_Char sAPI_AutoText[] = "com.sun.star.text.AutoTextContainer";


// #110680#
XMLAutoTextEventImport::XMLAutoTextEventImport(
	const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory) throw()
:	SvXMLImport(xServiceFactory)
{
}

XMLAutoTextEventImport::~XMLAutoTextEventImport() throw()
{
}

void XMLAutoTextEventImport::initialize(
	const Sequence<Any> & rArguments )
		throw(Exception, RuntimeException)
{
	// The events may come as either an XNameReplace or XEventsSupplier.

	const sal_Int32 nLength = rArguments.getLength();
	for( sal_Int32 i = 0; i < nLength; i++ )
	{
		const Type& rType = rArguments[i].getValueType();
		if ( rType == ::getCppuType( (Reference<XEventsSupplier>*)NULL ) )
		{
			Reference<XEventsSupplier> xSupplier;
			rArguments[i] >>= xSupplier;
			DBG_ASSERT(xSupplier.is(), "need XEventsSupplier or XNameReplace");

			xEvents = xSupplier->getEvents();
		}
		else if (rType == ::getCppuType( (Reference<XNameReplace>*)NULL ) )
		{
			rArguments[i] >>= xEvents;
			DBG_ASSERT(xEvents.is(), "need XEventsSupplier or XNameReplace");
		}
	}

	// call parent
	SvXMLImport::initialize(rArguments);
}



SvXMLImportContext* XMLAutoTextEventImport::CreateContext(
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	const Reference<XAttributeList > & xAttrList )
{
	if ( xEvents.is() && (XML_NAMESPACE_OOO == nPrefix) &&
		 IsXMLToken( rLocalName, XML_AUTO_TEXT_EVENTS) )
	{
		return new XMLAutoTextContainerEventImport(
			*this, nPrefix, rLocalName, xEvents);
	}
	else
	{
		return SvXMLImport::CreateContext(nPrefix, rLocalName, xAttrList);
	}
}


Sequence< OUString > SAL_CALL
	XMLAutoTextEventImport_getSupportedServiceNames()
		throw()
{
	Sequence< OUString > aSeq( 1 );
	aSeq[0] = XMLAutoTextEventImport_getImplementationName();
	return aSeq;
}

OUString SAL_CALL XMLAutoTextEventImport_getImplementationName() throw()
{
	return OUString( RTL_CONSTASCII_USTRINGPARAM(
		"com.sun.star.comp.Writer.XMLOasisAutotextEventsImporter" ) );
}

Reference< XInterface > SAL_CALL XMLAutoTextEventImport_createInstance(
		const Reference< XMultiServiceFactory > & rSMgr)
	throw( Exception )
{
	// #110680#
	// return (cppu::OWeakObject*)new XMLAutoTextEventImport;
	return (cppu::OWeakObject*)new XMLAutoTextEventImport(rSMgr);
}
