/**************************************************************
 * 
 * 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 "ChartOASISTContext.hxx"
#include "MutableAttrList.hxx"
#include "xmloff/xmlnmspe.hxx"
#include "ActionMapTypesOASIS.hxx"
#include "AttrTransformerAction.hxx"
#include "TransformerActions.hxx"
#ifndef _XMLOFF_TRANSFORMERBASE_HXX
#include "TransformerBase.hxx"
#endif

using ::rtl::OUString;

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

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

TYPEINIT1( XMLChartOASISTransformerContext, XMLTransformerContext );

XMLChartOASISTransformerContext::XMLChartOASISTransformerContext( 
		XMLTransformerBase& rImp, 
		const OUString& rQName ) :
	XMLTransformerContext( rImp, rQName )
{
}

XMLChartOASISTransformerContext::~XMLChartOASISTransformerContext()
{
}

void XMLChartOASISTransformerContext::StartElement( 
	const Reference< XAttributeList >& rAttrList )
{
	XMLTransformerActions *pActions =
		GetTransformer().GetUserDefinedActions( OASIS_CHART_ACTIONS );
	OSL_ENSURE( pActions, "go no actions" );
	
	OUString aAddInName;
	Reference< XAttributeList > xAttrList( rAttrList );
	XMLMutableAttributeList *pMutableAttrList = 0;
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for( sal_Int16 i=0; i < nAttrCount; i++ )
	{
		const OUString& rAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix =
			GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName, 
																 &aLocalName );
		XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
		XMLTransformerActions::const_iterator aIter =
			pActions->find( aKey );
		if( !(aIter == pActions->end() ) )
		{
			if( !pMutableAttrList )
			{
				pMutableAttrList = 
						new XMLMutableAttributeList( xAttrList );
				xAttrList = pMutableAttrList;
			}
			const OUString& rAttrValue = xAttrList->getValueByIndex( i );
			switch( (*aIter).second.m_nActionType )
			{
			case XML_ATACTION_IN2INCH:
				{
					OUString aAttrValue( rAttrValue );
					if( XMLTransformerBase::ReplaceSingleInWithInch( 
								aAttrValue ) )
						pMutableAttrList->SetValueByIndex( i, aAttrValue );
				}
				break;
			case XML_ATACTION_DECODE_STYLE_NAME_REF:
				{
					OUString aAttrValue( rAttrValue );
					if( GetTransformer().DecodeStyleName(aAttrValue) )
						pMutableAttrList->SetValueByIndex( i, aAttrValue );
				}
				break;
			case XML_ATACTION_REMOVE_ANY_NAMESPACE_PREFIX:
				OSL_ENSURE( IsXMLToken( aLocalName, XML_CLASS ),
					   		"unexpected class token" );
				{
					OUString aChartClass;
					sal_uInt16 nValuePrefix =
						GetTransformer().GetNamespaceMap().GetKeyByAttrName(
                            rAttrValue,
                            &aChartClass );
					if( XML_NAMESPACE_CHART == nValuePrefix )
					{
						pMutableAttrList->SetValueByIndex( i, aChartClass );
					}
					else if ( XML_NAMESPACE_OOO == nValuePrefix )
					{
						pMutableAttrList->SetValueByIndex( i,
												GetXMLToken(XML_ADD_IN ) );
						aAddInName = aChartClass;
					}
				}
				break;
			default:
				OSL_ENSURE( !this, "unknown action" );
				break;
			}
		}
	}

	if( aAddInName.getLength() > 0 )
	{
		OUString aAttrQName( GetTransformer().GetNamespaceMap().GetQNameByKey(
								XML_NAMESPACE_CHART,
								GetXMLToken( XML_ADD_IN_NAME ) ) );
		pMutableAttrList->AddAttribute( aAttrQName, aAddInName );
	}

	XMLTransformerContext::StartElement( xAttrList );
}
