/**************************************************************
 *
 * 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 <xmloff/xmlimp.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmluconv.hxx>
#include "XMLTextFrameContext.hxx"
#include "XMLTextFrameHyperlinkContext.hxx"

// OD 2004-04-21 #i26791#
#include <txtparaimphint.hxx>

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

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

TYPEINIT1( XMLTextFrameHyperlinkContext, SvXMLImportContext );

XMLTextFrameHyperlinkContext::XMLTextFrameHyperlinkContext(
		SvXMLImport& rImport,
		sal_uInt16 nPrfx, const OUString& rLName,
		const Reference< XAttributeList > & xAttrList,
		TextContentAnchorType eATyp ) :
	SvXMLImportContext( rImport, nPrfx, rLName ),
	eDefaultAnchorType( eATyp ),
	bMap( sal_False )
{
	OUString sShow;
	const SvXMLTokenMap& rTokenMap =
		GetImport().GetTextImport()->GetTextHyperlinkAttrTokenMap();

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

		OUString aLocalName;
		sal_uInt16 nPrefix =
			GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
															&aLocalName );
		switch( rTokenMap.Get( nPrefix, aLocalName ) )
		{
		case XML_TOK_TEXT_HYPERLINK_HREF:
			sHRef = GetImport().GetAbsoluteReference( rValue );
			break;
		case XML_TOK_TEXT_HYPERLINK_NAME:
			sName = rValue;
			break;
		case XML_TOK_TEXT_HYPERLINK_TARGET_FRAME:
			sTargetFrameName = rValue;
			break;
		case XML_TOK_TEXT_HYPERLINK_SHOW:
			sShow = rValue;
			break;
		case XML_TOK_TEXT_HYPERLINK_SERVER_MAP:
			{
				sal_Bool bTmp;
				if( rImport.GetMM100UnitConverter().convertBool( bTmp,
																  rValue ) )
				{
					bMap = bTmp;
				}
			}
			break;
		}
	}

	if( sShow.getLength() && !sTargetFrameName.getLength() )
	{
		if( IsXMLToken( sShow, XML_NEW ) )
			sTargetFrameName =
					OUString( RTL_CONSTASCII_USTRINGPARAM("_blank" ) );
		else if( IsXMLToken( sShow, XML_REPLACE ) )
			sTargetFrameName =
					OUString( RTL_CONSTASCII_USTRINGPARAM("_self" ) );
	}
}

XMLTextFrameHyperlinkContext::~XMLTextFrameHyperlinkContext()
{
}

void XMLTextFrameHyperlinkContext::EndElement()
{
}

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

	if( XML_NAMESPACE_DRAW == nPrefix )
	{
		if( IsXMLToken( rLocalName, XML_FRAME ) )
			pTextFrameContext = new XMLTextFrameContext( GetImport(), nPrefix,
												rLocalName, xAttrList,
												eDefaultAnchorType );
	}

	if( pTextFrameContext )
	{
		pTextFrameContext->SetHyperlink( sHRef, sName, sTargetFrameName, bMap );
		pContext = pTextFrameContext;
		xFrameContext = pContext;
	}
	else
		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );

	return pContext;
}


TextContentAnchorType XMLTextFrameHyperlinkContext::GetAnchorType() const
{
	if( xFrameContext.Is() )
	{
		SvXMLImportContext *pContext = &xFrameContext;
		return PTR_CAST( XMLTextFrameContext, pContext ) ->GetAnchorType();
	}
	else
		return eDefaultAnchorType;

}

Reference < XTextContent > XMLTextFrameHyperlinkContext::GetTextContent() const
{
	Reference <XTextContent > xTxt;
	if( xFrameContext.Is() )
	{
		SvXMLImportContext *pContext = &xFrameContext;
		xTxt = PTR_CAST( XMLTextFrameContext, pContext )->GetTextContent();
	}

	return xTxt;
}

// --> OD 2004-08-24 #33242#
Reference < drawing::XShape > XMLTextFrameHyperlinkContext::GetShape() const
{
    Reference < drawing::XShape > xShape;
    if( xFrameContext.Is() )
    {
        SvXMLImportContext *pContext = &xFrameContext;
        xShape = PTR_CAST( XMLTextFrameContext, pContext )->GetShape();
    }

    return xShape;
}
// <--
