/**************************************************************
 *
 * 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 "unointerfacetouniqueidentifiermapper.hxx"
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/presentation/AnimationEffect.hpp>
#include <com/sun/star/presentation/AnimationSpeed.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/xml/sax/XAttributeList.hpp>

#include <list>
#include <tools/color.hxx>
#include <comphelper/extract.hxx>
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlimp.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmluconv.hxx>
/*
#include <xmloff/xmlement.hxx>
*/
#include <xmloff/nmspmap.hxx>
#include "anim.hxx"
#include "animimp.hxx"

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

using namespace ::std;
using namespace ::cppu;
using namespace ::com::sun::star;
using namespace ::com::sun::star::xml;
using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::presentation;
using namespace ::xmloff::token;

SvXMLEnumMapEntry aXML_AnimationEffect_EnumMap[] =
{
	{ XML_NONE,			EK_none },
	{ XML_FADE,			EK_fade },
	{ XML_MOVE,			EK_move },
	{ XML_STRIPES,		EK_stripes },
	{ XML_OPEN,			EK_open },
	{ XML_CLOSE,		EK_close },
	{ XML_DISSOLVE,		EK_dissolve },
	{ XML_WAVYLINE,		EK_wavyline },
	{ XML_RANDOM,		EK_random },
	{ XML_LINES,		EK_lines },
	{ XML_LASER,		EK_laser },
	{ XML_APPEAR,		EK_appear },
	{ XML_HIDE,			EK_hide },
	{ XML_MOVE_SHORT,	EK_move_short },
	{ XML_CHECKERBOARD,	EK_checkerboard },
	{ XML_ROTATE,		EK_rotate },
	{ XML_STRETCH,		EK_stretch },
	{ XML_TOKEN_INVALID, 0 }
};

SvXMLEnumMapEntry aXML_AnimationDirection_EnumMap[] =
{
	{ XML_NONE,				ED_none },
	{ XML_FROM_LEFT,		ED_from_left },
	{ XML_FROM_TOP,			ED_from_top },
	{ XML_FROM_RIGHT,		ED_from_right },
	{ XML_FROM_BOTTOM,		ED_from_bottom },
	{ XML_FROM_CENTER,		ED_from_center },
	{ XML_FROM_UPPER_LEFT,	ED_from_upperleft },
	{ XML_FROM_UPPER_RIGHT,	ED_from_upperright },
	{ XML_FROM_LOWER_LEFT,	ED_from_lowerleft },
	{ XML_FROM_LOWER_RIGHT,	ED_from_lowerright },
	{ XML_TO_LEFT,			ED_to_left },
	{ XML_TO_TOP,			ED_to_top },
	{ XML_TO_RIGHT,			ED_to_right },
	{ XML_TO_BOTTOM,		ED_to_bottom },
	{ XML_TO_UPPER_LEFT,	ED_to_upperleft },
	{ XML_TO_UPPER_RIGHT,	ED_to_upperright },
	{ XML_TO_LOWER_RIGHT,	ED_to_lowerright },
	{ XML_TO_LOWER_LEFT,	ED_to_lowerleft },
	{ XML_PATH,				ED_path },
	{ XML_SPIRAL_INWARD_LEFT,	ED_spiral_inward_left },
	{ XML_SPIRAL_INWARD_RIGHT,	ED_spiral_inward_right },
	{ XML_SPIRAL_OUTWARD_LEFT,	ED_spiral_outward_left },
	{ XML_SPIRAL_OUTWARD_RIGHT,	ED_spiral_outward_right },
	{ XML_VERTICAL,			ED_vertical },
	{ XML_HORIZONTAL,		ED_horizontal },
	{ XML_TO_CENTER,		ED_to_center },
	{ XML_CLOCKWISE,		ED_clockwise },
	{ XML_COUNTER_CLOCKWISE,ED_cclockwise },
	{ XML_TOKEN_INVALID, 0 }
};

SvXMLEnumMapEntry aXML_AnimationSpeed_EnumMap[] =
{
	{ XML_SLOW,		AnimationSpeed_SLOW },
	{ XML_MEDIUM,	AnimationSpeed_MEDIUM },
	{ XML_FAST,		AnimationSpeed_FAST },
	{ XML_TOKEN_INVALID, 0 }
};

