/**************************************************************
 *
 * 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 <tools/debug.hxx>
#ifndef _COM_SUN_STAR_DOCUMENT_XEVENTSSUPPLIER_HPP
#include <com/sun/star/document/XEventsSupplier.hpp>
#endif
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include "XMLTextPropertySetContext.hxx"
#include <xmloff/xmlimp.hxx>
#include <xmloff/XMLEventsImportContext.hxx>
#include "XMLShapePropertySetContext.hxx"
#include "XMLTextColumnsContext.hxx"
#include "XMLBackgroundImageContext.hxx"
#ifndef _XMLOFF_TXTPRMAP_HXX
#include <xmloff/txtprmap.hxx>
#endif

#ifndef _XMLOFF_XMLTEXTSHAPESTYLECONTEXT_HXX
#include <xmloff/XMLTextShapeStyleContext.hxx>
#endif

using ::rtl::OUString;
using ::rtl::OUStringBuffer;

using namespace ::com::sun::star::document;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::beans;
using namespace ::xmloff::token;

class XMLTextShapePropertySetContext_Impl : public XMLShapePropertySetContext
{
public:
	XMLTextShapePropertySetContext_Impl( SvXMLImport& rImport, sal_uInt16 nPrfx,
		const OUString& rLName,
		const Reference< XAttributeList >& xAttrList,
				 sal_uInt32 nFamily,
		::std::vector< XMLPropertyState > &rProps,
		const UniReference < SvXMLImportPropertyMapper > &rMap );

	virtual ~XMLTextShapePropertySetContext_Impl();

	using SvXMLPropertySetContext::CreateChildContext;
	virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
		const OUString& rLocalName,
		const Reference< XAttributeList >& xAttrList,
		::std::vector< XMLPropertyState > &rProperties,
		const XMLPropertyState& rProp);
};

XMLTextShapePropertySetContext_Impl::XMLTextShapePropertySetContext_Impl(
				 SvXMLImport& rImport, sal_uInt16 nPrfx,
				 const OUString& rLName,
				 const Reference< XAttributeList > & xAttrList,
				 sal_uInt32 nFamily,
				 ::std::vector< XMLPropertyState > &rProps,
				 const UniReference < SvXMLImportPropertyMapper > &rMap ) :
	XMLShapePropertySetContext( rImport, nPrfx, rLName, xAttrList, nFamily,
								rProps, rMap )
{
}

XMLTextShapePropertySetContext_Impl::~XMLTextShapePropertySetContext_Impl()
{
}

SvXMLImportContext *XMLTextShapePropertySetContext_Impl::CreateChildContext(
				   sal_uInt16 nPrefix,
				   const OUString& rLocalName,
				   const Reference< XAttributeList > & xAttrList,
				   ::std::vector< XMLPropertyState > &rProperties,
				   const XMLPropertyState& rProp )
{
	SvXMLImportContext *pContext = 0;

	switch( mxMapper->getPropertySetMapper()
					->GetEntryContextId( rProp.mnIndex ) )
	{
	case CTF_TEXTCOLUMNS:
		pContext = new XMLTextColumnsContext( GetImport(), nPrefix,
												   rLocalName, xAttrList, rProp,
												   rProperties );
		break;

	case CTF_BACKGROUND_URL:
		DBG_ASSERT( rProp.mnIndex >= 3 &&
					CTF_BACKGROUND_TRANSPARENCY ==
						mxMapper->getPropertySetMapper()
						->GetEntryContextId( rProp.mnIndex-3 ) &&
					CTF_BACKGROUND_POS == mxMapper->getPropertySetMapper()
						->GetEntryContextId( rProp.mnIndex-2 ) &&
					CTF_BACKGROUND_FILTER == mxMapper->getPropertySetMapper()
						->GetEntryContextId( rProp.mnIndex-1 ),
					"invalid property map!");
		pContext =
			new XMLBackgroundImageContext( GetImport(), nPrefix,
										   rLocalName, xAttrList,
										   rProp,
										   rProp.mnIndex-2,
										   rProp.mnIndex-1,
										   rProp.mnIndex-3,
										   rProperties );
		break;
	}

	if( !pContext )
		pContext = XMLShapePropertySetContext::CreateChildContext(
						nPrefix, rLocalName, xAttrList, rProperties, rProp );

	return pContext;
}

//-----------------------------------------------------------------------------

void XMLTextShapeStyleContext::SetAttribute( sal_uInt16 nPrefixKey,
										const OUString& rLocalName,
										const OUString& rValue )
{
	if( XML_NAMESPACE_STYLE == nPrefixKey &&
		IsXMLToken( rLocalName, XML_AUTO_UPDATE ) )
	{
		if( IsXMLToken( rValue, XML_TRUE ) )
			bAutoUpdate = sal_True;
	}
	else
	{
		XMLShapeStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
	}
}

TYPEINIT1( XMLTextShapeStyleContext, XMLShapeStyleContext );

XMLTextShapeStyleContext::XMLTextShapeStyleContext( SvXMLImport& rImport,
		sal_uInt16 nPrfx, const OUString& rLName,
		const Reference< XAttributeList > & xAttrList,
		SvXMLStylesContext& rStyles, sal_uInt16 nFamily,
		sal_Bool /*bDefaultStyle*/ ) :
	XMLShapeStyleContext( rImport, nPrfx, rLName, xAttrList, rStyles,
						  nFamily ),
	sIsAutoUpdate( RTL_CONSTASCII_USTRINGPARAM( "IsAutoUpdate" ) ),
	bAutoUpdate( sal_False )
{
}

