/**************************************************************
 *
 * 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 <com/sun/star/animations/XAnimateColor.hpp>
#include <com/sun/star/animations/XAnimateSet.hpp>
#include <com/sun/star/animations/XCommand.hpp>
#include <com/sun/star/animations/Timing.hpp>
#include <com/sun/star/animations/Event.hpp>
#include <com/sun/star/animations/XAnimateMotion.hpp>
#include <com/sun/star/animations/XAnimateTransform.hpp>
#include <com/sun/star/animations/XTransitionFilter.hpp>
#include <com/sun/star/animations/XIterateContainer.hpp>
#include <com/sun/star/animations/XAudio.hpp>
#include <com/sun/star/animations/AnimationColorSpace.hpp>
#include <com/sun/star/animations/AnimationNodeType.hpp>
#include <com/sun/star/animations/AnimationRestart.hpp>
#include <com/sun/star/animations/EventTrigger.hpp>
#include <com/sun/star/animations/AnimationFill.hpp>
#include <com/sun/star/animations/AnimationEndSync.hpp>
#include <com/sun/star/animations/AnimationNodeType.hpp>
#include <com/sun/star/animations/AnimationCalcMode.hpp>
#include <com/sun/star/animations/AnimationAdditiveMode.hpp>
#include <com/sun/star/animations/AnimationTransformType.hpp>
#include <com/sun/star/animations/TransitionType.hpp>
#include <com/sun/star/animations/TransitionSubType.hpp>
#include <com/sun/star/animations/ValuePair.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/presentation/EffectNodeType.hpp>
#include <com/sun/star/presentation/EffectPresetClass.hpp>
#include <com/sun/star/presentation/ParagraphTarget.hpp>
#include <com/sun/star/presentation/TextAnimationType.hpp>
#include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
#include <com/sun/star/presentation/EffectCommands.hpp>
#include <com/sun/star/drawing/XShape.hpp>

#include <tools/debug.hxx>
#include <tools/time.hxx>
#include "unointerfacetouniqueidentifiermapper.hxx"
#include "sdxmlexp_impl.hxx"
#include "sdpropls.hxx"
#include <xmloff/xmltoken.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmlexp.hxx>
#include <xmloff/xmlement.hxx>
#include <xmloff/nmspmap.hxx>
#include <xmloff/shapeexport.hxx>

#include "animations.hxx"
#include "animationexport.hxx"

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

using namespace ::std;
using namespace ::cppu;
using namespace ::com::sun::star::animations;
using namespace ::com::sun::star::presentation;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::beans;
using namespace ::xmloff::token;

using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::uno::UNO_QUERY_THROW;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Exception;
using ::com::sun::star::uno::RuntimeException;
using ::com::sun::star::uno::XInterface;
using ::com::sun::star::beans::NamedValue;
using ::com::sun::star::container::XEnumerationAccess;
using ::com::sun::star::container::XEnumeration;

namespace xmloff
{

SvXMLEnumMapEntry* getAnimationsEnumMap( sal_uInt16 nMap )
{
	switch( nMap )
	{
	case Animations_EnumMap_Fill:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_Fill[] =
			{
				{ XML_DEFAULT,		AnimationFill::DEFAULT },
				{ XML_REMOVE,		AnimationFill::REMOVE },
				{ XML_FREEZE,		AnimationFill::FREEZE },
				{ XML_HOLD,			AnimationFill::HOLD },
				{ XML_TRANSITION,	AnimationFill::TRANSITION },
				{ XML_AUTO,			AnimationFill::AUTO },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_Fill;
		}
	case Animations_EnumMap_FillDefault:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_Fill[] =
			{
				{ XML_INHERIT,		AnimationFill::INHERIT },
				{ XML_REMOVE,		AnimationFill::REMOVE },
				{ XML_FREEZE,		AnimationFill::FREEZE },
				{ XML_HOLD,			AnimationFill::HOLD },
				{ XML_TRANSITION,	AnimationFill::TRANSITION },
				{ XML_AUTO,			AnimationFill::AUTO },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_Fill;
		}
	case Animations_EnumMap_Restart:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_Restart[] =
			{
				{ XML_DEFAULT,		AnimationRestart::DEFAULT },
				{ XML_ALWAYS,		AnimationRestart::ALWAYS },
				{ XML_WHENNOTACTIVE,AnimationRestart::WHEN_NOT_ACTIVE },
				{ XML_NEVER,		AnimationRestart::NEVER },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_Restart;
		}
	case Animations_EnumMap_RestartDefault:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_RestartDefault[] =
			{
				{ XML_INHERIT,		AnimationRestart::INHERIT },
				{ XML_ALWAYS,		AnimationRestart::ALWAYS },
				{ XML_WHENNOTACTIVE,AnimationRestart::WHEN_NOT_ACTIVE },
				{ XML_NEVER,		AnimationRestart::NEVER },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_RestartDefault;
		}
	case Animations_EnumMap_Endsync:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_Endsync[] =
			{
				{ XML_FIRST,		AnimationEndSync::FIRST },
				{ XML_LAST,			AnimationEndSync::LAST },
				{ XML_ALL,			AnimationEndSync::ALL },
				{ XML_MEDIA,		AnimationEndSync::MEDIA },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_Endsync;
		}
	case Animations_EnumMap_CalcMode:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_CalcMode[] =
			{
				{ XML_DISCRETE,		AnimationCalcMode::DISCRETE },
				{ XML_LINEAR,		AnimationCalcMode::LINEAR },
				{ XML_PACED,		AnimationCalcMode::PACED },
				{ XML_SPLINE,		AnimationCalcMode::SPLINE },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_CalcMode;
		}
	case Animations_EnumMap_AdditiveMode:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_AdditiveMode[] =
			{
				{ XML_BASE,			AnimationAdditiveMode::BASE },
				{ XML_SUM,			AnimationAdditiveMode::SUM },
				{ XML_REPLACE,		AnimationAdditiveMode::REPLACE },
				{ XML_MULTIPLY,		AnimationAdditiveMode::MULTIPLY },
				{ XML_NONE,			AnimationAdditiveMode::NONE },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_AdditiveMode;
		}
	case Animations_EnumMap_TransformType:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_TransformType[] =
			{
				{ XML_TRANSLATE,	AnimationTransformType::TRANSLATE },
				{ XML_SCALE,		AnimationTransformType::SCALE },
				{ XML_ROTATE,		AnimationTransformType::ROTATE },
				{ XML_SKEWX,		AnimationTransformType::SKEWX },
				{ XML_SKEWY,		AnimationTransformType::SKEWY },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_TransformType;
		}
	case Animations_EnumMap_TransitionType:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_TransitionType[] =
			{
				{ XML_BARWIPE,			TransitionType::BARWIPE },
				{ XML_BOXWIPE,			TransitionType::BOXWIPE },
				{ XML_FOURBOXWIPE,		TransitionType::FOURBOXWIPE },
				{ XML_BARNDOORWIPE,		TransitionType::BARNDOORWIPE },
				{ XML_DIAGONALWIPE,		TransitionType::DIAGONALWIPE },
				{ XML_BOWTIEWIPE,		TransitionType::BOWTIEWIPE },
				{ XML_MISCDIAGONALWIPE,	TransitionType::MISCDIAGONALWIPE },
				{ XML_VEEWIPE,			TransitionType::VEEWIPE },
				{ XML_BARNVEEWIPE,		TransitionType::BARNVEEWIPE },
				{ XML_ZIGZAGWIPE,		TransitionType::ZIGZAGWIPE },
				{ XML_BARNZIGZAGWIPE,	TransitionType::BARNZIGZAGWIPE },
				{ XML_IRISWIPE,			TransitionType::IRISWIPE },
				{ XML_TRIANGLEWIPE,		TransitionType::TRIANGLEWIPE },
				{ XML_ARROWHEADWIPE,	TransitionType::ARROWHEADWIPE },
				{ XML_PENTAGONWIPE,		TransitionType::PENTAGONWIPE },
				{ XML_HEXAGONWIPE,		TransitionType::HEXAGONWIPE },
				{ XML_ELLIPSEWIPE,		TransitionType::ELLIPSEWIPE },
				{ XML_EYEWIPE,			TransitionType::EYEWIPE },
				{ XML_ROUNDRECTWIPE,	TransitionType::ROUNDRECTWIPE },
				{ XML_STARWIPE,			TransitionType::STARWIPE },
				{ XML_MISCSHAPEWIPE,	TransitionType::MISCSHAPEWIPE },
				{ XML_CLOCKWIPE,		TransitionType::CLOCKWIPE },
				{ XML_PINWHEELWIPE,		TransitionType::PINWHEELWIPE },
				{ XML_SINGLESWEEPWIPE,	TransitionType::SINGLESWEEPWIPE },
				{ XML_FANWIPE,			TransitionType::FANWIPE },
				{ XML_DOUBLEFANWIPE,	TransitionType::DOUBLEFANWIPE },
				{ XML_DOUBLESWEEPWIPE,	TransitionType::DOUBLESWEEPWIPE },
				{ XML_SALOONDOORWIPE,	TransitionType::SALOONDOORWIPE },
				{ XML_WINDSHIELDWIPE,	TransitionType::WINDSHIELDWIPE },
				{ XML_SNAKEWIPE,		TransitionType::SNAKEWIPE },
				{ XML_SPIRALWIPE,		TransitionType::SPIRALWIPE },
				{ XML_PARALLELSNAKESWIPE,TransitionType::PARALLELSNAKESWIPE },
				{ XML_BOXSNAKESWIPE,	TransitionType::BOXSNAKESWIPE },
				{ XML_WATERFALLWIPE,	TransitionType::WATERFALLWIPE },
				{ XML_PUSHWIPE,			TransitionType::PUSHWIPE },
				{ XML_SLIDEWIPE,		TransitionType::SLIDEWIPE },
				{ XML_FADE,				TransitionType::FADE },
				{ XML_RANDOMBARWIPE,	TransitionType::RANDOMBARWIPE },
				{ XML_CHECKERBOARDWIPE,	TransitionType::CHECKERBOARDWIPE },
				{ XML_DISSOLVE,			TransitionType::DISSOLVE },
				{ XML_BLINDSWIPE,		TransitionType::BLINDSWIPE },
				{ XML_RANDOM,			TransitionType::RANDOM },
				{ XML_ZOOM,				TransitionType::ZOOM },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_TransitionType;
		}
	case Animations_EnumMap_TransitionSubType:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_TransitionSubType[] =
			{
				{ XML_DEFAULT,				TransitionSubType::DEFAULT },
				{ XML_LEFTTORIGHT,			TransitionSubType::LEFTTORIGHT },
				{ XML_TOPTOBOTTOM,			TransitionSubType::TOPTOBOTTOM },
				{ XML_TOPLEFT,				TransitionSubType::TOPLEFT },
				{ XML_TOPRIGHT,				TransitionSubType::TOPRIGHT },
				{ XML_BOTTOMRIGHT,			TransitionSubType::BOTTOMRIGHT },
				{ XML_BOTTOMLEFT,			TransitionSubType::BOTTOMLEFT },
				{ XML_TOPCENTER,			TransitionSubType::TOPCENTER },
				{ XML_RIGHTCENTER,			TransitionSubType::RIGHTCENTER },
				{ XML_BOTTOMCENTER,			TransitionSubType::BOTTOMCENTER },
				{ XML_LEFTCENTER,			TransitionSubType::LEFTCENTER },
				{ XML_CORNERSIN,			TransitionSubType::CORNERSIN },
				{ XML_CORNERSOUT,			TransitionSubType::CORNERSOUT },
				{ XML_VERTICAL,				TransitionSubType::VERTICAL },
				{ XML_HORIZONTAL,			TransitionSubType::HORIZONTAL },
				{ XML_DIAGONALBOTTOMLEFT,	TransitionSubType::DIAGONALBOTTOMLEFT },
				{ XML_DIAGONALTOPLEFT,		TransitionSubType::DIAGONALTOPLEFT },
				{ XML_DOUBLEBARNDOOR,		TransitionSubType::DOUBLEBARNDOOR },
				{ XML_DOUBLEDIAMOND,		TransitionSubType::DOUBLEDIAMOND },
				{ XML_DOWN,					TransitionSubType::DOWN },
				{ XML_LEFT,					TransitionSubType::LEFT },
				{ XML_UP,					TransitionSubType::UP },
				{ XML_RIGHT,				TransitionSubType::RIGHT },
				{ XML_RECTANGLE,			TransitionSubType::RECTANGLE },
				{ XML_DIAMOND,				TransitionSubType::DIAMOND },
				{ XML_CIRCLE,				TransitionSubType::CIRCLE },
				{ XML_FOURPOINT,			TransitionSubType::FOURPOINT },
				{ XML_FIVEPOINT,			TransitionSubType::FIVEPOINT },
				{ XML_SIXPOINT,				TransitionSubType::SIXPOINT },
				{ XML_HEART,				TransitionSubType::HEART },
				{ XML_KEYHOLE,				TransitionSubType::KEYHOLE },
				{ XML_CLOCKWISETWELVE,		TransitionSubType::CLOCKWISETWELVE },
				{ XML_CLOCKWISETHREE,		TransitionSubType::CLOCKWISETHREE },
				{ XML_CLOCKWISESIX,			TransitionSubType::CLOCKWISESIX },
				{ XML_CLOCKWISENINE,		TransitionSubType::CLOCKWISENINE },
				{ XML_TWOBLADEVERTICAL,		TransitionSubType::TWOBLADEVERTICAL },
				{ XML_TWOBLADEHORIZONTAL,	TransitionSubType::TWOBLADEHORIZONTAL },
				{ XML_FOURBLADE,			TransitionSubType::FOURBLADE },
				{ XML_CLOCKWISETOP,			TransitionSubType::CLOCKWISETOP },
				{ XML_CLOCKWISERIGHT,		TransitionSubType::CLOCKWISERIGHT },
				{ XML_CLOCKWISEBOTTOM,		TransitionSubType::CLOCKWISEBOTTOM },
				{ XML_CLOCKWISELEFT,		TransitionSubType::CLOCKWISELEFT },
				{ XML_CLOCKWISETOPLEFT,		TransitionSubType::CLOCKWISETOPLEFT },
				{ XML_COUNTERCLOCKWISEBOTTOMLEFT,TransitionSubType::COUNTERCLOCKWISEBOTTOMLEFT },
				{ XML_CLOCKWISEBOTTOMRIGHT,	TransitionSubType::CLOCKWISEBOTTOMRIGHT },
				{ XML_COUNTERCLOCKWISETOPRIGHT,TransitionSubType::COUNTERCLOCKWISETOPRIGHT },
				{ XML_CENTERTOP,			TransitionSubType::CENTERTOP },
				{ XML_CENTERRIGHT,			TransitionSubType::CENTERRIGHT },
				{ XML_TOP,					TransitionSubType::TOP },
				{ XML_BOTTOM,				TransitionSubType::BOTTOM },
				{ XML_FANOUTVERTICAL,		TransitionSubType::FANOUTVERTICAL },
				{ XML_FANOUTHORIZONTAL,		TransitionSubType::FANOUTHORIZONTAL },
				{ XML_FANINVERTICAL,		TransitionSubType::FANINVERTICAL },
				{ XML_FANINHORIZONTAL,		TransitionSubType::FANINHORIZONTAL },
				{ XML_PARALLELVERTICAL,		TransitionSubType::PARALLELVERTICAL },
				{ XML_PARALLELDIAGONAL,		TransitionSubType::PARALLELDIAGONAL },
				{ XML_OPPOSITEVERTICAL,		TransitionSubType::OPPOSITEVERTICAL },
				{ XML_OPPOSITEHORIZONTAL,	TransitionSubType::OPPOSITEHORIZONTAL },
				{ XML_PARALLELDIAGONALTOPLEFT,TransitionSubType::PARALLELDIAGONALTOPLEFT },
				{ XML_PARALLELDIAGONALBOTTOMLEFT,TransitionSubType::PARALLELDIAGONALBOTTOMLEFT },
				{ XML_TOPLEFTHORIZONTAL,	TransitionSubType::TOPLEFTHORIZONTAL },
				{ XML_TOPLEFTDIAGONAL,		TransitionSubType::TOPLEFTDIAGONAL },
				{ XML_TOPRIGHTDIAGONAL,		TransitionSubType::TOPRIGHTDIAGONAL },
				{ XML_BOTTOMRIGHTDIAGONAL,	TransitionSubType::BOTTOMRIGHTDIAGONAL },
				{ XML_BOTTOMLEFTDIAGONAL,	TransitionSubType::BOTTOMLEFTDIAGONAL },
				{ XML_TOPLEFTCLOCKWISE,		TransitionSubType::TOPLEFTCLOCKWISE },
				{ XML_TOPRIGHTCLOCKWISE,	TransitionSubType::TOPRIGHTCLOCKWISE },
				{ XML_BOTTOMRIGHTCLOCKWISE,	TransitionSubType::BOTTOMRIGHTCLOCKWISE },
				{ XML_BOTTOMLEFTCLOCKWISE,	TransitionSubType::BOTTOMLEFTCLOCKWISE },
				{ XML_TOPLEFTCOUNTERCLOCKWISE,TransitionSubType::TOPLEFTCOUNTERCLOCKWISE },
				{ XML_TOPRIGHTCOUNTERCLOCKWISE,TransitionSubType::TOPRIGHTCOUNTERCLOCKWISE },
				{ XML_BOTTOMRIGHTCOUNTERCLOCKWISE,TransitionSubType::BOTTOMRIGHTCOUNTERCLOCKWISE },
				{ XML_BOTTOMLEFTCOUNTERCLOCKWISE,TransitionSubType::BOTTOMLEFTCOUNTERCLOCKWISE },
				{ XML_VERTICALTOPSAME,		TransitionSubType::VERTICALTOPSAME },
				{ XML_VERTICALBOTTOMSAME,	TransitionSubType::VERTICALBOTTOMSAME },
				{ XML_VERTICALTOPLEFTOPPOSITE,TransitionSubType::VERTICALTOPLEFTOPPOSITE },
				{ XML_VERTICALBOTTOMLEFTOPPOSITE,TransitionSubType::VERTICALBOTTOMLEFTOPPOSITE },
				{ XML_HORIZONTALLEFTSAME,	TransitionSubType::HORIZONTALLEFTSAME },
				{ XML_HORIZONTALRIGHTSAME,	TransitionSubType::HORIZONTALRIGHTSAME },
				{ XML_HORIZONTALTOPLEFTOPPOSITE,TransitionSubType::HORIZONTALTOPLEFTOPPOSITE },
				{ XML_HORIZONTALTOPRIGHTOPPOSITE,TransitionSubType::HORIZONTALTOPRIGHTOPPOSITE },
				{ XML_DIAGONALBOTTOMLEFTOPPOSITE,TransitionSubType::DIAGONALBOTTOMLEFTOPPOSITE },
				{ XML_DIAGONALTOPLEFTOPPOSITE,TransitionSubType::DIAGONALTOPLEFTOPPOSITE },
				{ XML_TWOBOXTOP,			TransitionSubType::TWOBOXTOP },
				{ XML_TWOBOXBOTTOM,			TransitionSubType::TWOBOXBOTTOM },
				{ XML_TWOBOXLEFT,			TransitionSubType::TWOBOXLEFT },
				{ XML_TWOBOXRIGHT,			TransitionSubType::TWOBOXRIGHT },
				{ XML_FOURBOXVERTICAL,		TransitionSubType::FOURBOXVERTICAL },
				{ XML_FOURBOXHORIZONTAL,	TransitionSubType::FOURBOXHORIZONTAL },
				{ XML_VERTICALLEFT,			TransitionSubType::VERTICALLEFT },
				{ XML_VERTICALRIGHT,		TransitionSubType::VERTICALRIGHT },
				{ XML_HORIZONTALLEFT,		TransitionSubType::HORIZONTALLEFT },
				{ XML_HORIZONTALRIGHT,		TransitionSubType::HORIZONTALRIGHT },
				{ XML_FROMLEFT,				TransitionSubType::FROMLEFT },
				{ XML_FROMTOP,				TransitionSubType::FROMTOP },
				{ XML_FROMRIGHT,			TransitionSubType::FROMRIGHT },
				{ XML_FROMBOTTOM,			TransitionSubType::FROMBOTTOM },
				{ XML_CROSSFADE,			TransitionSubType::CROSSFADE },
				{ XML_FADETOCOLOR,			TransitionSubType::FADETOCOLOR },
				{ XML_FADEFROMCOLOR,		TransitionSubType::FADEFROMCOLOR },
				{ XML_FADEOVERCOLOR,		TransitionSubType::FADEOVERCOLOR },
				{ XML_THREEBLADE,			TransitionSubType::THREEBLADE },
				{ XML_EIGHTBLADE,			TransitionSubType::EIGHTBLADE },
				{ XML_ONEBLADE,				TransitionSubType::ONEBLADE },
				{ XML_ACROSS,				TransitionSubType::ACROSS },
                { XML_TOPLEFTVERTICAL,      TransitionSubType::TOPLEFTVERTICAL },
				{ XML_COMBHORIZONTAL,		TransitionSubType::COMBHORIZONTAL },
				{ XML_COMBVERTICAL,			TransitionSubType::COMBVERTICAL },
				{ XML_IN,					TransitionSubType::IN },
				{ XML_OUT,					TransitionSubType::OUT },
				{ XML_ROTATEIN,				TransitionSubType::ROTATEIN },
				{ XML_ROTATEOUT,			TransitionSubType::ROTATEOUT },
				{ XML_FROMTOPLEFT,			TransitionSubType::FROMTOPLEFT },
				{ XML_FROMTOPRIGHT,			TransitionSubType::FROMTOPRIGHT },
				{ XML_FROMBOTTOMLEFT,		TransitionSubType::FROMBOTTOMLEFT },
				{ XML_FROMBOTTOMRIGHT,		TransitionSubType::FROMBOTTOMRIGHT },

				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_TransitionSubType;
		}
	case Animations_EnumMap_EventTrigger:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_EventTrigger[] =
			{
				{ XML_ONBEGIN,			EventTrigger::ON_BEGIN },
				{ XML_ONEND,			EventTrigger::ON_END },
				{ XML_BEGIN,			EventTrigger::BEGIN_EVENT },
				{ XML_END,				EventTrigger::END_EVENT },
				{ XML_CLICK,			EventTrigger::ON_CLICK },
				{ XML_DOUBLECLICK,		EventTrigger::ON_DBL_CLICK },
				{ XML_MOUSEOVER,		EventTrigger::ON_MOUSE_ENTER },
				{ XML_MOUSEOUT,			EventTrigger::ON_MOUSE_LEAVE },
				{ XML_NEXT,				EventTrigger::ON_NEXT },
				{ XML_PREVIOUS,			EventTrigger::ON_PREV },
				{ XML_STOP_AUDIO,		EventTrigger::ON_STOP_AUDIO },
				{ XML_REPEAT,			EventTrigger::REPEAT },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_EventTrigger;
		}

	case Animations_EnumMap_EffectPresetClass:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_EffectPresetClass[] =
			{
				{ XML_CUSTOM,		EffectPresetClass::CUSTOM },
				{ XML_ENTRANCE,		EffectPresetClass::ENTRANCE },
				{ XML_EXIT,			EffectPresetClass::EXIT },
				{ XML_EMPHASIS,		EffectPresetClass::EMPHASIS },
				{ XML_MOTION_PATH,	EffectPresetClass::MOTIONPATH },
				{ XML_OLE_ACTION,	EffectPresetClass::OLEACTION },
				{ XML_MEDIA_CALL,	EffectPresetClass::MEDIACALL },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_EffectPresetClass;
		}

	case Animations_EnumMap_EffectNodeType:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_EffectNodeType[] =
			{
				{ XML_DEFAULT,					EffectNodeType::DEFAULT },
				{ XML_ON_CLICK,					EffectNodeType::ON_CLICK },
				{ XML_WITH_PREVIOUS,			EffectNodeType::WITH_PREVIOUS },
				{ XML_AFTER_PREVIOUS,			EffectNodeType::AFTER_PREVIOUS },
				{ XML_MAIN_SEQUENCE,			EffectNodeType::MAIN_SEQUENCE },
				{ XML_TIMING_ROOT,				EffectNodeType::TIMING_ROOT },
				{ XML_INTERACTIVE_SEQUENCE,		EffectNodeType::INTERACTIVE_SEQUENCE },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_EffectNodeType;
		}
	case Animations_EnumMap_SubItem:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_SubItem[] =
			{
				{ XML_WHOLE,					ShapeAnimationSubType::AS_WHOLE },
				{ XML_BACKGROUND,				ShapeAnimationSubType::ONLY_BACKGROUND },
				{ XML_TEXT,						ShapeAnimationSubType::ONLY_TEXT },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_SubItem;
		}
	case Animations_EnumMap_IterateType:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_IterateType[] =
			{
				{ XML_BY_PARAGRAPH,				TextAnimationType::BY_PARAGRAPH },
				{ XML_BY_WORD,					TextAnimationType::BY_WORD },
				{ XML_BY_LETTER,				TextAnimationType::BY_LETTER },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_IterateType;
		}
	case Animations_EnumMap_Command:
		{
			static SvXMLEnumMapEntry aAnimations_EnumMap_Command[] =
			{
				{ XML_CUSTOM,					EffectCommands::CUSTOM },
				{ XML_VERB,						EffectCommands::VERB },
				{ XML_PLAY,						EffectCommands::PLAY },
				{ XML_TOGGLE_PAUSE,				EffectCommands::TOGGLEPAUSE },
				{ XML_STOP,						EffectCommands::STOP },
				{ XML_STOP_AUDIO,				EffectCommands::STOPAUDIO },
				{ XML_TOKEN_INVALID, 0 }
			};
			return aAnimations_EnumMap_Command;
		}
	}

	DBG_ERROR( "xmloff::getAnimationsEnumMap(), invalid map!" );
	return NULL;
}

struct ImplAttributeNameConversion* getAnimationAttributeNamesConversionList()
{
	static struct ImplAttributeNameConversion gImplConversionList[] =
	{
		{ XML_X,						"X" },
		{ XML_Y,						"Y" },
		{ XML_WIDTH,					"Width" },
		{ XML_HEIGHT,					"Height" },
		{ XML_ROTATE,					"Rotate" },
		{ XML_SKEWX,					"SkewX" },
		{ XML_FILL_COLOR,				"FillColor" },
		{ XML_FILL,						"FillStyle" },
		{ XML_STROKE_COLOR,				"LineColor" },
		{ XML_STROKE,					"LineStyle" },
		{ XML_COLOR,					"CharColor" },
		{ XML_TEXT_ROTATION_ANGLE,		"CharRotation" },
		{ XML_FONT_WEIGHT,				"CharWeight" },
		{ XML_TEXT_UNDERLINE,			"CharUnderline" },
		{ XML_FONT_FAMILY,				"CharFontName" },
		{ XML_FONT_SIZE,				"CharHeight" },
		{ XML_FONT_STYLE,				"CharPosture" },
		{ XML_VISIBILITY,				"Visibility" },
		{ XML_OPACITY,					"Opacity" },
		{ XML_DIM,						"DimColor" },
		{ XML_TOKEN_INVALID,			NULL }
	};

	return gImplConversionList;
}


class AnimationsExporterImpl
{
public:
	AnimationsExporterImpl( SvXMLExport& rExport, const Reference< XPropertySet >& xPageProps );

	void prepareNode( const Reference< XAnimationNode >& xNode );
	void exportNode( const Reference< XAnimationNode >& xNode );

	void exportContainer( const Reference< XTimeContainer >& xNode, sal_Int16 nContainerNodeType );
	void exportAnimate( const Reference< XAnimate >& xNode );
	void exportAudio( const Reference< XAudio >& xAudio );
	void exportCommand( const Reference< XCommand >& xCommand );

	Reference< XInterface > getParagraphTarget( const ParagraphTarget* pTarget ) const;

	void convertPath( OUStringBuffer& sTmp, const Any& rPath );
	void convertValue( XMLTokenEnum eAttributeName, OUStringBuffer& sTmp, const Any& rValue );
	void convertTiming( OUStringBuffer& sTmp, const Any& rTiming );
	void convertSource( OUStringBuffer& sTmp, const Any& rSource );
	void convertTarget( OUStringBuffer& sTmp, const Any& rTarget );

	void prepareValue( const Any& rValue );

	void exportTransitionNode();
	void prepareTransitionNode();

	bool mbHasTransition;
private:
	SvXMLExport& mrExport;
	Reference< XInterface > mxExport;
	Reference< XPropertySet > mxPageProps;
};

AnimationsExporterImpl::AnimationsExporterImpl( SvXMLExport& rExport, const Reference< XPropertySet >& xPageProps )
: mbHasTransition(false)
, mrExport( rExport )
, mxPageProps( xPageProps )
{
	try
	{
		mxExport = static_cast< ::com::sun::star::document::XFilter *>(&rExport);
	}
	catch( RuntimeException& )
	{
		DBG_ERROR( "xmloff::AnimationsExporterImpl::AnimationsExporterImpl(), RuntimeException catched!" );
	}
}

void AnimationsExporterImpl::exportTransitionNode()
{
	if( mbHasTransition && mxPageProps.is() )
	{
		sal_Int16 nTransition = 0;
		mxPageProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionType" ) ) ) >>= nTransition;

		Any aSound( mxPageProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Sound" ) ) ) );
		OUString sSoundURL;
		aSound >>= sSoundURL;
		sal_Bool bStopSound = sal_False;
		if( !(aSound >>= bStopSound) )
			bStopSound = sal_False;


		OUStringBuffer sTmp;
		if( (nTransition != 0) || (sSoundURL.getLength() != 0) || bStopSound )
		{
			Reference< XInterface > xSource( mxPageProps.get() );
			Event aEvent;
			aEvent.Source <<= xSource;
			aEvent.Trigger = EventTrigger::BEGIN_EVENT;
			aEvent.Repeat = 0;

			convertTiming( sTmp, Any( aEvent ) );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_BEGIN, sTmp.makeStringAndClear() );

			SvXMLElementExport aElement( mrExport, XML_NAMESPACE_ANIMATION, XML_PAR, sal_True, sal_True );

			if( nTransition != 0 )
			{
				sal_Int16 nSubtype = 0;
				sal_Bool bDirection = sal_False;
				sal_Int32 nFadeColor = 0;
				double fDuration = 0.0;
				mxPageProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionSubtype" ) ) ) >>= nSubtype;
				mxPageProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionDirection" ) ) ) >>= bDirection;
				mxPageProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionFadeColor" ) ) ) >>= nFadeColor;
				mxPageProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionDuration" ) ) ) >>= fDuration;

				SvXMLUnitConverter::convertDouble( sTmp, fDuration );
				sTmp.append( sal_Unicode('s'));
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_DUR, sTmp.makeStringAndClear() );

				SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nTransition, getAnimationsEnumMap(Animations_EnumMap_TransitionType) );
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_TYPE, sTmp.makeStringAndClear() );

				if( nSubtype != TransitionSubType::DEFAULT )
				{
					SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nSubtype, getAnimationsEnumMap(Animations_EnumMap_TransitionSubType) );
					mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_SUBTYPE, sTmp.makeStringAndClear() );
				}

				if( !bDirection )
					mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_DIRECTION, XML_REVERSE );

				if( (nTransition == TransitionType::FADE) && ((nSubtype == TransitionSubType::FADETOCOLOR) || (nSubtype == TransitionSubType::FADEFROMCOLOR) ))
				{
					SvXMLUnitConverter::convertColor( sTmp, nFadeColor );
					mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_FADECOLOR, sTmp.makeStringAndClear() );
				}
				SvXMLElementExport aElement2( mrExport, XML_NAMESPACE_ANIMATION, XML_TRANSITIONFILTER, sal_True, sal_True );
			}

			if( bStopSound )
			{
				mrExport.AddAttribute( XML_NAMESPACE_ANIMATION, XML_COMMAND, XML_STOP_AUDIO );
				SvXMLElementExport aElement2( mrExport, XML_NAMESPACE_ANIMATION, XML_COMMAND, sal_True, sal_True );
			}
			else if( sSoundURL.getLength() != 0)
			{
				mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, mrExport.GetRelativeReference( sSoundURL ) );

				sal_Bool bLoopSound = sal_False;
				mxPageProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "LoopSound" ) ) ) >>= bLoopSound;

				if( bLoopSound )
					mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_REPEATCOUNT, XML_INDEFINITE );
				SvXMLElementExport aElement2( mrExport, XML_NAMESPACE_ANIMATION, XML_AUDIO, sal_True, sal_True );
			}
		}
	}
}

void AnimationsExporterImpl::prepareTransitionNode()
{
	if( mxPageProps.is() ) try
	{
		sal_Int16 nTransition = 0;
		mxPageProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionType" ) ) ) >>= nTransition;

		sal_Bool bStopSound = sal_False;
		OUString sSoundURL;

		if( nTransition == 0 )
		{
			Any aSound( mxPageProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Sound" ) ) ) );
			aSound >>= sSoundURL;

			if( !(aSound >>= bStopSound) )
				bStopSound = sal_False;
		}

		if( (nTransition != 0) || (sSoundURL.getLength() != 0) || bStopSound )
		{
			mbHasTransition = true;
			Reference< XInterface > xInt( mxPageProps.get() );
			mrExport.getInterfaceToIdentifierMapper().registerReference( xInt );
		}
	}
	catch( Exception& )
	{
		DBG_ERROR( "xmloff::AnimationsExporterImpl::prepareNode(), Exception caught!" );
	}

}

void AnimationsExporterImpl::prepareNode( const Reference< XAnimationNode >& xNode )
{
	try
	{
		prepareValue( xNode->getBegin() );
		prepareValue( xNode->getEnd() );

		sal_Int16 nNodeType = xNode->getType();
		switch( nNodeType )
		{
		case AnimationNodeType::ITERATE:
		{
			Reference< XIterateContainer > xIter( xNode, UNO_QUERY_THROW );
			prepareValue( xIter->getTarget() );
		}
		// its intended that here is no break!
		case AnimationNodeType::PAR:
		case AnimationNodeType::SEQ:
		{
			Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY_THROW );
			Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
			while( xEnumeration->hasMoreElements() )
			{
				Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
				prepareNode( xChildNode );
			}
		}
		break;

		case AnimationNodeType::ANIMATE:
		case AnimationNodeType::SET:
		case AnimationNodeType::ANIMATEMOTION:
		case AnimationNodeType::ANIMATECOLOR:
		case AnimationNodeType::ANIMATETRANSFORM:
		case AnimationNodeType::TRANSITIONFILTER:
		{
			Reference< XAnimate > xAnimate( xNode, UNO_QUERY_THROW );
			prepareValue( xAnimate->getTarget() );
		}
		break;

		case AnimationNodeType::COMMAND:
		{
			Reference< XCommand > xCommand( xNode, UNO_QUERY_THROW );
			prepareValue( xCommand->getTarget() );
		}
		break;

		case AnimationNodeType::AUDIO:
		{
			Reference< XAudio > xAudio( xNode, UNO_QUERY_THROW );
			prepareValue( xAudio->getSource() );
		}
		break;
		}

		Sequence< NamedValue > aUserData( xNode->getUserData() );
		if( aUserData.hasElements() )
		{
			const NamedValue* pValue = aUserData.getConstArray();
			const sal_Int32 nLength = aUserData.getLength();
			sal_Int32 nElement;
			for( nElement = 0; nElement < nLength; nElement++, pValue++ )
			{
				if( IsXMLToken( pValue->Name, XML_MASTER_ELEMENT ) )
				{
					Reference< XInterface > xMaster;
					pValue->Value >>= xMaster;
					if( xMaster.is() )
						mrExport.getInterfaceToIdentifierMapper().registerReference( xMaster );
				}
			}
		}
	}
	catch( Exception& )
	{
		DBG_ERROR( "xmloff::AnimationsExporterImpl::prepareNode(), RuntimeException catched!" );
	}
}

void AnimationsExporterImpl::exportNode( const Reference< XAnimationNode >& xNode )
{
	try
	{
		OUStringBuffer sTmp;

        const OUString& rExportIdentifier = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xNode );
		if( rExportIdentifier.getLength() )
        {
            mrExport.AddAttributeIdLegacy(
                XML_NAMESPACE_ANIMATION, rExportIdentifier);
        }

		Any aTemp( xNode->getBegin() );
		if( aTemp.hasValue() )
		{
			convertTiming( sTmp, aTemp );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_BEGIN, sTmp.makeStringAndClear() );
		}

		double fTemp = 0;
		sal_Int32 nTemp;

		aTemp = xNode->getDuration();
		if( aTemp.hasValue() )
		{
			if( aTemp >>= fTemp )
			{
				SvXMLUnitConverter::convertDouble( sTmp, fTemp );
				sTmp.append( sal_Unicode('s'));
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_DUR, sTmp.makeStringAndClear() );
			}
			else
			{
				Timing eTiming;
				if( aTemp >>= eTiming )
					mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_DUR, eTiming == Timing_INDEFINITE ? XML_INDEFINITE : XML_MEDIA );
			}
		}

		aTemp = xNode->getEnd();
		if( aTemp.hasValue() )
		{
			convertTiming( sTmp, aTemp );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_END, sTmp.makeStringAndClear() );
		}

		nTemp = xNode->getFill();
		if( nTemp != AnimationFill::DEFAULT )
		{
			SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nTemp, getAnimationsEnumMap(Animations_EnumMap_Fill) );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_FILL, sTmp.makeStringAndClear() );
		}

		nTemp = xNode->getFillDefault();
		if( nTemp != AnimationFill::INHERIT )
		{
			SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nTemp, getAnimationsEnumMap(Animations_EnumMap_FillDefault) );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_FILLDEFAULT, sTmp.makeStringAndClear() );
		}

		nTemp = xNode->getRestart();
		if( nTemp != AnimationRestart::DEFAULT )
		{
			SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nTemp, getAnimationsEnumMap(Animations_EnumMap_Restart) );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_RESTART, sTmp.makeStringAndClear() );
		}

		nTemp = xNode->getRestartDefault();
		if( nTemp != AnimationRestart::INHERIT )
		{
			SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nTemp, getAnimationsEnumMap(Animations_EnumMap_RestartDefault) );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_RESTARTDEFAULT, sTmp.makeStringAndClear() );
		}

		fTemp = xNode->getAcceleration();
		if( fTemp != 0.0 )
		{
			SvXMLUnitConverter::convertDouble( sTmp, fTemp );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_ACCELERATE, sTmp.makeStringAndClear() );
		}

		fTemp = xNode->getDecelerate();
		if( fTemp != 0.0 )
		{
			SvXMLUnitConverter::convertDouble( sTmp, fTemp );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_DECELERATE, sTmp.makeStringAndClear() );
		}

		sal_Bool bTemp = xNode->getAutoReverse();
		if( bTemp )
		{
			SvXMLUnitConverter::convertBool( sTmp, bTemp );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_AUTOREVERSE, sTmp.makeStringAndClear() );
		}

		aTemp = xNode->getRepeatCount();
		if( aTemp.hasValue() )
		{
			Timing eTiming;
			if( (aTemp >>= eTiming ) && (eTiming == Timing_INDEFINITE ) )
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_REPEATCOUNT, XML_INDEFINITE );
			else if( aTemp >>= fTemp )
			{
				SvXMLUnitConverter::convertDouble( sTmp, fTemp );
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_REPEATCOUNT, sTmp.makeStringAndClear() );
			}
		}

		aTemp = xNode->getRepeatDuration();
		if( aTemp.hasValue() )
		{
			Timing eTiming;
			if( ( aTemp >>= eTiming ) && (eTiming == Timing_INDEFINITE) )
			{
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_REPEATDUR, XML_INDEFINITE );
			}
			else if( aTemp >>= fTemp )
			{
				SvXMLUnitConverter::convertDouble( sTmp, fTemp );
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_REPEATDUR, sTmp.makeStringAndClear() );
			}
		}

		aTemp = xNode->getEndSync();
		if( aTemp.hasValue() )
		{
			if( aTemp >>= nTemp )
			{
				SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nTemp, getAnimationsEnumMap(Animations_EnumMap_Endsync) );
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_ENDSYNC, sTmp.makeStringAndClear() );
			}
		}

		sal_Int16 nContainerNodeType = EffectNodeType::DEFAULT;
		OUString aPresetId;
		Sequence< NamedValue > aUserData( xNode->getUserData() );
		if( aUserData.hasElements() )
		{
			const NamedValue* pValue = aUserData.getConstArray();
			const sal_Int32 nLength = aUserData.getLength();
			sal_Int32 nElement;
			for( nElement = 0; nElement < nLength; nElement++, pValue++ )
			{
				if( IsXMLToken( pValue->Name, XML_NODE_TYPE ) )
				{
					if( (pValue->Value >>= nContainerNodeType) && (nContainerNodeType != EffectNodeType::DEFAULT) )
					{
						SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nContainerNodeType, getAnimationsEnumMap(Animations_EnumMap_EffectNodeType) );
						mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_NODE_TYPE, sTmp.makeStringAndClear() );
					}
				}
				else if( IsXMLToken( pValue->Name, XML_PRESET_ID ) )
				{
					if( pValue->Value >>= aPresetId )
					{
						mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PRESET_ID, aPresetId );
					}
				}
				else if( IsXMLToken( pValue->Name, XML_PRESET_SUB_TYPE ) )
				{
					OUString aPresetSubType;
					if( pValue->Value >>= aPresetSubType )
					{
						mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PRESET_SUB_TYPE, aPresetSubType );
					}
				}
				else if( IsXMLToken( pValue->Name, XML_PRESET_CLASS ) )
				{
					sal_Int16 nEffectPresetClass = sal_Int16();
					if( pValue->Value >>= nEffectPresetClass )
					{
						SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nEffectPresetClass, getAnimationsEnumMap(Animations_EnumMap_EffectPresetClass) );
						mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PRESET_CLASS, sTmp.makeStringAndClear() );
					}
				}
				else if( IsXMLToken( pValue->Name, XML_MASTER_ELEMENT ) )
				{
					Reference< XInterface > xMaster;
					pValue->Value >>= xMaster;
					if( xMaster.is() )
					{
						const OUString& rIdentifier = mrExport.getInterfaceToIdentifierMapper().getIdentifier(xMaster);
						if( rIdentifier.getLength() )
							mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_MASTER_ELEMENT, rIdentifier );
					}
				}
				else if( IsXMLToken( pValue->Name, XML_GROUP_ID ) )
				{
					sal_Int32 nGroupId = 0;
					if( pValue->Value >>= nGroupId )
						mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_GROUP_ID, OUString::valueOf( nGroupId ) );
				}
				else
				{
					OUString aTmp;
					if( pValue->Value >>= aTmp )
						mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, pValue->Name, aTmp );
				}
			}
		}

		nTemp = xNode->getType();
		switch( nTemp )
		{
		case AnimationNodeType::PAR:
		case AnimationNodeType::SEQ:
		case AnimationNodeType::ITERATE:
		{
			Reference< XTimeContainer > xContainer( xNode, UNO_QUERY_THROW );
			exportContainer( xContainer, nContainerNodeType );
		}
		break;

		case AnimationNodeType::ANIMATE:
		case AnimationNodeType::SET:
		case AnimationNodeType::ANIMATEMOTION:
		case AnimationNodeType::ANIMATECOLOR:
		case AnimationNodeType::ANIMATETRANSFORM:
		case AnimationNodeType::TRANSITIONFILTER:
		{
			Reference< XAnimate > xAnimate( xNode, UNO_QUERY_THROW );
			exportAnimate( xAnimate );
		}
		break;
		case AnimationNodeType::AUDIO:
		{
			Reference< XAudio > xAudio( xNode, UNO_QUERY_THROW );
			exportAudio( xAudio );
		}
		break;
		case AnimationNodeType::COMMAND:
		{
			Reference< XCommand > xCommand( xNode, UNO_QUERY_THROW );
			exportCommand( xCommand );
		}
		break;
		default:
			DBG_ERROR( "xmloff::AnimationsExporterImpl::exportNode(), invalid AnimationNodeType!" );
		}
	}
	catch( RuntimeException& )
	{
		DBG_ERROR( "xmloff::AnimationsExporterImpl::exportNode(), RuntimeException catched!" );
	}

	// if something goes wrong, its always a good idea to clear the attribute list
	mrExport.ClearAttrList();
}

void AnimationsExporterImpl::exportContainer( const Reference< XTimeContainer >& xContainer, sal_Int16 nContainerNodeType )
{
	try
	{
		const sal_Int32 nNodeType = xContainer->getType();

		if( nNodeType == AnimationNodeType::ITERATE )
		{
			OUStringBuffer sTmp;
			Reference< XIterateContainer > xIter( xContainer, UNO_QUERY_THROW );

			Any aTemp( xIter->getTarget() );
			if( aTemp.hasValue() )
			{
				convertTarget( sTmp, aTemp );
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_TARGETELEMENT, sTmp.makeStringAndClear() );
			}

			sal_Int16 nTemp = xIter->getSubItem();
			if( nTemp )
			{
				SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nTemp, getAnimationsEnumMap(Animations_EnumMap_SubItem) );
				mrExport.AddAttribute( XML_NAMESPACE_ANIMATION, XML_SUB_ITEM, sTmp.makeStringAndClear() );
			}

			nTemp = xIter->getIterateType();
			if( nTemp )
			{
				SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nTemp, getAnimationsEnumMap(Animations_EnumMap_IterateType) );
				mrExport.AddAttribute( XML_NAMESPACE_ANIMATION, XML_ITERATE_TYPE, sTmp.makeStringAndClear() );
			}

			double fTemp = xIter->getIterateInterval();
			if( fTemp )
			{
				if( 0 == ( mrExport.getExportFlags() & EXPORT_SAVEBACKWARDCOMPATIBLE ) )
				{
					// issue 146582
					sal_Int32 nSecondsFraction = static_cast<sal_Int32>(fTemp * 1000 ) % 1000;
					::Time aTime( static_cast<sal_Int32>( fTemp * 100 ) );
					mrExport.AddAttribute( XML_NAMESPACE_ANIMATION, XML_ITERATE_INTERVAL, SvXMLUnitConverter::convertTimeDuration( aTime, nSecondsFraction ) );
				}
				else
				{
					sTmp.append( fTemp );
					sTmp.append( (sal_Unicode)'s' );
					mrExport.AddAttribute( XML_NAMESPACE_ANIMATION, XML_ITERATE_INTERVAL, sTmp.makeStringAndClear() );
				}
			}
		}

		XMLTokenEnum eElementToken;
		switch( nNodeType )
		{
		case AnimationNodeType::PAR:	eElementToken = XML_PAR; break;
		case AnimationNodeType::SEQ:	eElementToken = XML_SEQ; break;
		case AnimationNodeType::ITERATE:eElementToken = XML_ITERATE; break;
		default:
			DBG_ERROR( "xmloff::AnimationsExporterImpl::exportContainer(), invalid TimeContainerType!" );
			return;
		}
		SvXMLElementExport aElement( mrExport, XML_NAMESPACE_ANIMATION, eElementToken, sal_True, sal_True );

		if( nContainerNodeType == EffectNodeType::TIMING_ROOT )
			exportTransitionNode();

		Reference< XEnumerationAccess > xEnumerationAccess( xContainer, UNO_QUERY_THROW );
		Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
		while( xEnumeration->hasMoreElements() )
		{
			Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
			exportNode( xChildNode );
		}
	}
	catch( RuntimeException& )
	{
		DBG_ERROR( "xmloff::AnimationsExporterImpl::exportContainer(), RuntimeException catched!" );
	}
}

void AnimationsExporterImpl::exportAnimate( const Reference< XAnimate >& xAnimate )
{
	try
	{
		const sal_Int16 nNodeType = xAnimate->getType();

		OUStringBuffer sTmp;
		sal_Int32 nTemp;
		sal_Bool bTemp;

		Any aTemp( xAnimate->getTarget() );
		if( aTemp.hasValue() )
		{
			convertTarget( sTmp, aTemp );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_TARGETELEMENT, sTmp.makeStringAndClear() );
		}

		nTemp = xAnimate->getSubItem();
		if( nTemp )
		{
			SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nTemp, getAnimationsEnumMap(Animations_EnumMap_SubItem) );
			mrExport.AddAttribute( XML_NAMESPACE_ANIMATION, XML_SUB_ITEM, sTmp.makeStringAndClear() );
		}

		XMLTokenEnum eAttributeName = XML_TOKEN_INVALID;

		if( nNodeType == AnimationNodeType::TRANSITIONFILTER )
		{
			eAttributeName = XML_TRANSITIONFILTER;
		}
		else if( nNodeType == AnimationNodeType::ANIMATETRANSFORM )
		{
			eAttributeName = XML_ANIMATETRANSFORM;
		}
		else if( nNodeType == AnimationNodeType::ANIMATEMOTION )
		{
			eAttributeName = XML_ANIMATEMOTION;
		}
		else
		{
			OUString sTemp( xAnimate->getAttributeName() );
			if( sTemp.getLength() )
			{
				ImplAttributeNameConversion* p = getAnimationAttributeNamesConversionList();
				while( p->mpAPIName )
				{
					if( sTemp.compareToAscii( p->mpAPIName ) == 0 )
					{
						sTemp = GetXMLToken( p->meXMLToken );
						eAttributeName = p->meXMLToken;
						break;
					}

					p++;
				}

				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_ATTRIBUTENAME, sTemp );
			}
			else
			{
				OUString aStr( RTL_CONSTASCII_USTRINGPARAM( "invalid" ) );
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_ATTRIBUTENAME, aStr );
			}
		}

		Sequence< Any > aValues( xAnimate->getValues() );
		if( aValues.getLength() )
		{
			aTemp <<= aValues;
			convertValue( eAttributeName, sTmp, aTemp );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_VALUES, sTmp.makeStringAndClear() );
		}
		else
		{
			aTemp = xAnimate->getFrom();
			if( aTemp.hasValue() )
			{
				convertValue( eAttributeName, sTmp, aTemp );
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_FROM, sTmp.makeStringAndClear() );
			}

			aTemp = xAnimate->getBy();
			if( aTemp.hasValue() )
			{
				convertValue( eAttributeName, sTmp, aTemp );
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_BY, sTmp.makeStringAndClear() );
			}

			aTemp = xAnimate->getTo();
			if( aTemp.hasValue() )
			{
				convertValue( eAttributeName, sTmp, aTemp );
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_TO, sTmp.makeStringAndClear() );
			}
		}

		if(nNodeType != AnimationNodeType::SET)
		{
			Sequence< double > aKeyTimes( xAnimate->getKeyTimes() );
			if( aKeyTimes.getLength() )
			{
				sal_Int32 nLength = aKeyTimes.getLength();
				const double* p = aKeyTimes.getConstArray();

				while( nLength-- )
				{
					if( sTmp.getLength() )
						sTmp.append( (sal_Unicode)';' );

					sTmp.append( *p++ );
				}
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_KEYTIMES, sTmp.makeStringAndClear() );
			}

			OUString sTemp( xAnimate->getFormula() );
			if( sTemp.getLength() )
				mrExport.AddAttribute( XML_NAMESPACE_ANIMATION, XML_FORMULA, sTemp );

			if( (nNodeType != AnimationNodeType::TRANSITIONFILTER) &&
				(nNodeType != AnimationNodeType::AUDIO ) )
			{
				// calcMode  = "discrete | linear | paced | spline"
				nTemp = xAnimate->getCalcMode();
				if( ((nNodeType == AnimationNodeType::ANIMATEMOTION ) && (nTemp != AnimationCalcMode::PACED)) ||
					((nNodeType != AnimationNodeType::ANIMATEMOTION ) && (nTemp != AnimationCalcMode::LINEAR)) )
				{
					SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nTemp, getAnimationsEnumMap(Animations_EnumMap_CalcMode) );
					mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_CALCMODE, sTmp.makeStringAndClear() );
				}

				bTemp = xAnimate->getAccumulate();
				if( bTemp )
					mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_ACCUMULATE, XML_SUM );

				nTemp = xAnimate->getAdditive();
				if( nTemp != AnimationAdditiveMode::REPLACE )
				{
					SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nTemp, getAnimationsEnumMap(Animations_EnumMap_AdditiveMode) );
					mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_ADDITIVE, sTmp.makeStringAndClear() );
				}
			}

			Sequence< TimeFilterPair > aTimeFilter( xAnimate->getTimeFilter() );
			if( aTimeFilter.getLength() )
			{
				sal_Int32 nLength = aTimeFilter.getLength();
				const TimeFilterPair* p = aTimeFilter.getConstArray();

				while( nLength-- )
				{
					if( sTmp.getLength() )
						sTmp.append( (sal_Unicode)';' );

					sTmp.append( p->Time );
					sTmp.append( (sal_Unicode)',' );
					sTmp.append( p->Progress );

					p++;
				}

				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_KEYSPLINES, sTmp.makeStringAndClear() );
			}
		}

		XMLTokenEnum eElementToken = XML_ANIMATE;

		switch( nNodeType )
		{
		case AnimationNodeType::ANIMATE:
			eElementToken = XML_ANIMATE;
			break;

		case AnimationNodeType::SET:
			eElementToken = XML_SET;
			break;

		case AnimationNodeType::ANIMATEMOTION:
		{
			eElementToken = XML_ANIMATEMOTION;

			Reference< XAnimateMotion > xAnimateMotion( xAnimate, UNO_QUERY_THROW );

			aTemp = xAnimateMotion->getPath();
			if( aTemp.hasValue() )
			{
				convertPath( sTmp, aTemp );
				mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_PATH, sTmp.makeStringAndClear() );
			}

			// TODO: origin = ( parent | layout )
			aTemp = xAnimateMotion->getOrigin();
		}
		break;

		case AnimationNodeType::ANIMATECOLOR:
		{
			eElementToken = XML_ANIMATECOLOR;

			Reference< XAnimateColor > xAnimateColor( xAnimate, UNO_QUERY_THROW );

			nTemp = xAnimateColor->getColorInterpolation();
			mrExport.AddAttribute( XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION, (nTemp == AnimationColorSpace::RGB) ? XML_RGB : XML_HSL );

			bTemp = xAnimateColor->getDirection();
			mrExport.AddAttribute( XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION_DIRECTION, bTemp ? XML_CLOCKWISE : XML_COUNTER_CLOCKWISE );
		}
		break;

		case AnimationNodeType::ANIMATETRANSFORM:
		{
			eElementToken = XML_ANIMATETRANSFORM;

			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_ATTRIBUTENAME, XML_TRANSFORM );

			Reference< XAnimateTransform > xTransform( xAnimate, UNO_QUERY_THROW );
			nTemp = xTransform->getTransformType();
			SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nTemp, getAnimationsEnumMap(Animations_EnumMap_TransformType) );
			mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_TYPE, sTmp.makeStringAndClear() );
		}
		break;

		case AnimationNodeType::TRANSITIONFILTER:
		{
			Reference< XTransitionFilter > xTransitionFilter( xAnimate, UNO_QUERY );
			eElementToken = XML_TRANSITIONFILTER;

			sal_Int16 nTransition = xTransitionFilter->getTransition();
			SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nTransition, getAnimationsEnumMap(Animations_EnumMap_TransitionType) );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_TYPE, sTmp.makeStringAndClear() );

			sal_Int16 nSubtype = xTransitionFilter->getSubtype();
			if( nSubtype != TransitionSubType::DEFAULT )
			{
				SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nSubtype, getAnimationsEnumMap(Animations_EnumMap_TransitionSubType) );
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_SUBTYPE, sTmp.makeStringAndClear() );
			}

    		bTemp = xTransitionFilter->getMode();
			if( !bTemp )
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_MODE, XML_OUT );

			bTemp = xTransitionFilter->getDirection();
			if( !bTemp )
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_DIRECTION, XML_REVERSE );

			if( (nTransition == TransitionType::FADE) && ((nSubtype == TransitionSubType::FADETOCOLOR) || (nSubtype == TransitionSubType::FADEFROMCOLOR) ))
			{
				nTemp = xTransitionFilter->getFadeColor();
				SvXMLUnitConverter::convertColor( sTmp, nTemp );
				mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_FADECOLOR, sTmp.makeStringAndClear() );
			}
		}
		break;
		}

		SvXMLElementExport aElement( mrExport, XML_NAMESPACE_ANIMATION, eElementToken, sal_True, sal_True );

	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR( "xmloff::AnimationsExporterImpl::exportAnimate(), Exception caught!" );
	}
}

void AnimationsExporterImpl::exportAudio( const Reference< XAudio >& xAudio )
{
	if( xAudio.is() ) try
	{
		OUString aSourceURL;
		xAudio->getSource() >>= aSourceURL;
		if( aSourceURL.getLength() )
			mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, mrExport.GetRelativeReference( aSourceURL ) );

		const double fVolume = xAudio->getVolume();
		if( fVolume != 1.0 )
		{
			OUStringBuffer sTmp;
			SvXMLUnitConverter::convertDouble( sTmp, fVolume );
			mrExport.AddAttribute( XML_NAMESPACE_ANIMATION, XML_AUDIO_LEVEL, sTmp.makeStringAndClear() );
		}

/* todo?
		sal_Int32 nEndAfterSlide = 0;
		xAudio->getEndAfterSlide() >>= nEndAfterSlide;
		if( nEndAfterSlide != 0 )
			mrExport.AddAttribute( );
*/
		SvXMLElementExport aElement( mrExport, XML_NAMESPACE_ANIMATION, XML_AUDIO, sal_True, sal_True );

	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR( "xmloff::AnimationsExporterImpl::exportAudio(), exception caught!" );
	}
}