AnimationEffect ImplSdXMLgetEffect( XMLEffect eKind, XMLEffectDirection eDirection, sal_Int16 nStartScale, sal_Bool /*bIn*/ )
{
	switch( eKind )
	{
	case EK_fade:
		switch( eDirection )
		{
		case ED_from_left:			return AnimationEffect_FADE_FROM_LEFT;
		case ED_from_top:			return AnimationEffect_FADE_FROM_TOP;
		case ED_from_right:			return AnimationEffect_FADE_FROM_RIGHT;
		case ED_from_bottom:		return AnimationEffect_FADE_FROM_BOTTOM;
		case ED_from_center:		return AnimationEffect_FADE_FROM_CENTER;
		case ED_from_upperleft:		return AnimationEffect_FADE_FROM_UPPERLEFT;
		case ED_from_upperright:	return AnimationEffect_FADE_FROM_UPPERRIGHT;
		case ED_from_lowerleft:		return AnimationEffect_FADE_FROM_LOWERLEFT;
		case ED_from_lowerright:	return AnimationEffect_FADE_FROM_LOWERRIGHT;
		case ED_to_center:			return AnimationEffect_FADE_TO_CENTER;
		case ED_clockwise:			return AnimationEffect_CLOCKWISE;
		case ED_cclockwise:			return AnimationEffect_COUNTERCLOCKWISE;
		case ED_spiral_inward_left:	return AnimationEffect_SPIRALIN_LEFT;
		case ED_spiral_inward_right:return AnimationEffect_SPIRALIN_RIGHT;
		case ED_spiral_outward_left:return AnimationEffect_SPIRALOUT_LEFT;
		case ED_spiral_outward_right:return AnimationEffect_SPIRALOUT_RIGHT;
		default:					return AnimationEffect_FADE_FROM_LEFT;
		}
	case EK_move:
		if( nStartScale == 200 )
		{
			return AnimationEffect_ZOOM_OUT_SMALL;
		}
		else if( nStartScale == 50 )
		{
			return AnimationEffect_ZOOM_IN_SMALL;
		}
		else if( nStartScale < 100 )
		{
			switch( eDirection )
			{
			case ED_from_left:			return AnimationEffect_ZOOM_IN_FROM_LEFT;
			case ED_from_top:			return AnimationEffect_ZOOM_IN_FROM_TOP;
			case ED_from_right:			return AnimationEffect_ZOOM_IN_FROM_RIGHT;
			case ED_from_bottom:		return AnimationEffect_ZOOM_IN_FROM_BOTTOM;
			case ED_from_upperleft:		return AnimationEffect_ZOOM_IN_FROM_UPPERLEFT;
			case ED_from_upperright:	return AnimationEffect_ZOOM_IN_FROM_UPPERRIGHT;
			case ED_from_lowerleft:		return AnimationEffect_ZOOM_IN_FROM_LOWERLEFT;
			case ED_from_lowerright:	return AnimationEffect_ZOOM_IN_FROM_LOWERRIGHT;
			case ED_from_center:		return AnimationEffect_ZOOM_IN_FROM_CENTER;
			case ED_spiral_inward_left:	return AnimationEffect_ZOOM_IN_SPIRAL;
			case ED_to_left:			return AnimationEffect_MOVE_TO_LEFT;
			case ED_to_top:				return AnimationEffect_MOVE_TO_TOP;
			case ED_to_right:			return AnimationEffect_MOVE_TO_RIGHT;
			case ED_to_bottom:			return AnimationEffect_MOVE_TO_BOTTOM;
			case ED_to_upperleft:		return AnimationEffect_MOVE_TO_UPPERLEFT;
			case ED_to_upperright:		return AnimationEffect_MOVE_TO_UPPERRIGHT;
			case ED_to_lowerright:		return AnimationEffect_MOVE_TO_LOWERRIGHT;
			case ED_to_lowerleft:		return AnimationEffect_MOVE_TO_LOWERLEFT;
			default:					return AnimationEffect_ZOOM_IN;
			}
		}
		else if( nStartScale > 100 )
		{
			switch( eDirection )
			{
			case ED_from_left:			return AnimationEffect_ZOOM_OUT_FROM_LEFT;
			case ED_from_top:			return AnimationEffect_ZOOM_OUT_FROM_TOP;
			case ED_from_right:			return AnimationEffect_ZOOM_OUT_FROM_RIGHT;
			case ED_from_bottom:		return AnimationEffect_ZOOM_OUT_FROM_BOTTOM;
			case ED_from_upperleft:		return AnimationEffect_ZOOM_OUT_FROM_UPPERLEFT;
			case ED_from_upperright:	return AnimationEffect_ZOOM_OUT_FROM_UPPERRIGHT;
			case ED_from_lowerleft:		return AnimationEffect_ZOOM_OUT_FROM_LOWERLEFT;
			case ED_from_lowerright:	return AnimationEffect_ZOOM_OUT_FROM_LOWERRIGHT;
			case ED_from_center:		return AnimationEffect_ZOOM_OUT_FROM_CENTER;
			case ED_spiral_inward_left:	return AnimationEffect_ZOOM_OUT_SPIRAL;
			default:					return AnimationEffect_ZOOM_OUT;
			}
		}
		else
		{
			switch( eDirection )
			{
			case ED_from_left:			return AnimationEffect_MOVE_FROM_LEFT;
			case ED_from_top:			return AnimationEffect_MOVE_FROM_TOP;
			case ED_from_right:			return AnimationEffect_MOVE_FROM_RIGHT;
			case ED_from_bottom:		return AnimationEffect_MOVE_FROM_BOTTOM;
			case ED_from_upperleft:		return AnimationEffect_MOVE_FROM_UPPERLEFT;
			case ED_from_upperright:	return AnimationEffect_MOVE_FROM_UPPERRIGHT;
			case ED_from_lowerleft:		return AnimationEffect_MOVE_FROM_LOWERLEFT;
			case ED_from_lowerright:	return AnimationEffect_MOVE_FROM_LOWERRIGHT;
			case ED_path:				return AnimationEffect_PATH;
			case ED_to_top:				return AnimationEffect_MOVE_TO_TOP;
			case ED_to_right:			return AnimationEffect_MOVE_TO_RIGHT;
			case ED_to_bottom:			return AnimationEffect_MOVE_TO_BOTTOM;
			case ED_to_upperleft:		return AnimationEffect_MOVE_TO_UPPERLEFT;
			case ED_to_upperright:		return AnimationEffect_MOVE_TO_UPPERRIGHT;
			case ED_to_lowerright:		return AnimationEffect_MOVE_TO_LOWERRIGHT;
			case ED_to_lowerleft:		return AnimationEffect_MOVE_TO_LOWERLEFT;
			default:
				break;
			}
		}
		return AnimationEffect_MOVE_FROM_LEFT;
	case EK_stripes:
		if( eDirection == ED_vertical )
			return AnimationEffect_VERTICAL_STRIPES;
		else
			return AnimationEffect_HORIZONTAL_STRIPES;
	case EK_open:
		if( eDirection == ED_vertical )
			return AnimationEffect_OPEN_VERTICAL;
		else
			return AnimationEffect_OPEN_HORIZONTAL;
	case EK_close:
		if( eDirection == ED_vertical )
			return AnimationEffect_CLOSE_VERTICAL;
		else
			return AnimationEffect_CLOSE_HORIZONTAL;
	case EK_dissolve:
		return AnimationEffect_DISSOLVE;
	case EK_wavyline:
		switch( eDirection )
		{
		case ED_from_left:			return AnimationEffect_WAVYLINE_FROM_LEFT;
		case ED_from_top:			return AnimationEffect_WAVYLINE_FROM_TOP;
		case ED_from_right:			return AnimationEffect_WAVYLINE_FROM_RIGHT;
		case ED_from_bottom:		return AnimationEffect_WAVYLINE_FROM_BOTTOM;
		default:					return AnimationEffect_WAVYLINE_FROM_LEFT;
		}
	case EK_random:
		return AnimationEffect_RANDOM;
	case EK_lines:
		if( eDirection == ED_vertical )
			return AnimationEffect_VERTICAL_LINES;
		else
			return AnimationEffect_HORIZONTAL_LINES;
	case EK_laser:
		switch( eDirection )
		{
		case ED_from_left:			return AnimationEffect_LASER_FROM_LEFT;
		case ED_from_top:			return AnimationEffect_LASER_FROM_TOP;
		case ED_from_right:			return AnimationEffect_LASER_FROM_RIGHT;
		case ED_from_bottom:		return AnimationEffect_LASER_FROM_BOTTOM;
		case ED_from_upperleft:		return AnimationEffect_LASER_FROM_UPPERLEFT;
		case ED_from_upperright:	return AnimationEffect_LASER_FROM_UPPERRIGHT;
		case ED_from_lowerleft:		return AnimationEffect_LASER_FROM_LOWERLEFT;
		case ED_from_lowerright:	return AnimationEffect_LASER_FROM_LOWERRIGHT;
		default:					return AnimationEffect_LASER_FROM_LEFT;
		}
	case EK_appear:
		return AnimationEffect_APPEAR;
	case EK_hide:
		return AnimationEffect_HIDE;
	case EK_move_short:
		switch( eDirection )
		{
		case ED_from_left:			return AnimationEffect_MOVE_SHORT_FROM_LEFT;
		case ED_from_top:			return AnimationEffect_MOVE_SHORT_FROM_TOP;
		case ED_from_right:			return AnimationEffect_MOVE_SHORT_FROM_RIGHT;
		case ED_from_bottom:		return AnimationEffect_MOVE_SHORT_FROM_BOTTOM;
		case ED_from_upperleft:		return AnimationEffect_MOVE_SHORT_FROM_UPPERLEFT;
		case ED_from_upperright:	return AnimationEffect_MOVE_SHORT_FROM_UPPERRIGHT;
		case ED_from_lowerleft:		return AnimationEffect_MOVE_SHORT_FROM_LOWERLEFT;
		case ED_from_lowerright:	return AnimationEffect_MOVE_SHORT_FROM_LOWERRIGHT;
		case ED_to_left:			return AnimationEffect_MOVE_SHORT_TO_LEFT;
		case ED_to_upperleft:		return AnimationEffect_MOVE_SHORT_TO_UPPERLEFT;
		case ED_to_top:				return AnimationEffect_MOVE_SHORT_TO_TOP;
		case ED_to_upperright:		return AnimationEffect_MOVE_SHORT_TO_UPPERRIGHT;
		case ED_to_right:			return AnimationEffect_MOVE_SHORT_TO_RIGHT;
		case ED_to_lowerright:		return AnimationEffect_MOVE_SHORT_TO_LOWERRIGHT;
		case ED_to_bottom:			return AnimationEffect_MOVE_SHORT_TO_BOTTOM;
		case ED_to_lowerleft:		return AnimationEffect_MOVE_SHORT_TO_LOWERLEFT;
		default:					return AnimationEffect_MOVE_SHORT_FROM_LEFT;
		}
	case EK_checkerboard:
		if( eDirection == ED_vertical )
			return AnimationEffect_VERTICAL_CHECKERBOARD;
		else
			return AnimationEffect_HORIZONTAL_CHECKERBOARD;
	case EK_rotate:
		if( eDirection == ED_vertical )
			return AnimationEffect_VERTICAL_ROTATE;
		else
			return AnimationEffect_HORIZONTAL_ROTATE;
	case EK_stretch:
		switch( eDirection )
		{
		case ED_from_left:			return AnimationEffect_STRETCH_FROM_LEFT;
		case ED_from_top:			return AnimationEffect_STRETCH_FROM_TOP;
		case ED_from_right:			return AnimationEffect_STRETCH_FROM_RIGHT;
		case ED_from_bottom:		return AnimationEffect_STRETCH_FROM_BOTTOM;
		case ED_from_upperleft:		return AnimationEffect_STRETCH_FROM_UPPERLEFT;
		case ED_from_upperright:	return AnimationEffect_STRETCH_FROM_UPPERRIGHT;
		case ED_from_lowerleft:		return AnimationEffect_STRETCH_FROM_LOWERLEFT;
		case ED_from_lowerright:	return AnimationEffect_STRETCH_FROM_LOWERRIGHT;
		case ED_vertical:			return AnimationEffect_VERTICAL_STRETCH;
		case ED_horizontal:			return AnimationEffect_HORIZONTAL_STRETCH;
		default:
			break;
		}
		return AnimationEffect_STRETCH_FROM_LEFT;
	default:
		return AnimationEffect_NONE;
	}
}

