/**************************************************************
 *
 * 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 <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <xmloff/xmlimp.hxx>
#include <xmloff/xmltoken.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/nmspmap.hxx>
#include <xmloff/XMLBase64ImportContext.hxx>
#include "XMLReplacementImageContext.hxx"

using ::rtl::OUString;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::makeAny;
using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::beans;

TYPEINIT1( XMLReplacementImageContext, SvXMLImportContext );

XMLReplacementImageContext::XMLReplacementImageContext(
		SvXMLImport& rImport,
		sal_uInt16 nPrfx, const OUString& rLName,
		const Reference< XAttributeList > & rAttrList,
		const Reference< XPropertySet > & rPropSet ) :
	SvXMLImportContext( rImport, nPrfx, rLName ),
	m_xPropSet( rPropSet ),
	m_sGraphicURL(RTL_CONSTASCII_USTRINGPARAM("GraphicURL"))
{
	UniReference < XMLTextImportHelper > xTxtImport =
		GetImport().GetTextImport();
	const SvXMLTokenMap& rTokenMap =
		xTxtImport->GetTextFrameAttrTokenMap();

	sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
	for( sal_Int16 i=0; i < nAttrCount; i++ )
	{
		const OUString& rAttrName = rAttrList->getNameByIndex( i );
		const OUString& rValue = rAttrList->getValueByIndex( i );

		OUString aLocalName;
		sal_uInt16 nPrefix =
			GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
															&aLocalName );
		switch( rTokenMap.Get( nPrefix, aLocalName ) )
		{
		case XML_TOK_TEXT_FRAME_HREF:
			m_sHRef = rValue;
			break;
		}
	}
}

XMLReplacementImageContext::~XMLReplacementImageContext()
{
}

void XMLReplacementImageContext::EndElement()
{
	OSL_ENSURE( m_sHRef.getLength() > 0 || m_xBase64Stream.is(),
				"neither URL nor base64 image data given" );
	UniReference < XMLTextImportHelper > xTxtImport =
		GetImport().GetTextImport();
	OUString sHRef;
	if( m_sHRef.getLength() )
	{
		sal_Bool bForceLoad = xTxtImport->IsInsertMode() ||
							  xTxtImport->IsBlockMode() ||
							  xTxtImport->IsStylesOnlyMode() ||
							  xTxtImport->IsOrganizerMode();
		sHRef = GetImport().ResolveGraphicObjectURL( m_sHRef, !bForceLoad );
	}
	else if( m_xBase64Stream.is() )
	{
		sHRef = GetImport().ResolveGraphicObjectURLFromBase64( m_xBase64Stream );
		m_xBase64Stream = 0;
	}

	Reference < XPropertySetInfo > xPropSetInfo =
		m_xPropSet->getPropertySetInfo();
	if( xPropSetInfo->hasPropertyByName( m_sGraphicURL ) )
		m_xPropSet->setPropertyValue( m_sGraphicURL, makeAny( sHRef ) );
}

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

	if( XML_NAMESPACE_OFFICE == nPrefix &&
		IsXMLToken( rLocalName, ::xmloff::token::XML_BINARY_DATA ) &&
		!m_xBase64Stream.is() )
	{
		m_xBase64Stream = GetImport().GetStreamForGraphicObjectURLFromBase64();
		if( m_xBase64Stream.is() )
			pContext = new XMLBase64ImportContext( GetImport(), nPrefix,
													rLocalName, xAttrList,
													m_xBase64Stream );
	}

	if( !pContext )
		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );

	return pContext;
}