void AnimationsExporterImpl::exportCommand( const Reference< XCommand >& xCommand )
{
	if( xCommand.is() ) try
	{
		OUStringBuffer sTmp;
		Any aTemp( xCommand->getTarget() );
		if( aTemp.hasValue() )
		{
			convertTarget( sTmp, aTemp );
			mrExport.AddAttribute( XML_NAMESPACE_SMIL, XML_TARGETELEMENT, sTmp.makeStringAndClear() );
		}

		sal_Int16 nCommand = xCommand->getCommand();
		SvXMLUnitConverter::convertEnum( sTmp, (sal_uInt16)nCommand, getAnimationsEnumMap(Animations_EnumMap_Command) );
		mrExport.AddAttribute( XML_NAMESPACE_ANIMATION, XML_COMMAND, sTmp.makeStringAndClear() );

// todo virtual ::com::sun::star::uno::Any SAL_CALL getParameter() throw (::com::sun::star::uno::RuntimeException) = 0;

		SvXMLElementExport aElement( mrExport, XML_NAMESPACE_ANIMATION, XML_COMMAND, sal_True, sal_True );

	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR( "xmloff::AnimationsExporterImpl::exportCommand(), exception caught!" );
	}
}

Reference< XInterface > AnimationsExporterImpl::getParagraphTarget( const ParagraphTarget* pTarget ) const
{
	if( pTarget ) try
	{
		Reference< XEnumerationAccess > xParaEnumAccess( pTarget->Shape, UNO_QUERY_THROW );

		Reference< XEnumeration > xEnumeration( xParaEnumAccess->createEnumeration(), UNO_QUERY_THROW );
		sal_Int32 nParagraph = pTarget->Paragraph;

		while( xEnumeration->hasMoreElements() )
		{
			Reference< XInterface > xRef( xEnumeration->nextElement(), UNO_QUERY );
			if( nParagraph-- == 0 )
				return xRef;
		}
	}
	catch( RuntimeException& )
	{
		DBG_ERROR( "xmloff::AnimationsExporterImpl::getParagraphTarget(), RuntimeException catched!" );
	}

	Reference< XInterface > xRef;
	return xRef;
}