///////////////////////////////////////////////////////////////////////

class AnimImpImpl
{
public:
	Reference< XPropertySet > mxLastShape;
	OUString maLastShapeId;

	OUString msDimColor;
	OUString msDimHide;
	OUString msDimPrev;
	OUString msEffect;
	OUString msPlayFull;
	OUString msPresOrder;
	OUString msSound;
	OUString msSoundOn;
	OUString msSpeed;
	OUString msTextEffect;
	OUString msPresShapeService;
	OUString msAnimPath;
	OUString msIsAnimation;

	AnimImpImpl()
	:	msDimColor( RTL_CONSTASCII_USTRINGPARAM( "DimColor" ) ),
		msDimHide( RTL_CONSTASCII_USTRINGPARAM( "DimHide" ) ),
		msDimPrev( RTL_CONSTASCII_USTRINGPARAM( "DimPrevious" ) ),
		msEffect( RTL_CONSTASCII_USTRINGPARAM( "Effect" ) ),
		msPlayFull( RTL_CONSTASCII_USTRINGPARAM( "PlayFull" ) ),
		msPresOrder( RTL_CONSTASCII_USTRINGPARAM( "PresentationOrder" ) ),
		msSound( RTL_CONSTASCII_USTRINGPARAM( "Sound" ) ),
		msSoundOn( RTL_CONSTASCII_USTRINGPARAM( "SoundOn" ) ),
		msSpeed( RTL_CONSTASCII_USTRINGPARAM( "Speed" ) ),
		msTextEffect( RTL_CONSTASCII_USTRINGPARAM( "TextEffect" ) ),
		msPresShapeService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.Shape" ) ),
		msAnimPath( RTL_CONSTASCII_USTRINGPARAM( "AnimationPath" ) ),
		msIsAnimation( RTL_CONSTASCII_USTRINGPARAM( "IsAnimation" ) )
	{}
};

