/**************************************************************
 *
 * 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>
#include "XMLTextPropertySetContext.hxx"
#include "XMLTextColumnsContext.hxx"
#include "XMLBackgroundImageContext.hxx"
#include "XMLSectionFootnoteConfigImport.hxx"

#ifndef _XMLOFF_TXTPRMAP_HXX
#include <xmloff/txtprmap.hxx>
#endif
#include "xmltabi.hxx"
#ifndef _XMLOFF_TXTDROPI_HXX
#include "txtdropi.hxx"
#endif

using ::rtl::OUString;

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

XMLTextPropertySetContext::XMLTextPropertySetContext(
				 SvXMLImport& rImport, sal_uInt16 nPrfx,
				 const OUString& rLName,
				 const Reference< xml::sax::XAttributeList > & xAttrList,
				 sal_uInt32 nFamily,
				 ::std::vector< XMLPropertyState > &rProps,
				 const UniReference < SvXMLImportPropertyMapper > &rMap,
				 OUString& rDCTextStyleName ) :
	SvXMLPropertySetContext( rImport, nPrfx, rLName, xAttrList, nFamily,
							 rProps, rMap ),
	rDropCapTextStyleName( rDCTextStyleName )
{
}

XMLTextPropertySetContext::~XMLTextPropertySetContext()
{
}

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

	switch( mxMapper->getPropertySetMapper()
					->GetEntryContextId( rProp.mnIndex ) )
	{
	case CTF_TABSTOP:
		pContext = new SvxXMLTabStopImportContext( GetImport(), nPrefix,
												   rLocalName, rProp,
												   rProperties );
		break;
	case CTF_TEXTCOLUMNS:
#ifndef SVX_LIGHT
		pContext = new XMLTextColumnsContext( GetImport(), nPrefix,
												   rLocalName, xAttrList, rProp,
												   rProperties );
#else
		// create default context to skip content
		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
#endif // #ifndef SVX_LIGHT
		break;

	case CTF_DROPCAPFORMAT:
		{
			DBG_ASSERT( rProp.mnIndex >= 2 &&
						CTF_DROPCAPWHOLEWORD == mxMapper->getPropertySetMapper()
							->GetEntryContextId( rProp.mnIndex-2 ),
						"invalid property map!");
			XMLTextDropCapImportContext *pDCContext =
				new XMLTextDropCapImportContext( GetImport(), nPrefix,
														rLocalName, xAttrList,
														rProp,
														rProp.mnIndex-2,
														rProperties );
			rDropCapTextStyleName = pDCContext->GetStyleName();
		pContext = pDCContext;
		}
		break;

	case CTF_BACKGROUND_URL:
	{
		DBG_ASSERT( rProp.mnIndex >= 2 &&
					CTF_BACKGROUND_POS == mxMapper->getPropertySetMapper()
						->GetEntryContextId( rProp.mnIndex-2 ) &&
					CTF_BACKGROUND_FILTER == mxMapper->getPropertySetMapper()
						->GetEntryContextId( rProp.mnIndex-1 ),
					"invalid property map!");

		// #99657# Transparency might be there as well... but doesn't have
		// to. Thus, this is checked with an if, rather than with an assertion.
		sal_Int32 nTranspIndex = -1;
		if( (rProp.mnIndex >= 3) &&
			( CTF_BACKGROUND_TRANSPARENCY ==
			  mxMapper->getPropertySetMapper()->GetEntryContextId(
				rProp.mnIndex-3 ) ) )
			nTranspIndex = rProp.mnIndex-3;

		pContext =
			new XMLBackgroundImageContext( GetImport(), nPrefix,
										   rLocalName, xAttrList,
										   rProp,
										   rProp.mnIndex-2,
										   rProp.mnIndex-1,
										   nTranspIndex,
										   rProperties );
	}
	break;
#ifndef SVX_LIGHT
	case CTF_SECTION_FOOTNOTE_END:
	case CTF_SECTION_ENDNOTE_END:
		pContext = new XMLSectionFootnoteConfigImport(
			GetImport(), nPrefix, rLocalName, rProperties,
			mxMapper->getPropertySetMapper());
		break;
#endif // #ifndef SVX_LIGHT
	}

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

	return pContext;
}

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