void AnimationsExporterImpl::convertPath( OUStringBuffer& sTmp, const Any& rPath )
{
	OUString aStr;
	rPath >>= aStr;

	sTmp = aStr;
}

void AnimationsExporterImpl::convertValue( XMLTokenEnum eAttributeName, OUStringBuffer& sTmp, const Any& rValue )
{
	if( !rValue.hasValue() )
		return;

	if( rValue.getValueType() == ::getCppuType((const ValuePair*)0) )
	{
		const ValuePair* pValuePair = static_cast< const ValuePair* >( rValue.getValue() );
		OUStringBuffer sTmp2;
		convertValue( eAttributeName, sTmp, pValuePair->First );
		sTmp.append( (sal_Unicode)',' );
		convertValue( eAttributeName, sTmp2, pValuePair->Second );
		sTmp.append( sTmp2.makeStringAndClear() );
	}
	else if( rValue.getValueType() == ::getCppuType((Sequence<Any>*)0) )
	{
		const Sequence<Any>* pSequence = static_cast< const Sequence<Any>* >( rValue.getValue() );
		const sal_Int32 nLength = pSequence->getLength();
		sal_Int32 nElement;
		const Any* pAny = pSequence->getConstArray();

		OUStringBuffer sTmp2;

		for( nElement = 0; nElement < nLength; nElement++, pAny++ )
		{
			if( sTmp.getLength() )
				sTmp.append( (sal_Unicode)';' );
			convertValue( eAttributeName, sTmp2, *pAny );
			sTmp.append( sTmp2.makeStringAndClear() );
		}
	}
	else
	{
		OUString aString;
		sal_Int32 nType;

		switch( eAttributeName )
		{
		case XML_X:
		case XML_Y:
		case XML_WIDTH:
		case XML_HEIGHT:
		case XML_ANIMATETRANSFORM:
		case XML_ANIMATEMOTION:
		{
			if( rValue >>= aString )
			{
				/*
				const sal_Char* pSource[] = { "$X", "$Y", "$Width", "$Height", NULL };
				const sal_Char* pDest[] = { "$x", "$y", "$width", "$height", NULL };
				const sal_Int32 nLength[] = { 2, 2, 6, 7, 0 };

				sal_Int32 nIndex = 0;
				while( (nIndex = aString.indexOf( (sal_Unicode)'$', nIndex )) != -1  )
				{
					const sal_Char** ps = pSource;
					const sal_Char** pd = pDest;
					const sal_Int32* pl = nLength;

					while( *ps )
					{
						if( aString.matchAsciiL( *ps, *pl, nIndex ) )
						{
							const OUString aNew( OUString::createFromAscii( *pd ) );
							aString = aString.replaceAt( nIndex, *pl, aNew );
							nIndex += aNew.getLength();
							break;
						}

						ps++;
						pd++;
						pl++;
					}

					if( *ps == 0 )
						nIndex++;
				}
				*/
				sTmp.append( aString );
			}
			else if( rValue.getValueType() == ::getCppuType((const double*)0) )
			{
				sTmp.append( *(static_cast< const double* >( rValue.getValue() )) );
			}
			else
			{
				DBG_ERROR( "xmloff::AnimationsExporterImpl::convertValue(), invalid value type!" );
			}
			return;
		}

		case XML_SKEWX:
		case XML_ROTATE:			nType = XML_TYPE_DOUBLE;					break;
		case XML_TEXT_ROTATION_ANGLE: nType = XML_TYPE_NUMBER16;				break;
		case XML_FILL_COLOR:
		case XML_STROKE_COLOR:
		case XML_DIM:
		case XML_COLOR:				nType = XML_TYPE_COLOR;						break;
		case XML_FILL:				nType = XML_SD_TYPE_FILLSTYLE;				break;
		case XML_STROKE:			nType = XML_SD_TYPE_STROKE;					break;
		case XML_FONT_WEIGHT:		nType = XML_TYPE_TEXT_WEIGHT;				break;
		case XML_FONT_STYLE:		nType = XML_TYPE_TEXT_POSTURE;				break;
		case XML_TEXT_UNDERLINE:	nType = XML_TYPE_TEXT_UNDERLINE_STYLE;		break;
		case XML_FONT_SIZE:			nType = XML_TYPE_DOUBLE_PERCENT;			break;
		case XML_VISIBILITY:		nType = XML_SD_TYPE_PRESPAGE_VISIBILITY;	break;
		case XML_OPACITY:
		case XML_TRANSITIONFILTER:	nType = XML_TYPE_DOUBLE;					break;
		default:
			DBG_ERROR( "xmloff::AnimationsExporterImpl::convertValue(), invalid AttributeName!" );
			nType = XML_TYPE_STRING;
		}

		const XMLPropertyHandler* pHandler = static_cast<SdXMLExport*>(&mrExport)->GetSdPropHdlFactory()->GetPropertyHandler( nType );
		if( pHandler )
		{
			pHandler->exportXML( aString, rValue, mrExport.GetMM100UnitConverter() );
			sTmp.append( aString );
		}
	}

/*
	if( rValue.getValueType() == ::getCppuType((const double*)0) )
	{
		sTmp.append( *(static_cast< const double* >( rValue.getValue() )) );
	}
	else if( rValue.getValueType() == ::getCppuType((const OUString*)0) )
	{
		sTmp.append( *(static_cast< const OUString* >( rValue.getValue() )) );
	}
	else
	{
		DBG_ERROR( "xmloff::AnimationsExporterImpl::convertValue(), invalid value type!" );
	}
*/
}