///////////////////////////////////////////////////////////////////////

enum XMLActionKind
{
	XMLE_SHOW,
	XMLE_HIDE,
	XMLE_DIM,
	XMLE_PLAY
};

class XMLAnimationsEffectContext : public SvXMLImportContext
{
public:
	AnimImpImpl*	mpImpl;

	XMLActionKind	meKind;
	sal_Bool		mbTextEffect;
	OUString		maShapeId;

	XMLEffect		meEffect;
	XMLEffectDirection	meDirection;
	sal_Int16		mnStartScale;

	AnimationSpeed	meSpeed;
	Color			maDimColor;
	OUString		maSoundURL;
	sal_Bool		mbPlayFull;
	OUString		maPathShapeId;

public:
	TYPEINFO();

	XMLAnimationsEffectContext( SvXMLImport& rImport,
		sal_uInt16 nPrfx,
		const OUString& rLocalName,
		const Reference< XAttributeList >& xAttrList,
		AnimImpImpl* pImpl);
	virtual ~XMLAnimationsEffectContext();

	virtual void EndElement();

	virtual SvXMLImportContext * CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName,
		const Reference< XAttributeList >& xAttrList );
};

class XMLAnimationsSoundContext : public SvXMLImportContext
{
	XMLAnimationsEffectContext* mpParent;

public:
	TYPEINFO();

	XMLAnimationsSoundContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList, XMLAnimationsEffectContext* pParent );
	virtual ~XMLAnimationsSoundContext();
};

TYPEINIT1( XMLAnimationsSoundContext, SvXMLImportContext );

XMLAnimationsSoundContext::XMLAnimationsSoundContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList, XMLAnimationsEffectContext* pParent )
: SvXMLImportContext( rImport, nPrfx, rLocalName ), mpParent( pParent )
{
	if( mpParent && nPrfx == XML_NAMESPACE_PRESENTATION && IsXMLToken( rLocalName, XML_SOUND ) )
	{
		const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
		for(sal_Int16 i=0; i < nAttrCount; i++)
		{
			OUString sAttrName = xAttrList->getNameByIndex( i );
			OUString aLocalName;
			sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
			OUString sValue = xAttrList->getValueByIndex( i );

			switch( nPrefix )
			{
			case XML_NAMESPACE_XLINK:
				if( IsXMLToken( aLocalName, XML_HREF ) )
				{
					mpParent->maSoundURL = rImport.GetAbsoluteReference(sValue);
				}
				break;
			case XML_NAMESPACE_PRESENTATION:
				if( IsXMLToken( aLocalName, XML_PLAY_FULL ) )
				{
					mpParent->mbPlayFull = IsXMLToken( sValue, XML_TRUE );
				}
			}
		}
	}
}

