/**************************************************************
 * 
 * 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_slideshow.hxx"

// must be first
#include <canvas/debug.hxx>
#include <tools/diagnose_ex.h>
#include <canvas/verbosetrace.hxx>

#include <animationfactory.hxx>
#include <attributemap.hxx>

#include <com/sun/star/animations/AnimationAdditiveMode.hpp>
#include <com/sun/star/animations/AnimationTransformType.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
#include <com/sun/star/awt/FontSlant.hpp>
#include <com/sun/star/awt/FontUnderline.hpp>
#include <com/sun/star/awt/FontWeight.hpp>

#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>

#include <functional>


using namespace ::com::sun::star;


namespace slideshow
{
    namespace internal
    {
        namespace
        {            
            // attention, there is a similar implementation of Animation in 
            // transitions/transitionfactory.cxx
            
            template< typename ValueT > class TupleAnimation : public PairAnimation
            {
            public:
                TupleAnimation( const ShapeManagerSharedPtr&		rShapeManager,
                                int									nFlags,
                                bool      	 (ShapeAttributeLayer::*pIs1stValid)() const,
                                bool      	 (ShapeAttributeLayer::*pIs2ndValid)() const,
                                const ValueT&						rDefaultValue,
                                const ::basegfx::B2DSize&			rReferenceSize,
                                double 	 	 (ShapeAttributeLayer::*pGet1stValue)() const,
                                double 	 	 (ShapeAttributeLayer::*pGet2ndValue)() const,
                                void      	 (ShapeAttributeLayer::*pSetValue)( const ValueT& ) ) :
                    mpShape(),
                    mpAttrLayer(),
                    mpShapeManager( rShapeManager ),
                    mpIs1stValidFunc(pIs1stValid),
                    mpIs2ndValidFunc(pIs2ndValid),
                    mpGet1stValueFunc(pGet1stValue),
                    mpGet2ndValueFunc(pGet2ndValue),
                    mpSetValueFunc(pSetValue),
                    mnFlags( nFlags ),
                    maReferenceSize( rReferenceSize ),
                    maDefaultValue( rDefaultValue ),
                    mbAnimationStarted( false )
                {
                    ENSURE_OR_THROW( rShapeManager,
                                      "TupleAnimation::TupleAnimation(): Invalid ShapeManager" );
                    ENSURE_OR_THROW( pIs1stValid && pIs2ndValid && pGet1stValue && pGet2ndValue && pSetValue,
                                      "TupleAnimation::TupleAnimation(): One of the method pointers is NULL" );
                }                

                ~TupleAnimation()
                {
                    end_();
                }
                
                // Animation interface
                // -------------------
                virtual void prefetch( const AnimatableShapeSharedPtr&,
                                       const ShapeAttributeLayerSharedPtr& )
                {}

                virtual void start( const AnimatableShapeSharedPtr& 	rShape,
                                    const ShapeAttributeLayerSharedPtr& rAttrLayer )
                {
                    OSL_ENSURE( !mpShape,
                                "TupleAnimation::start(): Shape already set" );
                    OSL_ENSURE( !mpAttrLayer,
                                "TupleAnimation::start(): Attribute layer already set" );

                    mpShape = rShape;
                    mpAttrLayer = rAttrLayer;

                    ENSURE_OR_THROW( rShape,
                                      "TupleAnimation::start(): Invalid shape" );
                    ENSURE_OR_THROW( rAttrLayer,
                                      "TupleAnimation::start(): Invalid attribute layer" );

                    if( !mbAnimationStarted )
                    {
                        mbAnimationStarted = true;

                        if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
                            mpShapeManager->enterAnimationMode( mpShape );
                    }
                }
                
                virtual void end() { end_(); }
                void end_()
                {
                    if( mbAnimationStarted )
                    {
                        mbAnimationStarted = false;

                        if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
                            mpShapeManager->leaveAnimationMode( mpShape );

                        if( mpShape->isContentChanged() )
                            mpShapeManager->notifyShapeUpdate( mpShape );
                    }
                }

                // PairAnimation interface
                // -----------------------

                virtual bool operator()( const ::basegfx::B2DTuple& rValue )
                {
                    ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
                                       "TupleAnimation::operator(): Invalid ShapeAttributeLayer" );

                    ValueT aValue( rValue.getX(),
                                   rValue.getY() );

                    // Activitis get values from the expression parser,
                    // which returns _relative_ sizes/positions.
                    // Convert back relative to reference coordinate system
                    aValue *= maReferenceSize;

                    ((*mpAttrLayer).*mpSetValueFunc)( aValue );

                    if( mpShape->isContentChanged() )
                        mpShapeManager->notifyShapeUpdate( mpShape );
                    
                    return true;
                }

                virtual ::basegfx::B2DTuple getUnderlyingValue() const
                {
                    ENSURE_OR_THROW( mpAttrLayer,
                                      "TupleAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );

                    ::basegfx::B2DTuple aRetVal;

                    // deviated from the (*shared_ptr).*mpFuncPtr
                    // notation here, since gcc does not seem to parse
                    // that as a member function call anymore.
                    aRetVal.setX( (mpAttrLayer.get()->*mpIs1stValidFunc)() ?
                                  (mpAttrLayer.get()->*mpGet1stValueFunc)() :
                                  maDefaultValue.getX() );
                    aRetVal.setY( (mpAttrLayer.get()->*mpIs2ndValidFunc)() ?
                                  (mpAttrLayer.get()->*mpGet2ndValueFunc)() :
                                  maDefaultValue.getY() );

                    // Activities get values from the expression
                    // parser, which returns _relative_
                    // sizes/positions.  Convert start value to the
                    // same coordinate space (i.e. relative to given
                    // reference size).
                    aRetVal /= maReferenceSize;

                    return aRetVal;
                }

            private:
                AnimatableShapeSharedPtr		   mpShape;
                ShapeAttributeLayerSharedPtr	   mpAttrLayer;
                ShapeManagerSharedPtr			   mpShapeManager;
                bool 		(ShapeAttributeLayer::*mpIs1stValidFunc)() const;
                bool 		(ShapeAttributeLayer::*mpIs2ndValidFunc)() const;
                double 		(ShapeAttributeLayer::*mpGet1stValueFunc)() const;
                double 		(ShapeAttributeLayer::*mpGet2ndValueFunc)() const;
                void 		(ShapeAttributeLayer::*mpSetValueFunc)( const ValueT& );

                const int						   mnFlags;

                const ::basegfx::B2DSize		   maReferenceSize;
                const ValueT					   maDefaultValue;
                bool							   mbAnimationStarted;
            };


            class PathAnimation : public NumberAnimation
            {
            public:
                PathAnimation( const ::rtl::OUString&		rSVGDPath,
                               sal_Int16                    nAdditive,
                               const ShapeManagerSharedPtr&	rShapeManager,
                               const ::basegfx::B2DVector&  rSlideSize,
                               int							nFlags ) :
                    maPathPoly(),
                    mpShape(),
                    mpAttrLayer(),
                    mpShapeManager( rShapeManager ),
                    maPageSize( rSlideSize ),
					maShapeOrig(),
                    mnFlags( nFlags ),
					mbAnimationStarted( false ),
					mnAdditive( nAdditive )
                {
                    ENSURE_OR_THROW( rShapeManager,
                                      "PathAnimation::PathAnimation(): Invalid ShapeManager" );

                    ::basegfx::B2DPolyPolygon aPolyPoly;
                    
                    ENSURE_OR_THROW( ::basegfx::tools::importFromSvgD( aPolyPoly, rSVGDPath, false, 0 ),
                                      "PathAnimation::PathAnimation(): failed to parse SVG:d path" );
                    ENSURE_OR_THROW( aPolyPoly.count() == 1,
                                      "PathAnimation::PathAnimation(): motion path consists of multiple/zero polygon(s)" );

                    // TODO(F2): Since getPositionRelative() currently 
                    // cannot handle beziers, have to subdivide.
                    // AW: Should be no longer necessary; getPositionRelative is now bezier-safe
                    maPathPoly = ::basegfx::tools::adaptiveSubdivideByAngle(aPolyPoly.getB2DPolygon(0) );
                }

                ~PathAnimation()
                {
                    end_();
                }

                // Animation interface
                // -------------------
                virtual void prefetch( const AnimatableShapeSharedPtr&,
                                       const ShapeAttributeLayerSharedPtr& )
                {}

                virtual void start( const AnimatableShapeSharedPtr& 	rShape,
                                    const ShapeAttributeLayerSharedPtr& rAttrLayer )
                {
                    OSL_ENSURE( !mpShape,
                                "PathAnimation::start(): Shape already set" );
                    OSL_ENSURE( !mpAttrLayer,
                                "PathAnimation::start(): Attribute layer already set" );

                    mpShape = rShape;
                    mpAttrLayer = rAttrLayer;

                    ENSURE_OR_THROW( rShape,
                                      "PathAnimation::start(): Invalid shape" );
                    ENSURE_OR_THROW( rAttrLayer,
                                      "PathAnimation::start(): Invalid attribute layer" );

                    // TODO(F1): Check whether _shape_ bounds are correct here.
                    // Theoretically, our AttrLayer is way down the stack, and
                    // we only have to consider _that_ value, not the one from 
                    // the top of the stack as returned by Shape::getBounds()
					if( mnAdditive == animations::AnimationAdditiveMode::SUM )
						maShapeOrig = mpShape->getBounds().getCenter();
					else
						maShapeOrig = mpShape->getDomBounds().getCenter();

                    if( !mbAnimationStarted )
                    {
                        mbAnimationStarted = true;

                        if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
                            mpShapeManager->enterAnimationMode( mpShape );
                    }
                }
                
                virtual void end() { end_(); }
                void end_()
                {
                    if( mbAnimationStarted )
                    {
                        mbAnimationStarted = false;

                        if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
                            mpShapeManager->leaveAnimationMode( mpShape );

                        if( mpShape->isContentChanged() )
                            mpShapeManager->notifyShapeUpdate( mpShape );
                    }
                }

                // NumberAnimation interface
                // -----------------------

                virtual bool operator()( double nValue )
                {
                    ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
                                       "PathAnimation::operator(): Invalid ShapeAttributeLayer" );

                    ::basegfx::B2DPoint rOutPos = ::basegfx::tools::getPositionRelative( maPathPoly,
                                                                                         nValue );

                    // TODO(F1): Determine whether the path is
                    // absolute, or shape-relative.

                    // interpret path as page-relative. Scale up with page size
                    rOutPos *= maPageSize;

                    // TODO(F1): Determine whether the path origin is
                    // absolute, or shape-relative.

                    // interpret path as shape-originated. Offset to shape position

                    rOutPos += maShapeOrig;

                    mpAttrLayer->setPosition( rOutPos );

                    if( mpShape->isContentChanged() )
                        mpShapeManager->notifyShapeUpdate( mpShape );
                    
                    return true;
                }

                virtual double getUnderlyingValue() const
                {
                    ENSURE_OR_THROW( mpAttrLayer,
                                      "PathAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );

                    return 0.0; // though this should be used in concert with 
                    			// ActivitiesFactory::createSimpleActivity, better
                    			// explicitely name our start value.
                    			// Permissible range for operator() above is [0,1]
                }

            private:
                ::basegfx::B2DPolygon			   maPathPoly;
                AnimatableShapeSharedPtr		   mpShape;
                ShapeAttributeLayerSharedPtr	   mpAttrLayer;
                ShapeManagerSharedPtr			   mpShapeManager;
                const ::basegfx::B2DSize		   maPageSize;
                ::basegfx::B2DPoint				   maShapeOrig;
                const int						   mnFlags;
                bool							   mbAnimationStarted;
				sal_Int16						   mnAdditive;
            };


            /** GenericAnimation template

            	This template makes heavy use of SFINAE, only one of
            	the operator()() methods will compile for each of the
            	base classes.

                Note that we omit the virtual keyword on the
                operator()() overrides and getUnderlyingValue() methods on
                purpose; those that actually do override baseclass
                virtual methods inherit the property, and the others
                won't increase our vtable. What's more, having all
                those methods in the vtable actually creates POIs for
                them, which breaks the whole SFINAE concept (IOW, this
                template won't compile any longer).

            	@tpl AnimationBase
                Type of animation to generate (determines the
                interface GenericAnimation will implement). Must be
                one of NumberAnimation, ColorAnimation,
                StringAnimation, PairAnimation or BoolAnimation.

                @tpl ModifierFunctor
                Type of a functor object, which can optionally be used to
                modify the getter/setter values.
             */
            template< typename AnimationBase, typename ModifierFunctor > class GenericAnimation : public AnimationBase
            {
            public:
                typedef typename AnimationBase::ValueType ValueT;

                /** Create generic animation

                	@param pIsValid
                    Function pointer to one of the is*Valid
                    methods. Used to either take the given getter
                    method, or the given default value for the start value.

                    @param rDefaultValue
                    Default value, to take as the start value if
                    is*Valid returns false.

                    @param pGetValue
                    Getter method, to fetch start value if valid.

                    @param pSetValue
                    Setter method. This one puts the current animation
                    value to the ShapeAttributeLayer.

                    @param rGetterModifier
                    Modifies up values retrieved from the pGetValue method.
                    Must provide operator()( const ValueT& ) method.

                    @param rSetterModifier
                    Modifies up values before passing them to the pSetValue method.
                    Must provide operator()( const ValueT& ) method.
                 */
            	GenericAnimation( const ShapeManagerSharedPtr&			rShapeManager,
                                  int									nFlags,
                    			  bool      	 (ShapeAttributeLayer::*pIsValid)() const,
                                  const ValueT&				  	   		rDefaultValue,
                                  ValueT 		 (ShapeAttributeLayer::*pGetValue)() const,
                                  void      	 (ShapeAttributeLayer::*pSetValue)( const ValueT& ),
                                  const ModifierFunctor&				rGetterModifier,
                                  const ModifierFunctor&				rSetterModifier ) :
                    mpShape(),
                    mpAttrLayer(),
                    mpShapeManager( rShapeManager ),
                    mpIsValidFunc(pIsValid),
                    mpGetValueFunc(pGetValue),
                    mpSetValueFunc(pSetValue),
                    maGetterModifier( rGetterModifier ),
                    maSetterModifier( rSetterModifier ),
                    mnFlags( nFlags ),
                    maDefaultValue(rDefaultValue),
                    mbAnimationStarted( false )
                {
                    ENSURE_OR_THROW( rShapeManager,
                                      "GenericAnimation::GenericAnimation(): Invalid ShapeManager" );
                    ENSURE_OR_THROW( pIsValid && pGetValue && pSetValue,
                                      "GenericAnimation::GenericAnimation(): One of the method pointers is NULL" );
                }

                ~GenericAnimation()
                {
                    end_();
                }
                
                // Animation interface
                // -------------------
                virtual void prefetch( const AnimatableShapeSharedPtr&,
                                       const ShapeAttributeLayerSharedPtr& )
                {}

                virtual void start( const AnimatableShapeSharedPtr& 	rShape,
                                    const ShapeAttributeLayerSharedPtr& rAttrLayer )
                {
                    OSL_ENSURE( !mpShape,
                                "GenericAnimation::start(): Shape already set" );
                    OSL_ENSURE( !mpAttrLayer,
                                "GenericAnimation::start(): Attribute layer already set" );

                    mpShape = rShape;
                    mpAttrLayer = rAttrLayer;

                    ENSURE_OR_THROW( rShape,
                                      "GenericAnimation::start(): Invalid shape" );
                    ENSURE_OR_THROW( rAttrLayer,
                                      "GenericAnimation::start(): Invalid attribute layer" );

                    // only start animation once per repeated start() call,
                    // and only if sprites should be used for display
                    if( !mbAnimationStarted )
                    {
                        mbAnimationStarted = true;

                        if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
                            mpShapeManager->enterAnimationMode( mpShape );
                    }
                }
                
                virtual void end() { end_(); }
                void end_()
                {
                    // TODO(Q2): Factor out common code (most
                    // prominently start() and end()) into base class

                    // only stop animation once per repeated end() call,
                    // and only if sprites are used for display
                    if( mbAnimationStarted )
                    {
                        mbAnimationStarted = false;

                        if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
                            mpShapeManager->leaveAnimationMode( mpShape );

                        // Attention, this notifyShapeUpdate() is
                        // somewhat delicate here. Calling it
                        // unconditional (i.e. not guarded by
                        // mbAnimationStarted) will lead to shapes
                        // snapping back to their original state just
                        // before the slide ends. Not calling it at
                        // all might swallow final animation
                        // states. The current implementation relies
                        // on the fact that end() is either called by
                        // the Activity (then, the last animation
                        // state has been set, and corresponds to the
                        // shape's hold state), or by the animation
                        // node (then, it's a forced end, and we
                        // _have_ to snap back). 
                        // 
                        // To reiterate: normally, we're called from
                        // the Activity first, thus the
                        // notifyShapeUpdate() below will update to
                        // the last activity value.

                        // force shape update, activity might have changed
                        // state in the last round.
                        if( mpShape->isContentChanged() )
                            mpShapeManager->notifyShapeUpdate( mpShape );
                    }
                }

                // Derived Animation interface
                // ---------------------------

                /** For by-reference interfaces (B2DTuple, OUString)
                 */
                bool operator()( const ValueT& x )
                {
                    ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
                                       "GenericAnimation::operator(): Invalid ShapeAttributeLayer" );

                    ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) );

                    if( mpShape->isContentChanged() )
                        mpShapeManager->notifyShapeUpdate( mpShape );

                    return true;
                }

                /** For by-value interfaces (bool, double)
                 */
                bool operator()( ValueT x )
                {
                    ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
                                       "GenericAnimation::operator(): Invalid ShapeAttributeLayer" );

                    ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) );

                    if( mpShape->isContentChanged() )
                        mpShapeManager->notifyShapeUpdate( mpShape );

                    return true;
                }

                ValueT getUnderlyingValue() const
                {
                    ENSURE_OR_THROW( mpAttrLayer,
                                      "GenericAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );

                    // deviated from the (*shared_ptr).*mpFuncPtr
                    // notation here, since gcc does not seem to parse
                    // that as a member function call anymore.
                    if( (mpAttrLayer.get()->*mpIsValidFunc)() )
                        return maGetterModifier( ((*mpAttrLayer).*mpGetValueFunc)() );
                    else
                        return maDefaultValue;
                }

            private:
                AnimatableShapeSharedPtr		   mpShape;
                ShapeAttributeLayerSharedPtr	   mpAttrLayer;
                ShapeManagerSharedPtr			   mpShapeManager;
                bool 		(ShapeAttributeLayer::*mpIsValidFunc)() const;
                ValueT	 	(ShapeAttributeLayer::*mpGetValueFunc)() const;
                void 		(ShapeAttributeLayer::*mpSetValueFunc)( const ValueT& );

                ModifierFunctor					   maGetterModifier;
                ModifierFunctor					   maSetterModifier;

                const int						   mnFlags;

                const ValueT				 	   maDefaultValue;
                bool							   mbAnimationStarted;
            };

            /** Function template wrapper around GenericAnimation template

            	@tpl AnimationBase
                Type of animation to generate (determines the
                interface GenericAnimation will implement).
             */
            template< typename AnimationBase > ::boost::shared_ptr< AnimationBase > 
            	makeGenericAnimation( const ShapeManagerSharedPtr&							   rShapeManager,
                                      int													   nFlags,	
                                      bool 								(ShapeAttributeLayer::*pIsValid)() const,
                                      const typename AnimationBase::ValueType&				   rDefaultValue,
                                      typename AnimationBase::ValueType (ShapeAttributeLayer::*pGetValue)() const,
                                      void 								(ShapeAttributeLayer::*pSetValue)( const typename AnimationBase::ValueType& ) )
            {
                return ::boost::shared_ptr< AnimationBase >( 
                    new GenericAnimation< AnimationBase, 
                    					  ::std::identity< typename AnimationBase::ValueType > >( 
                                              rShapeManager,
                                              nFlags,
                                              pIsValid,
                                              rDefaultValue,
                                              pGetValue,
                                              pSetValue,
                                              // no modification necessary, use identity functor here
                                              std::identity< typename AnimationBase::ValueType >(),
                                              std::identity< typename AnimationBase::ValueType >()));
            }

            class Scaler
            {
            public:
                Scaler( double nScale ) : 
                    mnScale( nScale )
                {
                }

                double operator()( double nVal ) const
                {
                    return mnScale * nVal;
                }

            private:
                double mnScale;
            };

            /** Overload for NumberAnimations which need scaling (width,height,x,y currently)
             */
            NumberAnimationSharedPtr makeGenericAnimation( const ShapeManagerSharedPtr&							    rShapeManager,
                                                           int													    nFlags,	
                                                           bool 							 (ShapeAttributeLayer::*pIsValid)() const,
                                                           double				    								nDefaultValue,
                                                           double							 (ShapeAttributeLayer::*pGetValue)() const,
                                                           void 							 (ShapeAttributeLayer::*pSetValue)( const double& ),
                                                           double								 				    nScaleValue )
            {
                return NumberAnimationSharedPtr(
                    new GenericAnimation< NumberAnimation, Scaler >( rShapeManager,
                                                                     nFlags,
                                                                     pIsValid,
                                                                     nDefaultValue / nScaleValue,
                                                                     pGetValue,
                                                                     pSetValue,
                                                                     Scaler( 1.0/nScaleValue ),
                                                                     Scaler( nScaleValue ) ) );
            }


            uno::Any getShapeDefault( const AnimatableShapeSharedPtr& 	rShape,
                                      const ::rtl::OUString& 			rPropertyName )
            {
                uno::Reference< drawing::XShape > xShape( rShape->getXShape() );

                if( !xShape.is() )
                    return uno::Any(); // no regular shape, no defaults available

                
                // extract relevant value from XShape's PropertySet
                uno::Reference< beans::XPropertySet > xPropSet( xShape, 
                                                                uno::UNO_QUERY );

                ENSURE_OR_THROW( xPropSet.is(),
                                  "getShapeDefault(): Cannot query property set from shape" );

                return xPropSet->getPropertyValue( rPropertyName );
            }

            template< typename ValueType > ValueType getDefault( const AnimatableShapeSharedPtr& 	rShape,
                                                                 const ::rtl::OUString& 			rPropertyName )
            {
                const uno::Any& rAny( getShapeDefault( rShape, 
                                                       rPropertyName ) );

                if( !rAny.hasValue() )
                {
                    OSL_ENSURE( false, "getDefault(): cannot get requested shape property" );
                    OSL_TRACE( "getDefault(): cannot get '%s' shape property",
                               ::rtl::OUStringToOString( rPropertyName, 
                                                         RTL_TEXTENCODING_ASCII_US ).getStr() );
                    return ValueType();
                }
                else
                {
                    ValueType aValue = ValueType();

                    if( !(rAny >>= aValue) )
                    {
                        OSL_ENSURE( false, "getDefault(): cannot extract requested shape property" );
                        OSL_TRACE( "getDefault(): cannot extract '%s' shape property",
                                   ::rtl::OUStringToOString( rPropertyName, 
                                                             RTL_TEXTENCODING_ASCII_US ).getStr() );
                        return ValueType();
                    }

                    return aValue;
                }
            }

            template<> RGBColor getDefault< RGBColor >( const AnimatableShapeSharedPtr& rShape,
                                                        const ::rtl::OUString& 			rPropertyName )
            {
                const uno::Any& rAny( getShapeDefault( rShape, 
                                                       rPropertyName ) );

                if( !rAny.hasValue() )
                {
                    OSL_ENSURE( false, "getDefault(): cannot get requested shape color property" );
                    OSL_TRACE( "getDefault(): cannot get '%s' shape color property",
                               ::rtl::OUStringToOString( rPropertyName, 
                                                         RTL_TEXTENCODING_ASCII_US ).getStr() );
                    return RGBColor();
                }
                else
                {
                    sal_Int32 nValue = 0;

                    if( !(rAny >>= nValue) )
                    {
                        OSL_ENSURE( false, "getDefault(): cannot extract requested shape color property" );
                        OSL_TRACE( "getDefault(): cannot extract '%s' shape color property",
                                   ::rtl::OUStringToOString( rPropertyName, 
                                                             RTL_TEXTENCODING_ASCII_US ).getStr() );
                        return RGBColor();
                    }

                    // convert from 0xAARRGGBB API color to 0xRRGGBB00
                    // canvas color
                    return RGBColor( (nValue << 8U) & 0xFFFFFF00U );
                }
            }
        }

        AnimationFactory::AttributeClass AnimationFactory::classifyAttributeName( const ::rtl::OUString& rAttrName )
        {
            // ATTENTION: When changing this map, also the create*PropertyAnimation() methods must
            // be checked and possibly adapted in their switch statements

            // TODO(Q2): Since this map must be coherent with the various switch statements 
            // in the create*PropertyAnimation methods, try to unify into a single method or table
            switch( mapAttributeName( rAttrName ) )
            {
                default:
                    // FALLTHROUGH intended
                case ATTRIBUTE_INVALID:
                    return CLASS_UNKNOWN_PROPERTY;

                case ATTRIBUTE_CHAR_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_DIMCOLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_FILL_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_LINE_COLOR:
                    return CLASS_COLOR_PROPERTY;

                case ATTRIBUTE_CHAR_FONT_NAME:
                    return CLASS_STRING_PROPERTY;

                case ATTRIBUTE_VISIBILITY:
                    return CLASS_BOOL_PROPERTY;

                case ATTRIBUTE_CHAR_HEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_WEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_ROTATION:
                    // FALLTHROUGH intended
                case ATTRIBUTE_HEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_OPACITY:
                    // FALLTHROUGH intended
                case ATTRIBUTE_ROTATE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_SKEW_X:
                    // FALLTHROUGH intended
                case ATTRIBUTE_SKEW_Y:
                    // FALLTHROUGH intended
                case ATTRIBUTE_WIDTH:
                    // FALLTHROUGH intended
                case ATTRIBUTE_POS_X:
                    // FALLTHROUGH intended
                case ATTRIBUTE_POS_Y:
                    return CLASS_NUMBER_PROPERTY;

                case ATTRIBUTE_CHAR_UNDERLINE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_FILL_STYLE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_LINE_STYLE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_POSTURE:
                    return CLASS_ENUM_PROPERTY;
            }
        }

        NumberAnimationSharedPtr AnimationFactory::createNumberPropertyAnimation( const ::rtl::OUString&				rAttrName,
                                                                                  const AnimatableShapeSharedPtr&		rShape,
                                                                                  const ShapeManagerSharedPtr&			rShapeManager,
                                                                                  const ::basegfx::B2DVector&           rSlideSize,
                                                                                  int									nFlags )
        {
            // ATTENTION: When changing this map, also the classifyAttributeName() method must
            // be checked and possibly adapted in their switch statement
            switch( mapAttributeName( rAttrName ) )
            {
                default:
                    // FALLTHROUGH intended
                case ATTRIBUTE_INVALID:
                    ENSURE_OR_THROW( false,
                                      "AnimationFactory::createNumberPropertyAnimation(): Unknown attribute" );
                    break;

                case ATTRIBUTE_CHAR_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_FONT_NAME:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_POSTURE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_UNDERLINE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_DIMCOLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_FILL_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_FILL_STYLE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_LINE_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_LINE_STYLE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_VISIBILITY:
                    ENSURE_OR_THROW( false,
                                      "AnimationFactory::createNumberPropertyAnimation(): Attribute type mismatch" );
                    break;

                case ATTRIBUTE_CHAR_HEIGHT:
                    return makeGenericAnimation<NumberAnimation>( rShapeManager,
                                                                  nFlags,
                                                                  &ShapeAttributeLayer::isCharScaleValid, 
                                                                  1.0, // CharHeight is a relative attribute, thus
                                                                  	   // default is 1.0
                                                                  &ShapeAttributeLayer::getCharScale, 
                                                                  &ShapeAttributeLayer::setCharScale );

                case ATTRIBUTE_CHAR_WEIGHT:
                    return makeGenericAnimation<NumberAnimation>( rShapeManager,
                                                                  nFlags,
                                                                  &ShapeAttributeLayer::isCharWeightValid, 
                                                                  getDefault<double>( rShape, rAttrName ),
                                                                  &ShapeAttributeLayer::getCharWeight, 
                                                                  &ShapeAttributeLayer::setCharWeight );

                case ATTRIBUTE_CHAR_ROTATION:
                    return makeGenericAnimation<NumberAnimation>( rShapeManager,
                                                                  nFlags,
                                                                  &ShapeAttributeLayer::isCharRotationAngleValid, 
                                                                  getDefault<double>( rShape, rAttrName ),
                                                                  &ShapeAttributeLayer::getCharRotationAngle, 
                                                                  &ShapeAttributeLayer::setCharRotationAngle );

                case ATTRIBUTE_HEIGHT:
                    return makeGenericAnimation( rShapeManager,
                                                 nFlags,
                                                 &ShapeAttributeLayer::isHeightValid, 
                                                 // TODO(F1): Check whether _shape_ bounds are correct here.
                                                 // Theoretically, our AttrLayer is way down the stack, and
                                                 // we only have to consider _that_ value, not the one from 
                                                 // the top of the stack as returned by Shape::getBounds()
                                                 rShape->getBounds().getHeight(),
                                                 &ShapeAttributeLayer::getHeight, 
                                                 &ShapeAttributeLayer::setHeight,
                                                 // convert expression parser value from relative page size
                                                 rSlideSize.getY() );

                case ATTRIBUTE_OPACITY:
                    return makeGenericAnimation<NumberAnimation>( rShapeManager,
                                                                  nFlags,
                                                                  &ShapeAttributeLayer::isAlphaValid, 
                                                                  // TODO(F1): Provide shape default here (FillTransparency?)
                                                                  1.0,
                                                                  &ShapeAttributeLayer::getAlpha, 
                                                                  &ShapeAttributeLayer::setAlpha );

                case ATTRIBUTE_ROTATE:
                    return makeGenericAnimation<NumberAnimation>( rShapeManager,
                                                                  nFlags,
                                                                  &ShapeAttributeLayer::isRotationAngleValid, 
                                                                  // NOTE: Since we paint the shape as-is from metafile,
                                                                  // rotation angle is always 0.0, even for rotated shapes
                                                                  0.0,
                                                                  &ShapeAttributeLayer::getRotationAngle, 
                                                                  &ShapeAttributeLayer::setRotationAngle );
                    
                case ATTRIBUTE_SKEW_X:
                    return makeGenericAnimation<NumberAnimation>( rShapeManager,
                                                                  nFlags,
                                                                  &ShapeAttributeLayer::isShearXAngleValid, 
                                                                  // TODO(F1): Is there any shape property for skew?
                                                                  0.0,
                                                                  &ShapeAttributeLayer::getShearXAngle, 
                                                                  &ShapeAttributeLayer::setShearXAngle );
                    
                case ATTRIBUTE_SKEW_Y:
                    return makeGenericAnimation<NumberAnimation>( rShapeManager,
                                                                  nFlags,
                                                                  &ShapeAttributeLayer::isShearYAngleValid, 
                                                                  // TODO(F1): Is there any shape property for skew?
                                                                  0.0,
                                                                  &ShapeAttributeLayer::getShearYAngle, 
                                                                  &ShapeAttributeLayer::setShearYAngle );
                    
                case ATTRIBUTE_WIDTH:
                    return makeGenericAnimation( rShapeManager,
                                                 nFlags,
                                                 &ShapeAttributeLayer::isWidthValid, 
                                                 // TODO(F1): Check whether _shape_ bounds are correct here.
                                                 // Theoretically, our AttrLayer is way down the stack, and
                                                 // we only have to consider _that_ value, not the one from 
                                                 // the top of the stack as returned by Shape::getBounds()
                                                 rShape->getBounds().getWidth(),
                                                 &ShapeAttributeLayer::getWidth, 
                                                 &ShapeAttributeLayer::setWidth,
                                                 // convert expression parser value from relative page size
                                                 rSlideSize.getX() );
                    
                case ATTRIBUTE_POS_X:
                    return makeGenericAnimation( rShapeManager,
                                                 nFlags,
                                                 &ShapeAttributeLayer::isPosXValid, 
                                                 // TODO(F1): Check whether _shape_ bounds are correct here.
                                                 // Theoretically, our AttrLayer is way down the stack, and
                                                 // we only have to consider _that_ value, not the one from 
                                                 // the top of the stack as returned by Shape::getBounds()
                                                 rShape->getBounds().getCenterX(),
                                                 &ShapeAttributeLayer::getPosX, 
                                                 &ShapeAttributeLayer::setPosX,
                                                 // convert expression parser value from relative page size
                                                 rSlideSize.getX() );
                    
                case ATTRIBUTE_POS_Y:
                    return makeGenericAnimation( rShapeManager,
                                                 nFlags,
                                                 &ShapeAttributeLayer::isPosYValid, 
                                                 // TODO(F1): Check whether _shape_ bounds are correct here.
                                                 // Theoretically, our AttrLayer is way down the stack, and
                                                 // we only have to consider _that_ value, not the one from 
                                                 // the top of the stack as returned by Shape::getBounds()
                                                 rShape->getBounds().getCenterY(),
                                                 &ShapeAttributeLayer::getPosY, 
                                                 &ShapeAttributeLayer::setPosY,
                                                 // convert expression parser value from relative page size
                                                 rSlideSize.getY() );
            }

            return NumberAnimationSharedPtr();
        }

        EnumAnimationSharedPtr AnimationFactory::createEnumPropertyAnimation( const ::rtl::OUString&				rAttrName,
                                                                              const AnimatableShapeSharedPtr&		rShape,
                                                                              const ShapeManagerSharedPtr&			rShapeManager,
                                                                              const ::basegfx::B2DVector&           /*rSlideSize*/,
                                                                              int									nFlags )
        {
            // ATTENTION: When changing this map, also the classifyAttributeName() method must
            // be checked and possibly adapted in their switch statement
            switch( mapAttributeName( rAttrName ) )
            {
                default:
                    // FALLTHROUGH intended
                case ATTRIBUTE_INVALID:
                    ENSURE_OR_THROW( false,
                                      "AnimationFactory::createEnumPropertyAnimation(): Unknown attribute" );
                    break;

                case ATTRIBUTE_CHAR_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_FONT_NAME:
                    // FALLTHROUGH intended
                case ATTRIBUTE_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_DIMCOLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_FILL_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_LINE_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_VISIBILITY:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_HEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_WEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_ROTATION:
                    // FALLTHROUGH intended
                case ATTRIBUTE_HEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_OPACITY:
                    // FALLTHROUGH intended
                case ATTRIBUTE_ROTATE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_SKEW_X:
                    // FALLTHROUGH intended
                case ATTRIBUTE_SKEW_Y:
                    // FALLTHROUGH intended
                case ATTRIBUTE_WIDTH:
                    // FALLTHROUGH intended
                case ATTRIBUTE_POS_X:
                    // FALLTHROUGH intended
                case ATTRIBUTE_POS_Y:
                    ENSURE_OR_THROW( false,
                                      "AnimationFactory::createEnumPropertyAnimation(): Attribute type mismatch" );
                    break;


                case ATTRIBUTE_FILL_STYLE:
                    return makeGenericAnimation<EnumAnimation>( rShapeManager,
                                                                nFlags,
                                                                &ShapeAttributeLayer::isFillStyleValid, 
                                                                sal::static_int_cast<sal_Int16>(
                                                                    getDefault<drawing::FillStyle>( rShape, rAttrName )),
                                                                &ShapeAttributeLayer::getFillStyle, 
                                                                &ShapeAttributeLayer::setFillStyle );

                case ATTRIBUTE_LINE_STYLE:
                    return makeGenericAnimation<EnumAnimation>( rShapeManager,
                                                                nFlags,
                                                                &ShapeAttributeLayer::isLineStyleValid, 
                                                                sal::static_int_cast<sal_Int16>(
                                                                    getDefault<drawing::LineStyle>( rShape, rAttrName )),
                                                                &ShapeAttributeLayer::getLineStyle, 
                                                                &ShapeAttributeLayer::setLineStyle );
                    
                case ATTRIBUTE_CHAR_POSTURE:
                    return makeGenericAnimation<EnumAnimation>( rShapeManager,
                                                                nFlags,
                                                                &ShapeAttributeLayer::isCharPostureValid, 
                                                                sal::static_int_cast<sal_Int16>(
                                                                    getDefault<awt::FontSlant>( rShape, rAttrName )),
                                                                &ShapeAttributeLayer::getCharPosture, 
                                                                &ShapeAttributeLayer::setCharPosture );
                    
                case ATTRIBUTE_CHAR_UNDERLINE:
                    return makeGenericAnimation<EnumAnimation>( rShapeManager,
                                                                nFlags,
                                                                &ShapeAttributeLayer::isUnderlineModeValid, 
                                                                getDefault<sal_Int16>( rShape, rAttrName ),
                                                                &ShapeAttributeLayer::getUnderlineMode, 
                                                                &ShapeAttributeLayer::setUnderlineMode );
            }
            
            return EnumAnimationSharedPtr();
        }

        ColorAnimationSharedPtr AnimationFactory::createColorPropertyAnimation( const ::rtl::OUString&				rAttrName,
                                                                                const AnimatableShapeSharedPtr&		rShape,
                                                                                const ShapeManagerSharedPtr&		rShapeManager,
                                                                                const ::basegfx::B2DVector&         /*rSlideSize*/,
                                                                                int									nFlags )
        {
            // ATTENTION: When changing this map, also the classifyAttributeName() method must
            // be checked and possibly adapted in their switch statement
            switch( mapAttributeName( rAttrName ) )
            {
                default:
                    // FALLTHROUGH intended
                case ATTRIBUTE_INVALID:
                    ENSURE_OR_THROW( false,
                                      "AnimationFactory::createColorPropertyAnimation(): Unknown attribute" );
                    break;

                case ATTRIBUTE_CHAR_FONT_NAME:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_HEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_POSTURE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_ROTATION:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_UNDERLINE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_WEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_FILL_STYLE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_HEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_LINE_STYLE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_OPACITY:
                    // FALLTHROUGH intended
                case ATTRIBUTE_ROTATE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_SKEW_X:
                    // FALLTHROUGH intended
                case ATTRIBUTE_SKEW_Y:
                    // FALLTHROUGH intended
                case ATTRIBUTE_VISIBILITY:
                    // FALLTHROUGH intended
                case ATTRIBUTE_WIDTH:
                    // FALLTHROUGH intended
                case ATTRIBUTE_POS_X:
                    // FALLTHROUGH intended
                case ATTRIBUTE_POS_Y:
                    ENSURE_OR_THROW( false,
                                      "AnimationFactory::createColorPropertyAnimation(): Attribute type mismatch" );
                    break;

                case ATTRIBUTE_CHAR_COLOR:
                    return makeGenericAnimation<ColorAnimation>( rShapeManager,
                                                                 nFlags,
                                                                 &ShapeAttributeLayer::isCharColorValid, 
                                                                 getDefault<RGBColor>( rShape, rAttrName ),
                                                                 &ShapeAttributeLayer::getCharColor, 
                                                                 &ShapeAttributeLayer::setCharColor );
                    
                case ATTRIBUTE_COLOR:
                    // TODO(F2): This is just mapped to fill color to make it work
                    return makeGenericAnimation<ColorAnimation>( rShapeManager,
                                                                 nFlags,
                                                                 &ShapeAttributeLayer::isFillColorValid, 
                                                                 getDefault<RGBColor>( rShape, rAttrName ),
                                                                 &ShapeAttributeLayer::getFillColor, 
                                                                 &ShapeAttributeLayer::setFillColor );
                    
                case ATTRIBUTE_DIMCOLOR:
                    return makeGenericAnimation<ColorAnimation>( rShapeManager,
                                                                 nFlags,
                                                                 &ShapeAttributeLayer::isDimColorValid, 
                                                                 getDefault<RGBColor>( rShape, rAttrName ),
                                                                 &ShapeAttributeLayer::getDimColor, 
                                                                 &ShapeAttributeLayer::setDimColor );

                case ATTRIBUTE_FILL_COLOR:
                    return makeGenericAnimation<ColorAnimation>( rShapeManager,
                                                                 nFlags,
                                                                 &ShapeAttributeLayer::isFillColorValid, 
                                                                 getDefault<RGBColor>( rShape, rAttrName ),
                                                                 &ShapeAttributeLayer::getFillColor, 
                                                                 &ShapeAttributeLayer::setFillColor );
                    
                case ATTRIBUTE_LINE_COLOR:
                    return makeGenericAnimation<ColorAnimation>( rShapeManager,
                                                                 nFlags,
                                                                 &ShapeAttributeLayer::isLineColorValid, 
                                                                 getDefault<RGBColor>( rShape, rAttrName ),
                                                                 &ShapeAttributeLayer::getLineColor, 
                                                                 &ShapeAttributeLayer::setLineColor );
            }

            return ColorAnimationSharedPtr();
        }

        PairAnimationSharedPtr AnimationFactory::createPairPropertyAnimation( const AnimatableShapeSharedPtr&		rShape,
                                                                              const ShapeManagerSharedPtr&			rShapeManager,
                                                                              const ::basegfx::B2DVector&           rSlideSize,
                                                                              sal_Int16								nTransformType,
                                                                              int									nFlags )
        {
            const ::basegfx::B2DRectangle& rBounds( rShape->getBounds() );

            switch( nTransformType )
            {
                case animations::AnimationTransformType::SCALE:
                    return PairAnimationSharedPtr( 
                        new TupleAnimation< ::basegfx::B2DSize >( 
                            rShapeManager,
                            nFlags,
                            &ShapeAttributeLayer::isWidthValid, 
                            &ShapeAttributeLayer::isHeightValid, 
                            // TODO(F1): Check whether _shape_ bounds are correct here.
                            // Theoretically, our AttrLayer is way down the stack, and
                            // we only have to consider _that_ value, not the one from 
                            // the top of the stack as returned by Shape::getBounds()
                            rBounds.getRange(),
                            rBounds.getRange(),
                            &ShapeAttributeLayer::getWidth, 
                            &ShapeAttributeLayer::getHeight, 
                            &ShapeAttributeLayer::setSize ) );

                case animations::AnimationTransformType::TRANSLATE:
                    return PairAnimationSharedPtr( 
                        new TupleAnimation< ::basegfx::B2DPoint >( 
                            rShapeManager,
                            nFlags,
                            &ShapeAttributeLayer::isPosXValid, 
                            &ShapeAttributeLayer::isPosYValid, 
                            // TODO(F1): Check whether _shape_ bounds are correct here.
                            // Theoretically, our AttrLayer is way down the stack, and
                            // we only have to consider _that_ value, not the one from 
                            // the top of the stack as returned by Shape::getBounds()
                            rBounds.getCenter(),
                            rSlideSize,
                            &ShapeAttributeLayer::getPosX, 
                            &ShapeAttributeLayer::getPosY, 
                            &ShapeAttributeLayer::setPosition ) );

                default:
                    ENSURE_OR_THROW( false,
                                      "AnimationFactory::createPairPropertyAnimation(): Attribute type mismatch" );
                    break;
            }

            return PairAnimationSharedPtr();
        }

        StringAnimationSharedPtr AnimationFactory::createStringPropertyAnimation( const ::rtl::OUString&				rAttrName,
                                                                                  const AnimatableShapeSharedPtr&		rShape,
                                                                                  const ShapeManagerSharedPtr&			rShapeManager,
                                                                                  const ::basegfx::B2DVector&           /*rSlideSize*/,
                                                                                  int									nFlags )
        {
            // ATTENTION: When changing this map, also the classifyAttributeName() method must
            // be checked and possibly adapted in their switch statement
            switch( mapAttributeName( rAttrName ) )
            {
                default:
                    // FALLTHROUGH intended
                case ATTRIBUTE_INVALID:
                    ENSURE_OR_THROW( false,
                                      "AnimationFactory::createStringPropertyAnimation(): Unknown attribute" );
                    break;

                case ATTRIBUTE_CHAR_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_HEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_ROTATION:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_UNDERLINE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_DIMCOLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_FILL_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_HEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_LINE_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_OPACITY:
                    // FALLTHROUGH intended
                case ATTRIBUTE_ROTATE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_SKEW_X:
                    // FALLTHROUGH intended
                case ATTRIBUTE_SKEW_Y:
                    // FALLTHROUGH intended
                case ATTRIBUTE_VISIBILITY:
                    // FALLTHROUGH intended
                case ATTRIBUTE_WIDTH:
                    // FALLTHROUGH intended
                case ATTRIBUTE_POS_X:
                    // FALLTHROUGH intended
                case ATTRIBUTE_POS_Y:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_POSTURE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_WEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_FILL_STYLE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_LINE_STYLE:
                    ENSURE_OR_THROW( false,
                                      "AnimationFactory::createStringPropertyAnimation(): Attribute type mismatch" );
                    break;

                case ATTRIBUTE_CHAR_FONT_NAME:
                    return makeGenericAnimation<StringAnimation>( rShapeManager,
                                                                  nFlags,
                                                                  &ShapeAttributeLayer::isFontFamilyValid, 
                                                                  getDefault< ::rtl::OUString >( rShape, rAttrName ),
                                                                  &ShapeAttributeLayer::getFontFamily, 
                                                                  &ShapeAttributeLayer::setFontFamily );
            }

            return StringAnimationSharedPtr();
        }

        BoolAnimationSharedPtr AnimationFactory::createBoolPropertyAnimation( const ::rtl::OUString&				rAttrName,
                                                                              const AnimatableShapeSharedPtr&		/*rShape*/,
                                                                              const ShapeManagerSharedPtr&			rShapeManager,
                                                                              const ::basegfx::B2DVector&           /*rSlideSize*/,
                                                                              int									nFlags )
        {
            // ATTENTION: When changing this map, also the classifyAttributeName() method must
            // be checked and possibly adapted in their switch statement
            switch( mapAttributeName( rAttrName ) )
            {
                default:
                    // FALLTHROUGH intended
                case ATTRIBUTE_INVALID:
                    ENSURE_OR_THROW( false,
                                      "AnimationFactory::createBoolPropertyAnimation(): Unknown attribute" );
                    break;

                case ATTRIBUTE_CHAR_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_FONT_NAME:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_HEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_POSTURE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_ROTATION:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_WEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_DIMCOLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_FILL_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_FILL_STYLE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_HEIGHT:
                    // FALLTHROUGH intended
                case ATTRIBUTE_LINE_COLOR:
                    // FALLTHROUGH intended
                case ATTRIBUTE_LINE_STYLE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_OPACITY:
                    // FALLTHROUGH intended
                case ATTRIBUTE_ROTATE:
                    // FALLTHROUGH intended
                case ATTRIBUTE_SKEW_X:
                    // FALLTHROUGH intended
                case ATTRIBUTE_SKEW_Y:
                    // FALLTHROUGH intended
                case ATTRIBUTE_WIDTH:
                    // FALLTHROUGH intended
                case ATTRIBUTE_POS_X:
                    // FALLTHROUGH intended
                case ATTRIBUTE_POS_Y:
                    // FALLTHROUGH intended
                case ATTRIBUTE_CHAR_UNDERLINE:
                    ENSURE_OR_THROW( false,
                                      "AnimationFactory::createBoolPropertyAnimation(): Attribute type mismatch" );
                    break;

                case ATTRIBUTE_VISIBILITY:
                    return makeGenericAnimation<BoolAnimation>( rShapeManager,
                                                                nFlags,
                                                                &ShapeAttributeLayer::isVisibilityValid, 
                                                                // TODO(F1): Is there a corresponding shape property?
                                                                true,
                                                                &ShapeAttributeLayer::getVisibility, 
                                                                &ShapeAttributeLayer::setVisibility );
            }

            return BoolAnimationSharedPtr();
        }

        NumberAnimationSharedPtr AnimationFactory::createPathMotionAnimation( const ::rtl::OUString&			rSVGDPath,
																			  sal_Int16							nAdditive,
                                                                              const AnimatableShapeSharedPtr&	/*rShape*/,
                                                                              const ShapeManagerSharedPtr&		rShapeManager,
                                                                              const ::basegfx::B2DVector&       rSlideSize,
                                                                              int								nFlags )
        {
            return NumberAnimationSharedPtr( 
                new PathAnimation( rSVGDPath, nAdditive,
                                   rShapeManager,
                                   rSlideSize,
                                   nFlags ) );
        }
        
    }
}