void AnimationsExporterImpl::convertTiming( OUStringBuffer& sTmp, const Any& rValue )
{
	if( !rValue.hasValue() )
		return;

	if( rValue.getValueType() == ::getCppuType((Sequence<Any>*)0) )
	{
		const Sequence<Any>* pSequence = static_cast< const Sequence<Any>* >( rValue.getValue() );
		const sal_Int32 nLength = pSequence->getLength();
		sal_Int32 nElement;
		const Any* pAny = pSequence->getConstArray();

		OUStringBuffer sTmp2;

		for( nElement = 0; nElement < nLength; nElement++, pAny++ )
		{
			if( sTmp.getLength() )
				sTmp.append( (sal_Unicode)';' );
			convertTiming( sTmp2, *pAny );
			sTmp.append( sTmp2.makeStringAndClear() );
		}
	}
	else if( rValue.getValueType() == ::getCppuType((const double*)0) )
	{
		sTmp.append( *(static_cast< const double* >( rValue.getValue() )) );
		sTmp.append( sal_Unicode('s'));
	}
	else if( rValue.getValueType() == ::getCppuType((const Timing*)0) )
	{
		const Timing* pTiming = static_cast< const Timing* >( rValue.getValue() );
		sTmp.append( GetXMLToken( (*pTiming == Timing_MEDIA) ? XML_MEDIA : XML_INDEFINITE ) );
	}
	else if( rValue.getValueType() == ::getCppuType((const Event*)0) )
	{
		OUStringBuffer sTmp2;

		const Event* pEvent = static_cast< const Event* >( rValue.getValue() );

		if( pEvent->Trigger != EventTrigger::NONE )
		{
			if( pEvent->Source.hasValue() )
			{
				convertSource( sTmp, pEvent->Source );
				sTmp.append( (sal_Unicode)'.' );
			}

			SvXMLUnitConverter::convertEnum( sTmp2, (sal_uInt16)pEvent->Trigger, getAnimationsEnumMap(Animations_EnumMap_EventTrigger) );

			sTmp.append( sTmp2.makeStringAndClear() );
		}

		if( pEvent->Offset.hasValue() )
		{
			convertTiming( sTmp2, pEvent->Offset );

			if( sTmp.getLength() )
				sTmp.append( (sal_Unicode)'+' );

			sTmp.append( sTmp2.makeStringAndClear() );
		}
	}
	else
	{
		DBG_ERROR( "xmloff::AnimationsExporterImpl::convertTiming(), invalid value type!" );
	}
}

