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

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

TYPEINIT1( XMLControlOASISTransformerContext, XMLTransformerContext );

XMLControlOASISTransformerContext::XMLControlOASISTransformerContext( 
		XMLTransformerBase& rImp, 
		const OUString& rQName,
	    sal_Bool bCreateControl	) :
	XMLTransformerContext( rImp, rQName ),
	m_aElemQName( rImp.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_FORM, 
							::xmloff::token::GetXMLToken( XML_CONTROL ) ) ),
	m_bCreateControl( bCreateControl )
{
}

XMLControlOASISTransformerContext::~XMLControlOASISTransformerContext()
{
}

void XMLControlOASISTransformerContext::StartElement( 
	const Reference< XAttributeList >& rAttrList )
{

	XMLTransformerActions *pActions =
		GetTransformer().GetUserDefinedActions( OASIS_FORM_CONTROL_ACTIONS );
	OSL_ENSURE( pActions, "go no actions" );

	Reference< XAttributeList > xAttrList( rAttrList );
	XMLMutableAttributeList *pMutableAttrList = 0;
//		GetTransformer().ProcessAttrList( xAttrList, OOO_SHAPE_ACTIONS,
//										  sal_True );

	XMLMutableAttributeList *pControlMutableAttrList = 
		m_bCreateControl ? new XMLMutableAttributeList : 0;
	Reference< XAttributeList > xControlAttrList( pControlMutableAttrList );

	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( rAttrList );
				xAttrList = pMutableAttrList;
			}
			const OUString& rAttrValue = xAttrList->getValueByIndex( i );
			switch( (*aIter).second.m_nActionType )
			{
			case XML_ATACTION_MOVE_TO_ELEM:
				if( m_bCreateControl )
				{
					pControlMutableAttrList->AddAttribute( rAttrName, 
														   rAttrValue );
					pMutableAttrList->RemoveAttributeByIndex( i );
					--i;
					--nAttrCount;
				}
				break;
			case XML_ATACTION_RENAME_REMOVE_NAMESPACE_PREFIX:
				{
					OUString aAttrValue( rAttrValue );
					sal_uInt16 nValPrefix =
						static_cast<sal_uInt16>( (*aIter).second.m_nParam2 );
					GetTransformer().RemoveNamespacePrefix( aAttrValue, 
															nValPrefix );
					OUString aNewAttrQName( 
						GetTransformer().GetNamespaceMap().GetQNameByKey( 
							(*aIter).second.GetQNamePrefixFromParam1(), 
							::xmloff::token::GetXMLToken( 
								(*aIter).second.GetQNameTokenFromParam1()) ) );
					if( m_bCreateControl )
					{
						pControlMutableAttrList->AddAttribute( aNewAttrQName, 
															   aAttrValue );
						pMutableAttrList->RemoveAttributeByIndex( i );
						--i;
						--nAttrCount;
					}
					else
					{
						pMutableAttrList->RenameAttributeByIndex( i, 
															  aNewAttrQName );
						pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
				}
			case XML_ATACTION_URI_OASIS:
				{
					OUString aAttrValue( rAttrValue );
					if( GetTransformer().ConvertURIToOOo( aAttrValue,
						   static_cast< sal_Bool >((*aIter).second.m_nParam1)) )
						pMutableAttrList->SetValueByIndex( i, aAttrValue );
				}
				break;
			default:
				OSL_ENSURE( !this, "unknown action" );
				break;
			}
		}
	}

	if( m_bCreateControl )
		GetTransformer().GetDocHandler()->startElement( m_aElemQName, 
														xControlAttrList );
	XMLTransformerContext::StartElement( xAttrList );
}

void XMLControlOASISTransformerContext::EndElement()
{
	XMLTransformerContext::EndElement();
	if( m_bCreateControl )
		GetTransformer().GetDocHandler()->endElement( m_aElemQName );
}
