/**************************************************************
 * 
 * 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 <rtl/logfile.hxx>
#include <osl/diagnose.hxx>
#include <com/sun/star/awt/Rectangle.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/awt/FontWeight.hpp>
#include <comphelper/anytostring.hxx>
#include <cppuhelper/exc_hlp.hxx>

#include <vcl/metaact.hxx>
#include <vcl/gdimtf.hxx>
#include <vcl/wrkwin.hxx>

#include <basegfx/numeric/ftools.hxx>
#include <basegfx/range/rangeexpander.hxx>

#include <rtl/math.hxx>

#include <com/sun/star/drawing/TextAnimationKind.hpp>

#include <vcl/svapp.hxx>
#include <vcl/window.hxx>
#include <tools/stream.hxx>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/datatransfer/XTransferable.hpp>

#include <comphelper/scopeguard.hxx>
#include <canvas/canvastools.hxx>

#include <cmath> // for trigonometry and fabs
#include <algorithm>
#include <functional>
#include <limits>

#include "drawshapesubsetting.hxx"
#include "drawshape.hxx"
#include "eventqueue.hxx"
#include "wakeupevent.hxx"
#include "subsettableshapemanager.hxx"
#include "intrinsicanimationactivity.hxx"
#include "slideshowexceptions.hxx"
#include "tools.hxx"
#include "gdimtftools.hxx"
#include "drawinglayeranimation.hxx"

#include <boost/bind.hpp>
#include <math.h>

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


namespace slideshow
{
    namespace internal
    {
        //////////////////////////////////////////////////////////////////////
        //
        // Private methods
        //
        //////////////////////////////////////////////////////////////////////

        GDIMetaFileSharedPtr DrawShape::forceScrollTextMetaFile()
        {
            if ((mnCurrMtfLoadFlags & MTF_LOAD_SCROLL_TEXT_MTF) != MTF_LOAD_SCROLL_TEXT_MTF) 
            {
                // reload with added flags:
                mpCurrMtf.reset( new GDIMetaFile );
                mnCurrMtfLoadFlags |= MTF_LOAD_SCROLL_TEXT_MTF;
                getMetaFile(
                    uno::Reference<lang::XComponent>(mxShape, uno::UNO_QUERY),
                    mxPage, *mpCurrMtf, mnCurrMtfLoadFlags,
                    mxComponentContext );

                // TODO(F1): Currently, the scroll metafile will
                // never contain any verbose text comments. Thus,
                // can only display the full mtf content, no
                // subsets.
                maSubsetting.reset( mpCurrMtf );    

                // adapt maBounds. the requested scroll text metafile
                // will typically have dimension different from the
                // actual shape
                ::basegfx::B2DRectangle aScrollRect, aPaintRect;
                ENSURE_OR_THROW( getRectanglesFromScrollMtf( aScrollRect, 
                                                              aPaintRect,
                                                              mpCurrMtf ),
                                  "DrawShape::forceScrollTextMetaFile(): Could "
                                  "not extract scroll anim rectangles from mtf" );

                // take the larger one of the two rectangles (that
                // should be the bound rect of the retrieved
                // metafile)
                if( aScrollRect.isInside( aPaintRect ) )
                    maBounds = aScrollRect;
                else
                    maBounds = aPaintRect;
            }
            return mpCurrMtf;
        }
    
        void DrawShape::updateStateIds() const
        {
            // Update the states, we've just redrawn or created a new
            // attribute layer.
            if( mpAttributeLayer )
            {
                mnAttributeTransformationState = mpAttributeLayer->getTransformationState();
                mnAttributeClipState = mpAttributeLayer->getClipState();
                mnAttributeAlphaState = mpAttributeLayer->getAlphaState();
                mnAttributePositionState = mpAttributeLayer->getPositionState();
                mnAttributeContentState = mpAttributeLayer->getContentState();
                mnAttributeVisibilityState = mpAttributeLayer->getVisibilityState();
            }
        }

        void DrawShape::ensureVerboseMtfComments() const
        {
            // TODO(F1): Text effects don't currently work for drawing
            // layer animations.

            // only touch mpCurrMtf, if we're not a DrawingLayer
            // animation.
            if( (mnCurrMtfLoadFlags & MTF_LOAD_VERBOSE_COMMENTS) == 0 &&
                maAnimationFrames.empty() )
            {
                ENSURE_OR_THROW( !maSubsetting.hasSubsetShapes(),
                                  "DrawShape::ensureVerboseMtfComments(): reloading the metafile "
                                  "with active child subsets will wreak havoc on the view!" );
                ENSURE_OR_THROW( maSubsetting.getSubsetNode().isEmpty(),
                                  "DrawShape::ensureVerboseMtfComments(): reloading the metafile "
                                  "for an ALREADY SUBSETTED shape is not possible!" );

                // re-fetch metafile with comments
                // note that, in case of shapes without text, the new
                // metafile might still not provide any useful
                // subsetting information!
                mpCurrMtf.reset( new GDIMetaFile );
                mnCurrMtfLoadFlags |= MTF_LOAD_VERBOSE_COMMENTS;
                getMetaFile(
                    uno::Reference<lang::XComponent>(mxShape, uno::UNO_QUERY),
                    mxPage, *mpCurrMtf, mnCurrMtfLoadFlags,
                    mxComponentContext );

                maSubsetting.reset( maSubsetting.getSubsetNode(),
                                    mpCurrMtf );
            }
        }

        ViewShape::RenderArgs DrawShape::getViewRenderArgs() const
        {
            return ViewShape::RenderArgs(
                maBounds,
                getUpdateArea(),
                getBounds(),
                getActualUnitShapeBounds(),
                mpAttributeLayer,
                maSubsetting.getActiveSubsets(),
                mnPriority);
        }

        bool DrawShape::implRender( int nUpdateFlags ) const
        {
            RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::DrawShape::implRender()" );
            RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::presentation::internal::DrawShape: 0x%X", this );

            // will perform the update now, clear update-enforcing
            // flags
            mbForceUpdate = false;
            mbAttributeLayerRevoked = false;

            ENSURE_OR_RETURN_FALSE( !maViewShapes.empty(),
                               "DrawShape::implRender(): render called on DrawShape without views" );

            if( maBounds.isEmpty() )
            {
                // zero-sized shapes are effectively invisible,
                // thus, we save us the rendering...
                return true;
            }

            // redraw all view shapes, by calling their update() method
            if( ::std::count_if( maViewShapes.begin(),
                                 maViewShapes.end(),
                                 ::boost::bind<bool>(
                                     ::boost::mem_fn( &ViewShape::update ), // though _theoretically_,
                                     										// bind should eat this even
                                     										// with _1 being a shared_ptr,
                                     										// it does _not_ for MSVC without
                                     										// the extra mem_fn. WTF.
                                     _1,
                                     ::boost::cref( mpCurrMtf ),
                                     ::boost::cref(
                                         getViewRenderArgs() ), 
                                     nUpdateFlags,
                                     isVisible() ) ) 
                != static_cast<ViewShapeVector::difference_type>(maViewShapes.size()) )
            {
                // at least one of the ViewShape::update() calls did return 
                // false - update failed on at least one ViewLayer
                return false;
            }

            // successfully redrawn - update state IDs to detect next changes
            updateStateIds();

            return true;
        }

        int DrawShape::getUpdateFlags() const
        {
            // default: update nothing, unless ShapeAttributeStack
            // tells us below, or if the attribute layer was revoked
            int nUpdateFlags(ViewShape::NONE);

            // possibly the whole shape content changed
            if( mbAttributeLayerRevoked )
                nUpdateFlags = ViewShape::CONTENT;


            // determine what has to be updated
            // --------------------------------

            // do we have an attribute layer?
            if( mpAttributeLayer )
            {
                // Prevent nUpdateFlags to be modified when the shape is not
                // visible, except when it just was hidden.
                if (mpAttributeLayer->getVisibility()
                    || mpAttributeLayer->getVisibilityState() != mnAttributeVisibilityState )
                {
                    if (mpAttributeLayer->getVisibilityState() != mnAttributeVisibilityState )
                    {
                        // Change of the visibility state is mapped to
                        // content change because when the visibility
                        // changes then usually a sprite is shown or hidden
                        // and the background under has to be painted once.
                        nUpdateFlags |= ViewShape::CONTENT;
                    }

                    // TODO(P1): This can be done without conditional branching. 
                    // See HAKMEM.
                    if( mpAttributeLayer->getPositionState() != mnAttributePositionState )
                    {
                        nUpdateFlags |= ViewShape::POSITION;
                    }
                    if( mpAttributeLayer->getAlphaState() != mnAttributeAlphaState )
                    {
                        nUpdateFlags |= ViewShape::ALPHA;
                    }
                    if( mpAttributeLayer->getClipState() != mnAttributeClipState )
                    {
                        nUpdateFlags |= ViewShape::CLIP;
                    }
                    if( mpAttributeLayer->getTransformationState() != mnAttributeTransformationState )
                    {                
                        nUpdateFlags |= ViewShape::TRANSFORMATION;
                    }
                    if( mpAttributeLayer->getContentState() != mnAttributeContentState )
                    {                
                        nUpdateFlags |= ViewShape::CONTENT;
                    }
                }
            }

            return nUpdateFlags;
        }

        ::basegfx::B2DRectangle DrawShape::getActualUnitShapeBounds() const
        {
            ENSURE_OR_THROW( !maViewShapes.empty(),
                              "DrawShape::getActualUnitShapeBounds(): called on DrawShape without views" );

            const VectorOfDocTreeNodes& rSubsets( 
                maSubsetting.getActiveSubsets() );

            const ::basegfx::B2DRectangle aDefaultBounds( 0.0,0.0,1.0,1.0 );

            // perform the cheapest check first
            if( rSubsets.empty() )
            {
                // if subset contains the whole shape, no need to call
                // the somewhat expensive bound calculation, since as
                // long as the subset is empty, this branch will be
                // taken.
                return aDefaultBounds;
            }
            else
            {
                OSL_ENSURE( rSubsets.size() != 1 ||
                            !rSubsets.front().isEmpty(),
                            "DrawShape::getActualUnitShapeBounds() expects a "
                            "_non-empty_ subset vector for a subsetted shape!" );

                // are the cached bounds still valid?
                if( !maCurrentShapeUnitBounds )
                {
                    // no, (re)generate them
                    // =====================

                    // setup cached values to defaults (might fail to
                    // retrieve true bounds below)
                    maCurrentShapeUnitBounds.reset( aDefaultBounds );

                    // TODO(P2): the subset of the master shape (that from
                    // which the subsets are subtracted) changes
                    // relatively often (every time a subset shape is
                    // added or removed). Maybe we should exclude it here,
                    // always assuming full bounds?

                    ::cppcanvas::CanvasSharedPtr pDestinationCanvas( 
                        maViewShapes.front()->getViewLayer()->getCanvas() );

                    // TODO(Q2): Although this _is_ currently
                    // view-agnostic, it might not stay like
                    // that. Maybe this method should again be moved
                    // to the ViewShape
                    ::cppcanvas::RendererSharedPtr pRenderer( 
                        maViewShapes.front()->getRenderer( 
                            pDestinationCanvas, mpCurrMtf, mpAttributeLayer ) );

                    // If we cannot not prefetch, be defensive and assume
                    // full shape size
                    if( pRenderer )
                    {
                        // temporarily, switch total transformation to identity
                        // (need the bounds in the [0,1]x[0,1] unit coordinate
                        // system.
                        ::basegfx::B2DHomMatrix 	 aEmptyTransformation;

                        ::basegfx::B2DHomMatrix 	 aOldTransform( pDestinationCanvas->getTransformation() );
                        pDestinationCanvas->setTransformation( aEmptyTransformation );
                        pRenderer->setTransformation( aEmptyTransformation );            

                        // restore old transformation when leaving the scope
                        const ::comphelper::ScopeGuard aGuard(
                            boost::bind( &::cppcanvas::Canvas::setTransformation,
                                         pDestinationCanvas, aOldTransform ) );


                        // retrieve bounds for subset of whole metafile
                        // --------------------------------------------

                        ::basegfx::B2DRange aTotalBounds;

                        // cannot use ::boost::bind, ::basegfx::B2DRange::expand()
                        // is overloaded.
                        VectorOfDocTreeNodes::const_iterator 		aCurr( rSubsets.begin() );
                        const VectorOfDocTreeNodes::const_iterator	aEnd( rSubsets.end() );
                        while( aCurr != aEnd )
                        {
                            aTotalBounds.expand( pRenderer->getSubsetArea( 
                                                     aCurr->getStartIndex(),
                                                     aCurr->getEndIndex() )  );
                            ++aCurr;
                        }
                    
                        OSL_ENSURE( aTotalBounds.getMinX() >= -0.1 &&
                                    aTotalBounds.getMinY() >= -0.1 &&
                                    aTotalBounds.getMaxX() <= 1.1 &&
                                    aTotalBounds.getMaxY() <= 1.1,
                                    "DrawShape::getActualUnitShapeBounds(): bounds noticeably larger than original shape - clipping!" );

                        // really make sure no shape appears larger than its
                        // original bounds (there _are_ some pathologic cases,
                        // especially when imported from PPT, that have
                        // e.g. obscenely large polygon bounds)
                        aTotalBounds.intersect( 
                            ::basegfx::B2DRange( 0.0, 0.0,
                                                 1.0, 1.0 ));

                        maCurrentShapeUnitBounds.reset( aTotalBounds );
                    }
                }

                return *maCurrentShapeUnitBounds;
            }
        }

        DrawShape::DrawShape( const uno::Reference< drawing::XShape >& 		xShape,
                              const uno::Reference< drawing::XDrawPage >&	xContainingPage,
                              double										nPrio,
                              bool											bForeignSource,
                              const SlideShowContext&                       rContext ) :
            mxShape( xShape ),
            mxPage( xContainingPage ),
            maAnimationFrames(), // empty, we don't have no intrinsic animation
            mnCurrFrame(0),
            mpCurrMtf(),
            mnCurrMtfLoadFlags( bForeignSource
                                ? MTF_LOAD_FOREIGN_SOURCE : MTF_LOAD_NONE ),
            maCurrentShapeUnitBounds(),
            mnPriority( nPrio ), // TODO(F1): When ZOrder someday becomes usable: make this ( getAPIShapePrio( xShape ) ),
            maBounds( getAPIShapeBounds( xShape ) ),
            mpAttributeLayer(),
            mpIntrinsicAnimationActivity(),
            mnAttributeTransformationState(0),
            mnAttributeClipState(0),
            mnAttributeAlphaState(0),
            mnAttributePositionState(0),
            mnAttributeContentState(0),
            mnAttributeVisibilityState(0),
            maViewShapes(),
            mxComponentContext( rContext.mxComponentContext ),
            maHyperlinkIndices(),
            maHyperlinkRegions(),
            maSubsetting(),
            mnIsAnimatedCount(0),
            mnAnimationLoopCount(0),
            meCycleMode(CYCLE_LOOP),
            mbIsVisible( true ),
            mbForceUpdate( false ),
            mbAttributeLayerRevoked( false ),
            mbDrawingLayerAnim( false )
        {
            ENSURE_OR_THROW( mxShape.is(), "DrawShape::DrawShape(): Invalid XShape" );
            ENSURE_OR_THROW( mxPage.is(), "DrawShape::DrawShape(): Invalid containing page" );
            
            // check for drawing layer animations:
            drawing::TextAnimationKind eKind = drawing::TextAnimationKind_NONE;
            uno::Reference<beans::XPropertySet> xPropSet( mxShape, 
                                                          uno::UNO_QUERY );
            if( xPropSet.is() )
                getPropertyValue( eKind, xPropSet,
                                  OUSTR("TextAnimationKind") );
            mbDrawingLayerAnim = (eKind != drawing::TextAnimationKind_NONE);
            
            // must NOT be called from within initializer list, uses
            // state from mnCurrMtfLoadFlags!
            mpCurrMtf.reset( new GDIMetaFile );
            getMetaFile(
                uno::Reference<lang::XComponent>(xShape, uno::UNO_QUERY),
                xContainingPage, *mpCurrMtf, mnCurrMtfLoadFlags,
                mxComponentContext );
            ENSURE_OR_THROW( mpCurrMtf,
                              "DrawShape::DrawShape(): Invalid metafile" );
            maSubsetting.reset( mpCurrMtf );
            
            prepareHyperlinkIndices();
        }

        DrawShape::DrawShape( const uno::Reference< drawing::XShape >& 		xShape,
                              const uno::Reference< drawing::XDrawPage >&	xContainingPage,
                              double										nPrio,
                              const Graphic&								rGraphic,
                              const SlideShowContext&                       rContext ) :
            mxShape( xShape ),
            mxPage( xContainingPage ),
            maAnimationFrames(),
            mnCurrFrame(0),
            mpCurrMtf(),
            mnCurrMtfLoadFlags( MTF_LOAD_NONE ),
            maCurrentShapeUnitBounds(),
            mnPriority( nPrio ), // TODO(F1): When ZOrder someday becomes usable: make this ( getAPIShapePrio( xShape ) ),
            maBounds( getAPIShapeBounds( xShape ) ),
            mpAttributeLayer(),
            mpIntrinsicAnimationActivity(),
            mnAttributeTransformationState(0),
            mnAttributeClipState(0),
            mnAttributeAlphaState(0),
            mnAttributePositionState(0),
            mnAttributeContentState(0),
            mnAttributeVisibilityState(0),
            maViewShapes(),
            mxComponentContext( rContext.mxComponentContext ),
            maHyperlinkIndices(),
            maHyperlinkRegions(),
            maSubsetting(),
            mnIsAnimatedCount(0),
            mnAnimationLoopCount(0),
            meCycleMode(CYCLE_LOOP),
            mbIsVisible( true ),
            mbForceUpdate( false ),
            mbAttributeLayerRevoked( false ),
            mbDrawingLayerAnim( false )
        {
            ENSURE_OR_THROW( rGraphic.IsAnimated(),
                              "DrawShape::DrawShape(): Graphic is no animation" );

            getAnimationFromGraphic( maAnimationFrames,
                                     mnAnimationLoopCount,
                                     meCycleMode,
                                     rGraphic );

            ENSURE_OR_THROW( !maAnimationFrames.empty() &&
                              maAnimationFrames.front().mpMtf,
                              "DrawShape::DrawShape(): " );
            mpCurrMtf = maAnimationFrames.front().mpMtf;

            ENSURE_OR_THROW( mxShape.is(), "DrawShape::DrawShape(): Invalid XShape" );
            ENSURE_OR_THROW( mxPage.is(), "DrawShape::DrawShape(): Invalid containing page" );
            ENSURE_OR_THROW( mpCurrMtf, "DrawShape::DrawShape(): Invalid metafile" );
        }

        DrawShape::DrawShape( const DrawShape& 		rSrc, 
                              const DocTreeNode& 	rTreeNode,
                              double				nPrio ) :
            mxShape( rSrc.mxShape ),
            mxPage( rSrc.mxPage ),
            maAnimationFrames(), // don't copy animations for subsets,
                                 // only the current frame!
            mnCurrFrame(0),
            mpCurrMtf( rSrc.mpCurrMtf ),
            mnCurrMtfLoadFlags( rSrc.mnCurrMtfLoadFlags ),
            maCurrentShapeUnitBounds(),
            mnPriority( nPrio ),
            maBounds( rSrc.maBounds ),
            mpAttributeLayer(),
            mpIntrinsicAnimationActivity(),
            mnAttributeTransformationState(0),
            mnAttributeClipState(0),
            mnAttributeAlphaState(0),
            mnAttributePositionState(0),
            mnAttributeContentState(0),
            mnAttributeVisibilityState(0),
            maViewShapes(),
            mxComponentContext( rSrc.mxComponentContext ),
            maHyperlinkIndices(),
            maHyperlinkRegions(),
            maSubsetting( rTreeNode, mpCurrMtf ),
            mnIsAnimatedCount(0),
            mnAnimationLoopCount(0),
            meCycleMode(CYCLE_LOOP),
            mbIsVisible( rSrc.mbIsVisible ),
            mbForceUpdate( false ),
            mbAttributeLayerRevoked( false ),
            mbDrawingLayerAnim( false )
        {
            ENSURE_OR_THROW( mxShape.is(), "DrawShape::DrawShape(): Invalid XShape" );
            ENSURE_OR_THROW( mpCurrMtf, "DrawShape::DrawShape(): Invalid metafile" );

            // xxx todo: currently not implemented for subsetted shapes;
            //           would mean modifying set of hyperlink regions when
            //           subsetting text portions. N.B.: there's already an 
            //           issue for this #i72828#
        }

        //////////////////////////////////////////////////////////////////////
        //
        // Public methods
        //
        //////////////////////////////////////////////////////////////////////

        DrawShapeSharedPtr DrawShape::create(
            const uno::Reference< drawing::XShape >& 	xShape,
            const uno::Reference< drawing::XDrawPage >&	xContainingPage,
            double										nPrio,
            bool										bForeignSource,
            const SlideShowContext&                     rContext )
        {
            DrawShapeSharedPtr pShape( new DrawShape(xShape,
                                                     xContainingPage,
                                                     nPrio,
                                                     bForeignSource,
                                                     rContext) );

            if( pShape->hasIntrinsicAnimation() )
            {
                OSL_ASSERT( pShape->maAnimationFrames.empty() );
                if( pShape->getNumberOfTreeNodes( 
                        DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH) > 0 )
                {
                    pShape->mpIntrinsicAnimationActivity = 
                        createDrawingLayerAnimActivity(
                            rContext,
                            pShape);
                }
            }

            if( pShape->hasHyperlinks() )
                rContext.mpSubsettableShapeManager->addHyperlinkArea( pShape );

            return pShape;
        }

        DrawShapeSharedPtr DrawShape::create( 
            const uno::Reference< drawing::XShape >& 	xShape,
            const uno::Reference< drawing::XDrawPage >&	xContainingPage,
            double										nPrio,
            const Graphic&								rGraphic,
            const SlideShowContext&                     rContext )
        {
            DrawShapeSharedPtr pShape( new DrawShape(xShape, 
                                                     xContainingPage, 
                                                     nPrio, 
                                                     rGraphic, 
                                                     rContext) );

            if( pShape->hasIntrinsicAnimation() )
            {
                OSL_ASSERT( !pShape->maAnimationFrames.empty() );

                std::vector<double> aTimeout;
                std::transform(
                    pShape->maAnimationFrames.begin(),
                    pShape->maAnimationFrames.end(),
                    std::back_insert_iterator< std::vector<double> >( aTimeout ),
                    boost::mem_fn(&MtfAnimationFrame::getDuration) );
                
                WakeupEventSharedPtr pWakeupEvent(
                    new WakeupEvent( rContext.mrEventQueue.getTimer(),
                                     rContext.mrActivitiesQueue ) );
                
                ActivitySharedPtr pActivity = 
                    createIntrinsicAnimationActivity(
                        rContext,
                        pShape,
                        pWakeupEvent,
                        aTimeout,
                        pShape->mnAnimationLoopCount,
                        pShape->meCycleMode);

                pWakeupEvent->setActivity( pActivity );
                pShape->mpIntrinsicAnimationActivity = pActivity;
            }
            
            OSL_ENSURE( !pShape->hasHyperlinks(),
                        "DrawShape::create(): graphic-only shapes must not have hyperlinks!" );

            return pShape;
        }

        DrawShape::~DrawShape()
        {
            try
            {
                // dispose intrinsic animation activity, else, it will  
                // linger forever   
                ActivitySharedPtr pActivity( mpIntrinsicAnimationActivity.lock() );
                if( pActivity )
                    pActivity->dispose();
            }
            catch (uno::Exception &) 
            {
                OSL_ENSURE( false, rtl::OUStringToOString(
                                comphelper::anyToString(
                                    cppu::getCaughtException() ),
                                RTL_TEXTENCODING_UTF8 ).getStr() );
            }
        }

        uno::Reference< drawing::XShape > DrawShape::getXShape() const
        {
            return mxShape;
        }

        void DrawShape::addViewLayer( const ViewLayerSharedPtr& rNewLayer,
                                      bool						bRedrawLayer )
        {
            ViewShapeVector::iterator aEnd( maViewShapes.end() );

            // already added?
            if( ::std::find_if( maViewShapes.begin(), 
                                aEnd, 
                                ::boost::bind<bool>( 
                                    ::std::equal_to< ViewLayerSharedPtr >(),
                                    ::boost::bind( &ViewShape::getViewLayer,
                                                   _1 ),
                                    ::boost::cref( rNewLayer ) ) ) != aEnd )
            {
                // yes, nothing to do
                return;
            }

            ViewShapeSharedPtr pNewShape( new ViewShape( rNewLayer ) );

            maViewShapes.push_back( pNewShape );

            // pass on animation state
            if( mnIsAnimatedCount )
            {
                for( int i=0; i<mnIsAnimatedCount; ++i )
                    pNewShape->enterAnimationMode();
            }

            // render the Shape on the newly added ViewLayer
            if( bRedrawLayer )
            {
                pNewShape->update( mpCurrMtf, 
                                   getViewRenderArgs(),
                                   ViewShape::FORCE, 
                                   isVisible() );
            }
        }

        bool DrawShape::removeViewLayer( const ViewLayerSharedPtr& rLayer )
        {
            const ViewShapeVector::iterator aEnd( maViewShapes.end() );

            OSL_ENSURE( ::std::count_if(maViewShapes.begin(), 
                                        aEnd, 
                                        ::boost::bind<bool>( 
                                            ::std::equal_to< ViewLayerSharedPtr >(),
                                            ::boost::bind( &ViewShape::getViewLayer,
                                                           _1 ),
                                            ::boost::cref( rLayer ) ) ) < 2,
                        "DrawShape::removeViewLayer(): Duplicate ViewLayer entries!" );

            ViewShapeVector::iterator aIter;

            if( (aIter=::std::remove_if( maViewShapes.begin(), 
                                         aEnd, 
                                         ::boost::bind<bool>( 
                                             ::std::equal_to< ViewLayerSharedPtr >(),
                                             ::boost::bind( &ViewShape::getViewLayer,
                                                            _1 ),
                                             ::boost::cref( rLayer ) ) )) == aEnd )
            {
                // view layer seemingly was not added, failed
                return false;
            }

            // actually erase from container
            maViewShapes.erase( aIter, aEnd );

            return true;
        }

        bool DrawShape::clearAllViewLayers()
        {
            maViewShapes.clear();
            return true;
        }

        bool DrawShape::update() const
        {
            if( mbForceUpdate )
            {
                return render();
            }
            else
            {
                return implRender( getUpdateFlags() );
            }
        }

        bool DrawShape::render() const
        {
            // force redraw. Have to also pass on the update flags,
            // because e.g. content update (regeneration of the
            // metafile renderer) is normally not performed. A simple
            // ViewShape::FORCE would only paint the metafile in its
            // old state.
            return implRender( ViewShape::FORCE | getUpdateFlags() );
        }

        bool DrawShape::isContentChanged() const
        {
            return mbForceUpdate ? 
                true : 
                getUpdateFlags() != ViewShape::NONE;
        }


        ::basegfx::B2DRectangle DrawShape::getBounds() const
        {
            // little optimization: for non-modified shapes, we don't
            // create an ShapeAttributeStack, and therefore also don't
            // have to check it.
            return getShapePosSize( maBounds,
                                    mpAttributeLayer );
        }

        ::basegfx::B2DRectangle DrawShape::getDomBounds() const
        {
            return maBounds;
        }

        namespace
        {
            /** Functor expanding AA border for each passed ViewShape

            	Could not use ::boost::bind here, since
            	B2DRange::expand is overloaded (which yields one or
            	the other template type deduction ambiguous)
             */
            class Expander
            {
            public: 
                Expander( ::basegfx::B2DSize& rBounds ) :
                    mrBounds( rBounds )
                {
                }

                void operator()( const ViewShapeSharedPtr& rShape ) const
                {
                    const ::basegfx::B2DSize& rShapeBorder( rShape->getAntialiasingBorder() );

                    mrBounds.setX( 
                        ::std::max(
                            rShapeBorder.getX(),
                            mrBounds.getX() ) );
                    mrBounds.setY( 
                        ::std::max(
                            rShapeBorder.getY(),
                            mrBounds.getY() ) );
                }

            private:
                ::basegfx::B2DSize& mrBounds;
            };
        }

        ::basegfx::B2DRectangle DrawShape::getUpdateArea() const
        {
            ::basegfx::B2DRectangle aBounds;

            // an already empty shape bound need no further
            // treatment. In fact, any changes applied below would
            // actually remove the special empty state, thus, don't
            // change!
            if( !maBounds.isEmpty() )
            {
                basegfx::B2DRectangle aUnitBounds(0.0,0.0,1.0,1.0);

                if( !maViewShapes.empty() )
                    aUnitBounds = getActualUnitShapeBounds();

                if( !aUnitBounds.isEmpty() )
                {
                    if( mpAttributeLayer )
                    {
                        // calc actual shape area (in user coordinate
                        // space) from the transformation as given by the
                        // shape attribute layer
                        aBounds = getShapeUpdateArea( aUnitBounds,
                                                      getShapeTransformation( getBounds(),
                                                                              mpAttributeLayer ),
                                                      mpAttributeLayer );
                    }
                    else
                    {
                        // no attribute layer, thus, the true shape bounds
                        // can be directly derived from the XShape bound
                        // attribute
                        aBounds = getShapeUpdateArea( aUnitBounds,
                                                      maBounds );
                    }

                    if( !maViewShapes.empty() )
                    {
                        // determine border needed for antialiasing the shape
                        ::basegfx::B2DSize aAABorder(0.0,0.0);

                        // for every view, get AA border and 'expand' aAABorder
                        // appropriately.
                        ::std::for_each( maViewShapes.begin(),
                                         maViewShapes.end(),
                                         Expander( aAABorder ) );

                        // add calculated AA border to aBounds
                        aBounds = ::basegfx::B2DRectangle( aBounds.getMinX() - aAABorder.getX(),
                                                           aBounds.getMinY() - aAABorder.getY(),
                                                           aBounds.getMaxX() + aAABorder.getX(),
                                                           aBounds.getMaxY() + aAABorder.getY() );
                    }
                }
            }

            return aBounds;
        }

        bool DrawShape::isVisible() const
        {
            bool bIsVisible( mbIsVisible );

            if( mpAttributeLayer )
            {
                // check whether visibility and alpha are not default
                // (mpAttributeLayer->isVisibilityValid() returns true
                // then): bVisible becomes true, if shape visibility
                // is on and alpha is not 0.0 (fully transparent)
                if( mpAttributeLayer->isVisibilityValid() )
                    bIsVisible = mpAttributeLayer->getVisibility();

                // only touch bIsVisible, if the shape is still
                // visible - if getVisibility already made us
                // invisible, no alpha value will make us appear
                // again.
                if( bIsVisible && mpAttributeLayer->isAlphaValid() )
                    bIsVisible = !::basegfx::fTools::equalZero( mpAttributeLayer->getAlpha() );
            }

            return bIsVisible;
        }

        double DrawShape::getPriority() const
        {
            return mnPriority;
        }

        bool DrawShape::isBackgroundDetached() const
        {
            return mnIsAnimatedCount > 0;
        }

        bool DrawShape::hasIntrinsicAnimation() const
        {
            return (!maAnimationFrames.empty() || mbDrawingLayerAnim);
        }

        bool DrawShape::setIntrinsicAnimationFrame( ::std::size_t nCurrFrame )
        {
            ENSURE_OR_RETURN_FALSE( nCurrFrame < maAnimationFrames.size(),
                               "DrawShape::setIntrinsicAnimationFrame(): frame index out of bounds" );

            if( mnCurrFrame != nCurrFrame )
            {
                mnCurrFrame   = nCurrFrame;
                mpCurrMtf     = maAnimationFrames[ mnCurrFrame ].mpMtf;
                mbForceUpdate = true;
            }

            return true;
        }

        // hyperlink support
        void DrawShape::prepareHyperlinkIndices() const
        {
            if ( !maHyperlinkIndices.empty())
            {
                maHyperlinkIndices.clear();
                maHyperlinkRegions.clear();
            }

            sal_Int32 nIndex = 0;
            for ( MetaAction * pCurrAct = mpCurrMtf->FirstAction();
                  pCurrAct != 0; pCurrAct = mpCurrMtf->NextAction() )
            {
                if (pCurrAct->GetType() == META_COMMENT_ACTION) {
                    MetaCommentAction * pAct =
                        static_cast<MetaCommentAction *>(pCurrAct);
                    // skip comment if not a special XTEXT comment
                    if (pAct->GetComment().CompareIgnoreCaseToAscii(
                            RTL_CONSTASCII_STRINGPARAM("FIELD_SEQ_BEGIN") ) ==
                        COMPARE_EQUAL &&
                        // e.g. date field doesn't have data!
                        // currently assuming that only url field, this is
                        // somehow fragile! xxx todo if possible
                        pAct->GetData() != 0 &&
                        pAct->GetDataSize() > 0)
                    {
                        if (!maHyperlinkIndices.empty() &&
                            maHyperlinkIndices.back().second == -1) {
                            OSL_ENSURE( false, "### pending FIELD_SEQ_END!" );
                            maHyperlinkIndices.pop_back();
                            maHyperlinkRegions.pop_back();
                        }
                        maHyperlinkIndices.push_back(
                            HyperlinkIndexPair( nIndex + 1,
                                                -1 /* to be filled below */ ) );
                        maHyperlinkRegions.push_back(
                            HyperlinkRegion(
                                basegfx::B2DRectangle(),
                                rtl::OUString(
                                    reinterpret_cast<sal_Unicode const*>(
                                        pAct->GetData()),
                                    pAct->GetDataSize() / sizeof(sal_Unicode) )
                                ) );
                    }
                    else if (pAct->GetComment().CompareIgnoreCaseToAscii(
                                 RTL_CONSTASCII_STRINGPARAM("FIELD_SEQ_END")) ==
                             COMPARE_EQUAL &&
                             // pending end is expected:
                             !maHyperlinkIndices.empty() &&
                             maHyperlinkIndices.back().second == -1)
                    {
                        maHyperlinkIndices.back().second = nIndex;
                    }
                    ++nIndex;
                }
                else
                    nIndex += getNextActionOffset(pCurrAct);
            }
            if (!maHyperlinkIndices.empty() &&
                maHyperlinkIndices.back().second == -1) {
                OSL_ENSURE( false, "### pending FIELD_SEQ_END!" );
                maHyperlinkIndices.pop_back();
                maHyperlinkRegions.pop_back();
            }
            OSL_ASSERT( maHyperlinkIndices.size() == maHyperlinkRegions.size());
        }

        bool DrawShape::hasHyperlinks() const
        {
            return ! maHyperlinkRegions.empty();
        }
    
        HyperlinkArea::HyperlinkRegions DrawShape::getHyperlinkRegions() const
        {
            OSL_ASSERT( !maViewShapes.empty() );

            if( !isVisible() )
                return HyperlinkArea::HyperlinkRegions();

            // late init, determine regions:
            if( !maHyperlinkRegions.empty() &&
                !maViewShapes.empty() &&
                // region already inited?
                maHyperlinkRegions.front().first.getWidth() == 0 &&
                maHyperlinkRegions.front().first.getHeight() == 0 &&
                maHyperlinkRegions.size() == maHyperlinkIndices.size() )
            {
                // TODO(Q2): Although this _is_ currently
                // view-agnostic, it might not stay like that.
                ViewShapeSharedPtr const& pViewShape = maViewShapes.front();
                cppcanvas::CanvasSharedPtr const pCanvas(
                    pViewShape->getViewLayer()->getCanvas() );

                // reuse Renderer of first view shape:
                cppcanvas::RendererSharedPtr const pRenderer( 
                    pViewShape->getRenderer(
                        pCanvas, mpCurrMtf, mpAttributeLayer ) );

                OSL_ASSERT( pRenderer );

                if (pRenderer) 
                {
                    basegfx::B2DHomMatrix const aOldTransform(
                        pCanvas->getTransformation() );
                    basegfx::B2DHomMatrix aTransform;
                    pCanvas->setTransformation( aTransform /* empty */ );

                    comphelper::ScopeGuard const resetOldTransformation(
                        boost::bind( &cppcanvas::Canvas::setTransformation,
                                     pCanvas.get(),
                                     boost::cref(aOldTransform) ));

                    aTransform.scale( maBounds.getWidth(),
                                      maBounds.getHeight() );
                    pRenderer->setTransformation( aTransform );
                    pRenderer->setClip();
                    
                    for( std::size_t pos = maHyperlinkRegions.size(); pos--; ) 
                    {
                        // get region:
                        HyperlinkIndexPair const& rIndices = maHyperlinkIndices[pos];
                        basegfx::B2DRectangle const region(
                            pRenderer->getSubsetArea( rIndices.first,
                                                      rIndices.second ));
                        maHyperlinkRegions[pos].first = region;
                    }
                }
            }

            // shift shape-relative hyperlink regions to
            // slide-absolute position

            HyperlinkRegions aTranslatedRegions;
            const basegfx::B2DPoint& rOffset(getBounds().getMinimum());
            HyperlinkRegions::const_iterator       aIter( maHyperlinkRegions.begin() );
            HyperlinkRegions::const_iterator const aEnd ( maHyperlinkRegions.end() );
            while( aIter != aEnd )
            {
                basegfx::B2DRange const& relRegion( aIter->first );
                aTranslatedRegions.push_back(
                    std::make_pair(
                        basegfx::B2DRange(
                            relRegion.getMinimum() + rOffset,
                            relRegion.getMaximum() + rOffset),
                        aIter->second) );
                ++aIter;
            }

            return aTranslatedRegions;
        }

        double DrawShape::getHyperlinkPriority() const
        {
            return getPriority();
        }


        // AnimatableShape methods
        // ======================================================

        void DrawShape::enterAnimationMode()
        {
            OSL_ENSURE( !maViewShapes.empty(),
                        "DrawShape::enterAnimationMode(): called on DrawShape without views" );

            if( mnIsAnimatedCount == 0 )
            {
                // notify all ViewShapes, by calling their enterAnimationMode method.
                // We're now entering animation mode
                ::std::for_each( maViewShapes.begin(),
                                 maViewShapes.end(),
                                 ::boost::mem_fn( &ViewShape::enterAnimationMode ) );
            }

            ++mnIsAnimatedCount;
        }

        void DrawShape::leaveAnimationMode()
        {
            OSL_ENSURE( !maViewShapes.empty(),
                        "DrawShape::leaveAnimationMode(): called on DrawShape without views" );

            --mnIsAnimatedCount;

            if( mnIsAnimatedCount == 0 )
            {
                // notify all ViewShapes, by calling their leaveAnimationMode method.
                // we're now leaving animation mode
                ::std::for_each( maViewShapes.begin(),
                                 maViewShapes.end(),
                                 ::boost::mem_fn( &ViewShape::leaveAnimationMode ) );
            }
        }


        // AttributableShape methods
        // ======================================================

        ShapeAttributeLayerSharedPtr DrawShape::createAttributeLayer()
        {
            // create new layer, with last as its new child
            mpAttributeLayer.reset( new ShapeAttributeLayer( mpAttributeLayer ) );

            // Update the local state ids to reflect those of the new layer.
            updateStateIds();

            return mpAttributeLayer;
        }

        bool DrawShape::revokeAttributeLayer( const ShapeAttributeLayerSharedPtr& rLayer )
        {
            if( !mpAttributeLayer )
                return false; // no layers

            if( mpAttributeLayer == rLayer )
            {
                // it's the toplevel layer
                mpAttributeLayer = mpAttributeLayer->getChildLayer();
                
                // force content redraw, all state variables have
                // possibly changed
                mbAttributeLayerRevoked = true;

                return true;
            }
            else
            {
                // pass on to the layer, to try its children
                return mpAttributeLayer->revokeChildLayer( rLayer );
            }
        }

        ShapeAttributeLayerSharedPtr DrawShape::getTopmostAttributeLayer() const
        {
            return mpAttributeLayer;
        }

        void DrawShape::setVisibility( bool bVisible )
        {
            if( mbIsVisible != bVisible )
            {
                mbIsVisible = bVisible;
                mbForceUpdate = true;
            }
        }

        const DocTreeNodeSupplier& DrawShape::getTreeNodeSupplier() const
        {
            return *this;
        }

        DocTreeNodeSupplier& DrawShape::getTreeNodeSupplier()
        {
            return *this;
        }

        DocTreeNode DrawShape::getSubsetNode() const
        {
            ensureVerboseMtfComments();

            // forward to delegate
            return maSubsetting.getSubsetNode();
        }

        AttributableShapeSharedPtr DrawShape::getSubset( const DocTreeNode& rTreeNode ) const
        {
            ENSURE_OR_THROW( (mnCurrMtfLoadFlags & MTF_LOAD_VERBOSE_COMMENTS) != 0,
                              "DrawShape::getSubset(): subset query on shape with apparently no subsets" );
            
            // forward to delegate
            return maSubsetting.getSubsetShape( rTreeNode );
        }

        bool DrawShape::createSubset( AttributableShapeSharedPtr& 	o_rSubset,
                                      const DocTreeNode& 			rTreeNode )
        {
            ENSURE_OR_THROW( (mnCurrMtfLoadFlags & MTF_LOAD_VERBOSE_COMMENTS) != 0,
                              "DrawShape::createSubset(): subset query on shape with apparently no subsets" );

            // subset shape already created for this DocTreeNode?
            AttributableShapeSharedPtr pSubset( maSubsetting.getSubsetShape( rTreeNode ) );

            // when true, this method has created a new subset
            // DrawShape
            bool bNewlyCreated( false );

            if( pSubset )
            {
                o_rSubset = pSubset;

                // reusing existing subset
            }
            else
            {
                // not yet created, init entry
                o_rSubset.reset( new DrawShape( *this, 
                                                rTreeNode, 
                                                // TODO(Q3): That's a
                                                // hack. We assume
                                                // that start and end
                                                // index will always
                                                // be less than 65535
                                                mnPriority + 
                                                rTreeNode.getStartIndex()/double(SAL_MAX_INT16) ));

                bNewlyCreated = true; // subset newly created
            }

            // always register shape at DrawShapeSubsetting, to keep
            // refcount up-to-date
            maSubsetting.addSubsetShape( o_rSubset );
                
            // flush bounds cache
            maCurrentShapeUnitBounds.reset();

            return bNewlyCreated;
        }

        bool DrawShape::revokeSubset( const AttributableShapeSharedPtr& rShape )
        {
            ENSURE_OR_THROW( (mnCurrMtfLoadFlags & MTF_LOAD_VERBOSE_COMMENTS) != 0,
                              "DrawShape::createSubset(): subset query on shape with apparently no subsets" );

            // flush bounds cache
            maCurrentShapeUnitBounds.reset();

            // forward to delegate
            if( maSubsetting.revokeSubsetShape( rShape ) )
            {
                // force redraw, our content has possibly changed (as
                // one of the subsets now display within our shape
                // again).
                mbForceUpdate = true;

                // #i47428# TEMP FIX: synchronize visibility of subset
                // with parent. 

                // TODO(F3): Remove here, and implement
                // TEXT_ONLY/BACKGROUND_ONLY with the proverbial
                // additional level of indirection: create a
                // persistent subset, containing all text/only the
                // background respectively. From _that_ object,
                // generate the temporary character subset shapes.
                const ShapeAttributeLayerSharedPtr& rAttrLayer( 
                    rShape->getTopmostAttributeLayer() );
                if( rAttrLayer &&
                    rAttrLayer->isVisibilityValid() &&
                    rAttrLayer->getVisibility() != isVisible() )
                {
                    const bool bVisibility( rAttrLayer->getVisibility() );

                    // visibilities differ - adjust ours, then
                    if( mpAttributeLayer )
                        mpAttributeLayer->setVisibility( bVisibility );
                    else
                        mbIsVisible = bVisibility;
                }
                
                // END TEMP FIX

                return true;
            }

            return false;
        }

        sal_Int32 DrawShape::getNumberOfTreeNodes( DocTreeNode::NodeType eNodeType ) const // throw ShapeLoadFailedException
        {
            ensureVerboseMtfComments();

            return maSubsetting.getNumberOfTreeNodes( eNodeType );
        }

        DocTreeNode DrawShape::getTreeNode( sal_Int32				nNodeIndex,
                                            DocTreeNode::NodeType	eNodeType ) const // throw ShapeLoadFailedException
        {
            ensureVerboseMtfComments();

            if ( hasHyperlinks())
            {
                prepareHyperlinkIndices();
            }

            return maSubsetting.getTreeNode( nNodeIndex, eNodeType );
        }

        sal_Int32 DrawShape::getNumberOfSubsetTreeNodes	( const DocTreeNode& 	rParentNode,
                                                          DocTreeNode::NodeType eNodeType ) const // throw ShapeLoadFailedException
        {
            ensureVerboseMtfComments();

            return maSubsetting.getNumberOfSubsetTreeNodes( rParentNode, eNodeType );
        }

        DocTreeNode DrawShape::getSubsetTreeNode( const DocTreeNode& 	rParentNode,
                                                  sal_Int32				nNodeIndex,
                                                  DocTreeNode::NodeType	eNodeType ) const // throw ShapeLoadFailedException
        {
            ensureVerboseMtfComments();

            return maSubsetting.getSubsetTreeNode( rParentNode, nNodeIndex, eNodeType );
        }
    }
}