void AnimationsExporterImpl::convertSource( OUStringBuffer& sTmp, const Any& rSource )
{
	convertTarget( sTmp, rSource );
}

void AnimationsExporterImpl::convertTarget( OUStringBuffer& sTmp, const Any& rTarget )
{
	if( !rTarget.hasValue() )
		return;

	Reference< XInterface > xRef;

	if( rTarget.getValueTypeClass() == ::com::sun::star::uno::TypeClass_INTERFACE )
	{
		rTarget >>= xRef;
	}
	else if( rTarget.getValueType() == ::getCppuType((const ParagraphTarget*)0) )
	{
		xRef = getParagraphTarget( static_cast< const ParagraphTarget* >( rTarget.getValue() ) );
	}

	DBG_ASSERT( xRef.is(), "xmloff::AnimationsExporterImpl::convertTarget(), invalid target type!" );
	if( xRef.is() )
	{
		const OUString& rIdentifier = mrExport.getInterfaceToIdentifierMapper().getIdentifier(xRef);
		if( rIdentifier.getLength() )
			sTmp.append( rIdentifier );
	}
}

void AnimationsExporterImpl::prepareValue( const Any& rValue )
{
	if( !rValue.hasValue() )
		return;

	if( rValue.getValueType() == ::getCppuType((const ValuePair*)0) )
	{
		const ValuePair* pValuePair = static_cast< const ValuePair* >( rValue.getValue() );
		prepareValue( pValuePair->First );
		prepareValue( pValuePair->Second );
	}
	else if( rValue.getValueType() == ::getCppuType((Sequence<Any>*)0) )
	{
		const Sequence<Any>* pSequence = static_cast< const Sequence<Any>* >( rValue.getValue() );
		const sal_Int32 nLength = pSequence->getLength();
		sal_Int32 nElement;
		const Any* pAny = pSequence->getConstArray();

		for( nElement = 0; nElement < nLength; nElement++, pAny++ )
			prepareValue( *pAny );
	}
	else if( rValue.getValueTypeClass() == ::com::sun::star::uno::TypeClass_INTERFACE )
	{
		Reference< XInterface> xRef( rValue, UNO_QUERY );
		if( xRef.is() )
			mrExport.getInterfaceToIdentifierMapper().registerReference( xRef );
	}
	else if( rValue.getValueType() == ::getCppuType((const ParagraphTarget*)0) )
	{
		Reference< XInterface> xRef( getParagraphTarget( static_cast< const ParagraphTarget* >( rValue.getValue() ) ) );
		if( xRef.is() )
			mrExport.getInterfaceToIdentifierMapper().registerReference( xRef );
	}
	else if( rValue.getValueType() == ::getCppuType((const Event*)0) )
	{
		const Event* pEvent = static_cast< const Event* >( rValue.getValue() );
		prepareValue( pEvent->Source );
	}
}