XMLTextShapeStyleContext::~XMLTextShapeStyleContext()
{
}

SvXMLImportContext *XMLTextShapeStyleContext::CreateChildContext(
		sal_uInt16 nPrefix,
		const OUString& rLocalName,
		const Reference< XAttributeList > & xAttrList )
{
	SvXMLImportContext *pContext = 0;

	if( XML_NAMESPACE_STYLE == nPrefix )
	{
		sal_uInt32 nFamily = 0;
		if( IsXMLToken( rLocalName, XML_TEXT_PROPERTIES ) )
			nFamily = XML_TYPE_PROP_TEXT;
		else if( IsXMLToken( rLocalName, XML_PARAGRAPH_PROPERTIES ) )
			nFamily = XML_TYPE_PROP_PARAGRAPH;
		else if( IsXMLToken( rLocalName, XML_GRAPHIC_PROPERTIES ) )
			nFamily = XML_TYPE_PROP_GRAPHIC;
		if( nFamily )
		{
			UniReference < SvXMLImportPropertyMapper > xImpPrMap =
				GetStyles()->GetImportPropertyMapper( GetFamily() );
			if( xImpPrMap.is() )
			{
				pContext = new XMLTextShapePropertySetContext_Impl(
						GetImport(), nPrefix, rLocalName, xAttrList, nFamily,
						GetProperties(), xImpPrMap );
			}
		}
	}
	else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
			  IsXMLToken( rLocalName, XML_EVENT_LISTENERS ) )
	{
		// create and remember events import context
		// (for delayed processing of events)
		pContext = new XMLEventsImportContext( GetImport(), nPrefix,
												   rLocalName);
		xEventContext = pContext;
	}

	if( !pContext )
		pContext = XMLShapeStyleContext::CreateChildContext( nPrefix, rLocalName,
														  xAttrList );

	return pContext;
}

void XMLTextShapeStyleContext::CreateAndInsert( sal_Bool bOverwrite )
{
	XMLShapeStyleContext::CreateAndInsert( bOverwrite );
	Reference < XStyle > xStyle = GetStyle();
	if( !xStyle.is() || !(bOverwrite || IsNew()) )
		return;

	Reference < XPropertySet > xPropSet( xStyle, UNO_QUERY );
	Reference< XPropertySetInfo > xPropSetInfo =
				xPropSet->getPropertySetInfo();
	if( xPropSetInfo->hasPropertyByName( sIsAutoUpdate ) )
	{
		Any aAny;
		sal_Bool bTmp = bAutoUpdate;
		aAny.setValue( &bTmp, ::getBooleanCppuType() );
		xPropSet->setPropertyValue( sIsAutoUpdate, aAny );
	}

	// tell the style about it's events (if applicable)
	if( xEventContext.Is() )
	{
		// set event suppplier and release reference to context
		Reference<XEventsSupplier> xEventsSupplier(xStyle, UNO_QUERY);
		((XMLEventsImportContext *)&xEventContext)->SetEvents(xEventsSupplier);
		xEventContext = 0;
	}
}


void XMLTextShapeStyleContext::Finish( sal_Bool bOverwrite )
{
	XMLPropStyleContext::Finish( bOverwrite );
}

/* vim: set noet sw=4 ts=4: */