XMLAnimationsSoundContext::~XMLAnimationsSoundContext()
{
}


TYPEINIT1( XMLAnimationsEffectContext, SvXMLImportContext );

XMLAnimationsEffectContext::XMLAnimationsEffectContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList, AnimImpImpl* pImpl )
:	SvXMLImportContext(rImport, nPrfx, rLocalName),
	mpImpl( pImpl ),
	meKind( XMLE_SHOW ), mbTextEffect( sal_False ),
	meEffect( EK_none ), meDirection( ED_none ), mnStartScale( 100 ),
	meSpeed( AnimationSpeed_MEDIUM ), maDimColor(0), mbPlayFull( sal_False )
{
	if( IsXMLToken( rLocalName, XML_SHOW_SHAPE ) )
	{
		meKind = XMLE_SHOW;
	}
	else if( IsXMLToken( rLocalName, XML_SHOW_TEXT ) )
	{
		meKind = XMLE_SHOW;
		mbTextEffect = sal_True;
	}
	else if( IsXMLToken( rLocalName, XML_HIDE_SHAPE ) )
	{
		meKind = XMLE_HIDE;
	}
	else if( IsXMLToken( rLocalName, XML_HIDE_TEXT ) )
	{
		meKind = XMLE_HIDE;
		mbTextEffect = sal_True;
	}
	else if( IsXMLToken( rLocalName, XML_DIM ) )
	{
		meKind = XMLE_DIM;
	}
	else if( IsXMLToken( rLocalName, XML_PLAY ) )
	{
		meKind = XMLE_PLAY;
	}
	else
	{
		// unknown action, overread
		return;
	}

	// read attributes
	const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for(sal_Int16 i=0; i < nAttrCount; i++)
	{
		OUString sAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
		OUString sValue = xAttrList->getValueByIndex( i );

		switch( nPrefix )
		{
		case XML_NAMESPACE_DRAW:
			if( IsXMLToken( aLocalName, XML_SHAPE_ID ) )
			{
				maShapeId = sValue;
			}
			else if( IsXMLToken( aLocalName, XML_COLOR ) )
			{
				SvXMLUnitConverter::convertColor(maDimColor, sValue);
			}
			break;

		case XML_NAMESPACE_PRESENTATION:
			if( IsXMLToken( aLocalName, XML_EFFECT ) )
			{
				sal_uInt16 eEnum;
				if( SvXMLUnitConverter::convertEnum( eEnum, sValue, aXML_AnimationEffect_EnumMap ) )
					meEffect = (XMLEffect)eEnum;
			}
			else if( IsXMLToken(aLocalName, XML_DIRECTION ) )
			{
				sal_uInt16 eEnum;
				if( SvXMLUnitConverter::convertEnum( eEnum, sValue, aXML_AnimationDirection_EnumMap ) )
					meDirection = (XMLEffectDirection)eEnum;
			}
			else if( IsXMLToken( aLocalName, XML_START_SCALE ) )
			{
				sal_Int32 nScale;
				if( SvXMLUnitConverter::convertPercent( nScale, sValue ) )
					mnStartScale = (sal_Int16)nScale;
			}
			else if( IsXMLToken( aLocalName, XML_SPEED ) )
			{
				sal_uInt16 eEnum;
				if( SvXMLUnitConverter::convertEnum( eEnum, sValue, aXML_AnimationSpeed_EnumMap ) )
					meSpeed = (AnimationSpeed)eEnum;
			}
			else if( IsXMLToken( aLocalName, XML_PATH_ID ) )
			{
				maPathShapeId = sValue;
			}
			break;
		}
	}
}

XMLAnimationsEffectContext::~XMLAnimationsEffectContext()
{
}

SvXMLImportContext * XMLAnimationsEffectContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList>& xAttrList )
{
	return new XMLAnimationsSoundContext( GetImport(), nPrefix, rLocalName, xAttrList, this );
}