AnimationsExporter::AnimationsExporter( SvXMLExport& rExport, const Reference< XPropertySet >& xPageProps )
{
	mpImpl = new AnimationsExporterImpl( rExport, xPageProps );
}

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

void AnimationsExporter::prepare( Reference< XAnimationNode > xRootNode )
{
	try
	{
		if( xRootNode.is() )
		{
			mpImpl->prepareTransitionNode();
			mpImpl->prepareNode( xRootNode );
		}
	}
	catch( RuntimeException& )
	{
		DBG_ERROR( "xmloff::AnimationsExporter::prepare(), exception catched" );
	}
}

void AnimationsExporter::exportAnimations( Reference< XAnimationNode > xRootNode )
{
	try
	{
		if( xRootNode.is() )
		{
			bool bHasEffects = mpImpl->mbHasTransition;

			if( !bHasEffects )
			{
				// first check if there are no animations
				Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
				Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
				if( xEnumeration->hasMoreElements() )
				{
					// first child node may be an empty main sequence, check this
					Reference< XAnimationNode > xMainNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
					Reference< XEnumerationAccess > xMainEnumerationAccess( xMainNode, UNO_QUERY_THROW );
					Reference< XEnumeration > xMainEnumeration( xMainEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );

					// only export if the main sequence is not empty or if there are additional
					// trigger sequences
					bHasEffects = xMainEnumeration->hasMoreElements() || xEnumeration->hasMoreElements();
				}
			}

			if( bHasEffects )
				mpImpl->exportNode( xRootNode );
		}
	}
	catch( RuntimeException& )
	{
		DBG_ERROR( "xmloff::AnimationsExporter::exportAnimations(), exception catched" );
	}
}

}