void XMLAnimationsEffectContext::EndElement()
{
	// set effect on shape

	try
	{
		UniReference< XMLShapeImportHelper > xShapeImport( GetImport().GetShapeImport() );
		Any aAny;

		if( maShapeId.getLength() )
		{
			Reference< XPropertySet > xSet;
			if( mpImpl->maLastShapeId != maShapeId )
			{
				xSet = Reference< XPropertySet >::query( GetImport().getInterfaceToIdentifierMapper().getReference( maShapeId ) );
				if( xSet.is() )
				{
					// check for presentation shape service
					{
						Reference< XServiceInfo > xServiceInfo( xSet, UNO_QUERY );
						if( !xServiceInfo.is() || !xServiceInfo->supportsService( mpImpl->msPresShapeService ) )
							return;
					}

					mpImpl->maLastShapeId = maShapeId;
					mpImpl->mxLastShape = xSet;
				}
			}
			else
			{
				xSet = mpImpl->mxLastShape;
			}

			if( xSet.is() )
			{
				if( meKind == XMLE_DIM )
				{
					aAny <<= (sal_Bool)sal_True;
					xSet->setPropertyValue( mpImpl->msDimPrev, aAny );

					aAny <<= (sal_Int32)maDimColor.GetColor();
					xSet->setPropertyValue( mpImpl->msDimColor, aAny );
				}
				else if( meKind == XMLE_PLAY )
				{
					aAny <<= (sal_Bool)sal_True;
					xSet->setPropertyValue( mpImpl->msIsAnimation, aAny );

					// #42894# speed is not supported for the old group animation fallback, so no need to set it
					// aAny <<= meSpeed;
					// xSet->setPropertyValue( mpImpl->msSpeed, aAny );
				}
				else
				{
					if( meKind == XMLE_HIDE && !mbTextEffect && meEffect == EK_none )
					{
						aAny = bool2any( sal_True );
						xSet->setPropertyValue( mpImpl->msDimHide, aAny );
					}
					else
					{
						const AnimationEffect eEffect = ImplSdXMLgetEffect( meEffect, meDirection, mnStartScale, meKind == XMLE_SHOW );

						xSet->setPropertyValue( mbTextEffect ? mpImpl->msTextEffect : mpImpl->msEffect, makeAny( eEffect ) );
						xSet->setPropertyValue( mpImpl->msSpeed, makeAny( meSpeed ) );

						if( eEffect == AnimationEffect_PATH && maPathShapeId.getLength() )
						{
							Reference< XShape > xPath( GetImport().getInterfaceToIdentifierMapper().getReference( maPathShapeId ), UNO_QUERY );
							if( xPath.is() )
								xSet->setPropertyValue( mpImpl->msAnimPath, makeAny( xPath ) );
						}
					}
				}
			}
			if( maSoundURL.getLength() != 0 )
			{
				if( xSet.is() )
				{
					aAny <<= maSoundURL;
					xSet->setPropertyValue( mpImpl->msSound, aAny );

					aAny <<= bool2any( mbPlayFull );
					xSet->setPropertyValue( mpImpl->msPlayFull, aAny );

					aAny <<= bool2any( sal_True );
					xSet->setPropertyValue( mpImpl->msSoundOn, aAny );
				}
				else
				{
					DBG_ERROR("XMLAnimationsEffectContext::EndElement - Sound URL without a XPropertySet!");
				}
			}
		}
	}
	catch( Exception e )
	{
		DBG_ERROR( "exception caught while importing animation information!" );
	}
}

///////////////////////////////////////////////////////////////////////

TYPEINIT1( XMLAnimationsContext, SvXMLImportContext );

XMLAnimationsContext::XMLAnimationsContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLocalName,
		const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& )
: SvXMLImportContext(rImport, nPrfx, rLocalName)
{
	mpImpl = new AnimImpImpl();
}

XMLAnimationsContext::~XMLAnimationsContext()
{
	delete mpImpl;
}

SvXMLImportContext * XMLAnimationsContext::CreateChildContext( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName,
		const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList )
{
	return new XMLAnimationsEffectContext( GetImport(), nPrefix, rLocalName, xAttrList, mpImpl );
}
