/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/


#include "precompiled_slideshow.hxx"

#include <canvas/debug.hxx>
#include <tools/diagnose_ex.h>
#include <canvas/canvastools.hxx>

#include "eventqueue.hxx"
#include "eventmultiplexer.hxx"
#include "slideview.hxx"
#include "delayevent.hxx"
#include "unoview.hxx"

#include <rtl/instance.hxx>
#include <cppuhelper/basemutex.hxx>
#include <cppuhelper/compbase2.hxx>
#include <cppuhelper/implementationentry.hxx>
#include <cppuhelper/interfacecontainer.h>
#include <comphelper/make_shared_from_uno.hxx>

#include <cppcanvas/spritecanvas.hxx>
#include <cppcanvas/customsprite.hxx>
#include <cppcanvas/vclfactory.hxx>
#include <cppcanvas/basegfxfactory.hxx>

#include <tools/debug.hxx>

#include <basegfx/range/b1drange.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/range/b2irange.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <basegfx/polygon/b2dpolygonclipper.hxx>
#include <basegfx/polygon/b2dpolypolygoncutter.hxx>

#include <com/sun/star/presentation/XSlideShow.hpp>

#include <boost/noncopyable.hpp>
#include <boost/bind.hpp>
#include <boost/weak_ptr.hpp>

#include <vector>
#include <iterator>
#include <algorithm>

using namespace com::sun::star;

namespace slideshow {
namespace internal {

namespace {

struct StaticUnitRectPoly : public rtl::StaticWithInit<basegfx::B2DPolygon, StaticUnitRectPoly>
{
    basegfx::B2DPolygon operator()()
    {
        return basegfx::tools::createUnitPolygon();
    }
};

/** Sprite entry, to store sprite plus priority

    The operator<() defines a strict weak ordering of sprites, sort
    key is the sprite priority.
 */
struct SpriteEntry
{
    SpriteEntry( const cppcanvas::CustomSpriteSharedPtr& rSprite,
                 double                                  nPrio ) :
        mpSprite( rSprite ),
        mnPriority( nPrio )
    {
    }

    bool operator<(const SpriteEntry& rRHS) const
    {
        return mnPriority < rRHS.mnPriority;
    }

    boost::weak_ptr< cppcanvas::CustomSprite > mpSprite;
    double                                     mnPriority;
};

typedef std::vector< SpriteEntry > SpriteVector;


/** Create a clip polygon for slide views

    @param rClip
    Clip to set (can be empty)

    @param rCanvas
    Canvas to create the clip polygon for

    @param rUserSize
    The size of the view. Note that the returned clip will
    <em>always</em> clip to at least the rect defined herein.

    @return the view clip polygon, in view coordinates, which is
    guaranteed to at least clip to the view size.
 */
basegfx::B2DPolyPolygon createClipPolygon( const basegfx::B2DPolyPolygon&    rClip,
                                           const cppcanvas::CanvasSharedPtr& /*rCanvas*/,
                                           const basegfx::B2DSize&           rUserSize )
{
    // setup canvas clipping
    // =====================

    // AW: Simplified
	const basegfx::B2DRange aClipRange(0, 0, rUserSize.getX(), rUserSize.getY());

    if(rClip.count())
    {
    	return basegfx::tools::clipPolyPolygonOnRange(rClip, aClipRange, true, false);
    }
    else
    {
        return basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aClipRange));
    }
}

/** Prepare given clip polygon to be stored as the current clip

    Note that this is separate from createClipPolygon(), to allow
    SlideView implementations to store this intermediate result
    (createClipPolygon() has to be called every time the view size
    changes)
 */
basegfx::B2DPolyPolygon prepareClip( const basegfx::B2DPolyPolygon& rClip ) 
{
    basegfx::B2DPolyPolygon aClip( rClip );

    // TODO(P2): unnecessary, once XCanvas is correctly handling this
    // AW: Should be no longer necessary; tools are now bezier-safe
    if( aClip.areControlPointsUsed() )
        aClip = basegfx::tools::adaptiveSubdivideByAngle( aClip );
    
    // normalize polygon, preparation for clipping
    // in updateCanvas()
    aClip = basegfx::tools::correctOrientations(aClip);
    aClip = basegfx::tools::solveCrossovers(aClip);
    aClip = basegfx::tools::stripNeutralPolygons(aClip);
    aClip = basegfx::tools::stripDispensablePolygons(aClip, false);
    
    return aClip;
}


void clearRect( ::cppcanvas::CanvasSharedPtr const& pCanvas,
                basegfx::B2IRange const&            rArea )
{
    // convert clip polygon to device coordinate system
    ::basegfx::B2DPolyPolygon const* pClipPoly( pCanvas->getClip() );
    if( pClipPoly )
    {
        ::basegfx::B2DPolyPolygon aClipPoly( *pClipPoly );
        aClipPoly.transform( pCanvas->getTransformation() );
        pCanvas->setClip( aClipPoly );
    }

    // set transformation to identitiy (->device pixel)
    pCanvas->setTransformation( ::basegfx::B2DHomMatrix() );

    // #i42440# Fill the _full_ background in
    // black. Since we had to extend the bitmap by one
    // pixel, and the bitmap is initialized white,
    // depending on the slide content a one pixel wide
    // line will show to the bottom and the right.
    const ::basegfx::B2DPolygon aPoly(
        ::basegfx::tools::createPolygonFromRect(
            basegfx::B2DRange(rArea)));

    ::cppcanvas::PolyPolygonSharedPtr pPolyPoly( 
        ::cppcanvas::BaseGfxFactory::getInstance().createPolyPolygon( pCanvas, 
                                                                      aPoly ) );

    if( pPolyPoly )
    {
        pPolyPoly->setCompositeOp( cppcanvas::CanvasGraphic::SOURCE );
        pPolyPoly->setRGBAFillColor( 0x00000000U );
        pPolyPoly->draw();
    }

#if defined(VERBOSE) && defined(DBG_UTIL)
    ::cppcanvas::CanvasSharedPtr pCliplessCanvas( pCanvas->clone() );
    pCliplessCanvas->setClip();

    if( pCanvas->getClip() )
    {
        ::cppcanvas::PolyPolygonSharedPtr pPolyPoly2(
            ::cppcanvas::BaseGfxFactory::getInstance().createPolyPolygon( pCliplessCanvas, 
                                                                          *(pCanvas->getClip()) ));
        if( pPolyPoly2 )
        {
            pPolyPoly2->setRGBALineColor( 0x008000FFU );
            pPolyPoly2->draw();
        }
    }
#endif
}

/** Get bounds in pixel

    @param rLayerBounds
    Bound rect, in user space coordinates

    @param rTransformation
    User space to device pixel transformation

    @return the layer bounds in pixel, extended by one pixel to the
    right and bottom
 */
basegfx::B2IRange getLayerBoundsPixel( basegfx::B2DRange const&     rLayerBounds,
                                       basegfx::B2DHomMatrix const& rTransformation )
{
    ::basegfx::B2DRange aTmpRect;
    ::canvas::tools::calcTransformedRectBounds( aTmpRect, 
                                                rLayerBounds, 
                                                rTransformation );

    if( aTmpRect.isEmpty() )
        return ::basegfx::B2IRange();

    // #i42440# Returned layer size is one pixel too small, as  
    // rendering happens one pixel to the right and below the   
    // actual bound rect.   
    return ::basegfx::B2IRange( ::basegfx::fround(aTmpRect.getMinX()),
                                ::basegfx::fround(aTmpRect.getMinY()),
                                ::basegfx::fround(aTmpRect.getMaxX()) + 1,
                                ::basegfx::fround(aTmpRect.getMaxY()) + 1 );
}


// ----------------------------------------------------------------

/** Container class for sprites issued by a ViewLayer

    This class handles the sprite prioritization issues, that are
    needed for layer sprites (e.g. the need to re-prioritize sprites
    when the layer changes prio).
 */
class LayerSpriteContainer
{
    /** Max fill level of maSprites, before we try to prune it from
        deceased sprites
    */
    enum{ SPRITE_ULLAGE=256 };

    /** All sprites that have been issued by this container (pruned
        from time to time, for invalid references). This vector is
        kept sorted with increasing sprite priority.
    */
    SpriteVector       maSprites;

    /// Priority of this layer, relative to other view layers
    basegfx::B1DRange  maLayerPrioRange;

    double getSpritePriority( std::size_t nSpriteNum ) const
    {
        // divide the available layer range equally between all
        // sprites, assign upper bound of individual sprite range as
        // sprite prio (the layer itself gets assigned the lower bound
        // of sprite 0's individual range):
        //
        // | layer 0                    | layer 1                    | ...
        // |    sprite 0 |    sprite 1  |    sprite 0 |    sprite 1  | ...
        return maLayerPrioRange.getMinimum() + maLayerPrioRange.getRange()*(nSpriteNum+1)/(maSprites.size()+1);
    }

    /** Rescan sprite vector, and remove deceased sprites (and reset
        sprite prio)

        @param aBegin
        Iterator to the first entry to rescan
     */
    void updateSprites()
    {
        SpriteVector aValidSprites;

        // check all sprites for validity and set new priority
        SpriteVector::iterator       aCurrSprite( maSprites.begin() );
        const SpriteVector::iterator aEnd( maSprites.end() );
        while( aCurrSprite != aEnd )
        {
            cppcanvas::CustomSpriteSharedPtr pCurrSprite( aCurrSprite->mpSprite.lock() );
            
            if( pCurrSprite )
            {
                // only copy still valid sprites over to the refreshed
                // sprite vector.
                aValidSprites.push_back( *aCurrSprite );

                pCurrSprite->setPriority( 
                    getSpritePriority( aValidSprites.size()-1 ));
            }

            ++aCurrSprite;
        }

        // replace sprite list with pruned one
        maSprites.swap( aValidSprites );
    }

public:
    LayerSpriteContainer() :
        maSprites(),
        maLayerPrioRange()
    {
    }

    basegfx::B1DRange getLayerPriority() const
    {
        return maLayerPrioRange;
    }

    void setLayerPriority( const basegfx::B1DRange& rRange )
    {
        if( rRange != maLayerPrioRange )
        {
            maLayerPrioRange = rRange;

            // prune and recalc sprite prios
            updateSprites();
        }
    }

    void addSprite( const cppcanvas::CustomSpriteSharedPtr& pSprite,
                    double                                  nPriority )
    {
        if( !pSprite )
            return;

        SpriteEntry aEntry( pSprite,nPriority );

        // insert new sprite, such that vector stays sorted
        SpriteVector::iterator aInsertPos(
            maSprites.insert(
                std::lower_bound( maSprites.begin(),
                                  maSprites.end(),
                                  aEntry ),
                aEntry ));

        const std::size_t nNumSprites( maSprites.size() );
        if( nNumSprites > SPRITE_ULLAGE ||
            maSprites.end() - aInsertPos > 1 )
        {
            // updateSprites() also updates all sprite prios
            updateSprites();
        }
        else
        {
            // added sprite to the end, and not too many sprites in
            // vector - perform optimized update (only need to set
            // prio). This basically caters for the common case of
            // iterated character animations, which generate lots of
            // sprites, all added to the end.
            pSprite->setPriority( 
                getSpritePriority( nNumSprites-1 ));
        }
    }

    void clear()
    {
        maSprites.clear();
    }
};


// ----------------------------------------------------------------


/** This class provides layers for a slide view

    Layers are used to render animations with the correct z order -
    because sprites are always in front of the static canvas
    background, shapes that must appear <em<before</em> an animation
    must also be displayed as a sprite.

    Each layer has a priority assigned to it (valid range [0,1]), which
    also affects all sprites created for this specific layer - i.e. if
    the layer priority changes, the sprites change z order together
    with their parent.
 */
class SlideViewLayer : public ViewLayer, 
                       private boost::noncopyable
{
    /// Smart container for all sprites issued by this layer
    mutable LayerSpriteContainer             maSpriteContainer;

    /// Bounds of this layer in user space coordinates
    basegfx::B2DRange                        maLayerBounds;

    /// Bounds of this layer in device pixel
    mutable basegfx::B2IRange                maLayerBoundsPixel;

    /// Current clip polygon in user coordinates
    basegfx::B2DPolyPolygon                  maClip;
    
    /// Current size of the view in user coordinates
    basegfx::B2DSize                         maUserSize;

    /// Current overall view transformation
    basegfx::B2DHomMatrix                    maTransformation;

    /// 'parent' canvas, this viewlayer is associated with
    const cppcanvas::SpriteCanvasSharedPtr   mpSpriteCanvas;

    /** output surface (necessarily a sprite, won't otherwise be able
        to display anything <em>before</em> other sprites)
    */
    mutable cppcanvas::CustomSpriteSharedPtr mpSprite;

    /// actual output canvas retrieved from a sprite
    mutable cppcanvas::CanvasSharedPtr       mpOutputCanvas;
    
    /// ptr back to owning view. needed for isOnView() method
    View const* const                        mpParentView;

public:
    /** Create a new layer

        @param pCanvas
        Sprite canvas to create the layer on

        @param rTransform
        Initial overall canvas transformation

        @param rLayerBounds
        Initial layer bounds, in view coordinate system
     */
    SlideViewLayer( const cppcanvas::SpriteCanvasSharedPtr& pCanvas,
                    const basegfx::B2DHomMatrix&            rTransform,
                    const basegfx::B2DRange&                rLayerBounds,
                    const basegfx::B2DSize&                 rUserSize,
                    View const* const                       pParentView) :
        maSpriteContainer(),
        maLayerBounds(rLayerBounds),
        maLayerBoundsPixel(),
        maClip(),
        maUserSize(rUserSize),
        maTransformation(rTransform),
        mpSpriteCanvas(pCanvas),
        mpSprite(),
        mpOutputCanvas(),
        mpParentView(pParentView)
    {        
    }

    void updateView( const basegfx::B2DHomMatrix& rMatrix,
                     const basegfx::B2DSize&      rUserSize )
    {
        maTransformation = rMatrix;
        maUserSize = rUserSize;

        // limit layer bounds to visible screen
        maLayerBounds.intersect( basegfx::B2DRange(0.0,
                                                   0.0,
                                                   maUserSize.getX(),
                                                   maUserSize.getY()) );

        basegfx::B2IRange const& rNewLayerPixel(
            getLayerBoundsPixel(maLayerBounds,
                                maTransformation) );
        if( rNewLayerPixel != maLayerBoundsPixel )
        {
            // re-gen sprite with new size
            mpOutputCanvas.reset();
            mpSprite.reset();
        }
    }

private:
    // ViewLayer interface
    // ----------------------------------------------

    virtual cppcanvas::CustomSpriteSharedPtr createSprite(
        const ::basegfx::B2DSize& rSpriteSizePixel,
        double                    nPriority ) const
    {
        cppcanvas::CustomSpriteSharedPtr pSprite(
            mpSpriteCanvas->createCustomSprite( rSpriteSizePixel ) );

        maSpriteContainer.addSprite( pSprite,
                                     nPriority );

        return pSprite;
    }

    virtual void setPriority( const basegfx::B1DRange& rRange )
    {
        OSL_ENSURE( !rRange.isEmpty() &&
                    rRange.getMinimum() >= 1.0,
                    "SlideViewLayer::setPriority(): prio MUST be larger than 1.0 (because "
                    "the background layer already lies there)" );

        maSpriteContainer.setLayerPriority( rRange );

        if( mpSprite )
            mpSprite->setPriority( rRange.getMinimum() );
    }

    virtual basegfx::B2DHomMatrix getTransformation() const
    {
        // Offset given transformation by left, top border of given
        // range (after transformation through given transformation)
        basegfx::B2DRectangle aTmpRect;
        canvas::tools::calcTransformedRectBounds( aTmpRect, 
                                                  maLayerBounds, 
                                                  maTransformation );

        basegfx::B2DHomMatrix aMatrix( maTransformation );

        // Add translation according to the origin of aTmpRect.  Ignore the
        // translation when aTmpRect was not properly initialized.
        if ( ! aTmpRect.isEmpty())
        {
            aMatrix.translate( -basegfx::fround(aTmpRect.getMinX()),
                               -basegfx::fround(aTmpRect.getMinY()) );
        }

        return aMatrix;
    }

    virtual basegfx::B2DHomMatrix getSpriteTransformation() const
    {
        return maTransformation;
    }

    virtual void clear() const
    {
        // keep layer clip
        clearRect(getCanvas()->clone(),
                  maLayerBoundsPixel);
    }

    virtual void clearAll() const
    {
        ::cppcanvas::CanvasSharedPtr pCanvas( getCanvas()->clone() );

        // clear layer clip, to clear whole area
        pCanvas->setClip();

        clearRect(pCanvas,
                  maLayerBoundsPixel);
    }

    virtual bool isOnView(boost::shared_ptr<View> const& rView) const
    {
        return rView.get() == mpParentView;
    }

    virtual cppcanvas::CanvasSharedPtr getCanvas() const
    {
        if( !mpOutputCanvas )
        {
            if( !mpSprite )
            {
                maLayerBoundsPixel = getLayerBoundsPixel(maLayerBounds,
                                                         maTransformation);

                // HACK: ensure at least 1x1 pixel size. clients might
                // need an actual canvas (e.g. for bound rect
                // calculations) without rendering anything. Better
                // solution: introduce something like a reference
                // canvas for ViewLayers, which is always available.
                if( maLayerBoundsPixel.isEmpty() )
                    maLayerBoundsPixel = basegfx::B2IRange(0,0,1,1);

                const basegfx::B2I64Tuple& rSpriteSize(maLayerBoundsPixel.getRange());
                mpSprite = mpSpriteCanvas->createCustomSprite(
                    basegfx::B2DVector(sal::static_int_cast<sal_Int32>(rSpriteSize.getX()),
                                       sal::static_int_cast<sal_Int32>(rSpriteSize.getY())) );

                mpSprite->setPriority( 
                    maSpriteContainer.getLayerPriority().getMinimum() );

#if defined(VERBOSE) && defined(DBG_UTIL)
                mpSprite->movePixel( 
                    basegfx::B2DPoint(maLayerBoundsPixel.getMinimum()) + 
                    basegfx::B2DPoint(10,10) );

                mpSprite->setAlpha(0.5); 
#else
                mpSprite->movePixel( 
                    basegfx::B2DPoint(maLayerBoundsPixel.getMinimum()) );

                mpSprite->setAlpha(1.0); 
#endif
                mpSprite->show(); 
            }

            ENSURE_OR_THROW( mpSprite,
                              "SlideViewLayer::getCanvas(): no layer sprite" );

            mpOutputCanvas = mpSprite->getContentCanvas();
            
            ENSURE_OR_THROW( mpOutputCanvas,
                              "SlideViewLayer::getCanvas(): sprite doesn't yield a canvas" );

            // new canvas retrieved - setup transformation and clip
            mpOutputCanvas->setTransformation( getTransformation() );
            mpOutputCanvas->setClip( 
                createClipPolygon( maClip,
                                   mpOutputCanvas,
                                   maUserSize ));
        }
        
        return mpOutputCanvas;
    }

    virtual void setClip( const basegfx::B2DPolyPolygon& rClip )
    {
        basegfx::B2DPolyPolygon aNewClip = prepareClip( rClip );

        if( aNewClip != maClip )
        {
            maClip = aNewClip;

            if(mpOutputCanvas )
                mpOutputCanvas->setClip( 
                    createClipPolygon( maClip,
                                       mpOutputCanvas,
                                       maUserSize ));
        }
    }

    virtual bool resize( const ::basegfx::B2DRange& rArea )
    {
        const bool bRet( maLayerBounds != rArea );
        maLayerBounds = rArea;
        updateView( maTransformation,
                    maUserSize );

        return bRet;
    }
};


// ---------------------------------------------------------

typedef cppu::WeakComponentImplHelper2<
    ::com::sun::star::util::XModifyListener, 
      ::com::sun::star::awt::XPaintListener> SlideViewBase;

/** SlideView class

    This class implements the View interface, encapsulating
    <em>one</em> view a slideshow is displayed on.
 */
class SlideView : private cppu::BaseMutex,
                  public SlideViewBase,
                  public UnoView
{
public:
    SlideView( const uno::Reference<presentation::XSlideShowView>& xView,
               EventQueue&                                         rEventQueue,
               EventMultiplexer&                                   rEventMultiplexer );
    void updateCanvas();

private:
    // View:
    virtual ViewLayerSharedPtr createViewLayer( const basegfx::B2DRange& rLayerBounds ) const;
    virtual bool updateScreen() const;
    virtual bool paintScreen() const;
    virtual void setViewSize( const ::basegfx::B2DSize& );
    virtual void setCursorShape( sal_Int16 nPointerShape );

    // ViewLayer interface
    virtual bool isOnView(boost::shared_ptr<View> const& rView) const;
    virtual void clear() const;
    virtual void clearAll() const;
    virtual cppcanvas::CanvasSharedPtr getCanvas() const;
    virtual cppcanvas::CustomSpriteSharedPtr createSprite( const ::basegfx::B2DSize& rSpriteSizePixel,
                                                           double                    nPriority ) const;
    virtual void setPriority( const basegfx::B1DRange& rRange );
    virtual ::basegfx::B2DHomMatrix getTransformation() const;
    virtual basegfx::B2DHomMatrix getSpriteTransformation() const;
    virtual void setClip( const ::basegfx::B2DPolyPolygon& rClip );
    virtual bool resize( const ::basegfx::B2DRange& rArea );

    // UnoView:
    virtual void _dispose();
    virtual uno::Reference<presentation::XSlideShowView> getUnoView()const;
    virtual void setIsSoundEnabled (const bool bValue);
    virtual bool isSoundEnabled (void) const;

    // XEventListener:
    virtual void SAL_CALL disposing( lang::EventObject const& evt )
        throw (uno::RuntimeException);
    // XModifyListener:
    virtual void SAL_CALL modified( const lang::EventObject& aEvent )
        throw (uno::RuntimeException);
    // XPaintListener:
    virtual void SAL_CALL windowPaint( const awt::PaintEvent& e )
        throw (uno::RuntimeException);

    // WeakComponentImplHelperBase:
    virtual void SAL_CALL disposing();

    void updateClip();

private:    
    typedef std::vector< boost::weak_ptr<SlideViewLayer> > ViewLayerVector;

    /// Prune viewlayers from deceased ones, optionally update them
    void pruneLayers( bool bWithViewLayerUpdate=false ) const;

    /** Max fill level of maViewLayers, before we try to prune it from
        deceased layers
    */
    enum{ LAYER_ULLAGE=8 };

    uno::Reference<presentation::XSlideShowView>              mxView;
    cppcanvas::SpriteCanvasSharedPtr                          mpCanvas;
    
    EventMultiplexer&                                         mrEventMultiplexer;
    EventQueue&                                               mrEventQueue;

    mutable LayerSpriteContainer                              maSprites;
    mutable ViewLayerVector                                   maViewLayers;  

    basegfx::B2DPolyPolygon                                   maClip;
    
    basegfx::B2DHomMatrix                                     maViewTransform;
    basegfx::B2DSize                                          maUserSize;
    bool mbIsSoundEnabled;
};


SlideView::SlideView( const uno::Reference<presentation::XSlideShowView>& xView,
                      EventQueue&                                         rEventQueue,
                      EventMultiplexer&                                   rEventMultiplexer ) :
    SlideViewBase( m_aMutex ),
    mxView( xView ),
    mpCanvas(),
    mrEventMultiplexer( rEventMultiplexer ),
    mrEventQueue( rEventQueue ),
    maSprites(),
    maViewLayers(),
    maClip(),
    maViewTransform(),
    maUserSize( 1.0, 1.0 ), // default size: one-by-one rectangle 
    mbIsSoundEnabled(true)
{
    // take care not constructing any UNO references to this _inside_
    // ctor, shift that code to createSlideView()!    
    ENSURE_OR_THROW( mxView.is(),
                      "SlideView::SlideView(): Invalid view" );
    
    mpCanvas = cppcanvas::VCLFactory::getInstance().createSpriteCanvas(
        xView->getCanvas() );
    ENSURE_OR_THROW( mpCanvas, 
                      "Could not create cppcanvas" );
    
    geometry::AffineMatrix2D aViewTransform(
        xView->getTransformation() );

    if( basegfx::fTools::equalZero(
            basegfx::B2DVector(aViewTransform.m00,
                               aViewTransform.m10).getLength()) ||
        basegfx::fTools::equalZero(
            basegfx::B2DVector(aViewTransform.m01,
                               aViewTransform.m11).getLength()) )
    {
        OSL_ENSURE( false, 
                    "SlideView::SlideView(): Singular matrix!" );

        canvas::tools::setIdentityAffineMatrix2D(aViewTransform);
    }
    
    basegfx::unotools::homMatrixFromAffineMatrix(
        maViewTransform, aViewTransform );

    // once and forever: set fixed prio to this 'layer' (we're always
    // the background layer)
    maSprites.setLayerPriority( basegfx::B1DRange(0.0,1.0) );
}

void SlideView::disposing()
{
    osl::MutexGuard aGuard( m_aMutex );

    maViewLayers.clear();
    maSprites.clear();
    mpCanvas.reset();

    // additionally, also de-register from XSlideShowView
    if (mxView.is()) 
    {
        mxView->removeTransformationChangedListener( this );
        mxView->removePaintListener( this );
        mxView.clear();
    }
}

ViewLayerSharedPtr SlideView::createViewLayer( const basegfx::B2DRange& rLayerBounds ) const
{
    osl::MutexGuard aGuard( m_aMutex );

    ENSURE_OR_THROW( mpCanvas, 
                      "SlideView::createViewLayer(): Disposed" );

    const std::size_t nNumLayers( maViewLayers.size() );

    // avoid filling up layer vector with lots of deceased layer weak
    // ptrs
    if( nNumLayers > LAYER_ULLAGE )
        pruneLayers();

    boost::shared_ptr<SlideViewLayer> pViewLayer( new SlideViewLayer(mpCanvas,
                                                                     getTransformation(),
                                                                     rLayerBounds,
                                                                     maUserSize,
                                                                     this) );
    maViewLayers.push_back( pViewLayer );

    return pViewLayer;
}

bool SlideView::updateScreen() const
{
    osl::MutexGuard aGuard( m_aMutex );

    ENSURE_OR_RETURN_FALSE( mpCanvas.get(),
                       "SlideView::updateScreen(): Disposed" );

    return mpCanvas->updateScreen( false );
}

bool SlideView::paintScreen() const
{
    osl::MutexGuard aGuard( m_aMutex );

    ENSURE_OR_RETURN_FALSE( mpCanvas.get(),
                       "SlideView::paintScreen(): Disposed" );

    return mpCanvas->updateScreen( true );
}

void SlideView::clear() const
{
    osl::MutexGuard aGuard( m_aMutex );

    OSL_ENSURE( mxView.is() && mpCanvas, 
                "SlideView::clear(): Disposed" );
    if( !mxView.is() || !mpCanvas )
        return;

    // keep layer clip
    clearRect(getCanvas()->clone(),
              getLayerBoundsPixel(
                  basegfx::B2DRange(0,0,
                                    maUserSize.getX(),
                                    maUserSize.getY()),
                  getTransformation()));
}

void SlideView::clearAll() const
{
    osl::MutexGuard aGuard( m_aMutex );

    OSL_ENSURE( mxView.is() && mpCanvas, 
                "SlideView::clear(): Disposed" );
    if( !mxView.is() || !mpCanvas )
        return;

    // clear whole view
    mxView->clear();
}

void SlideView::setViewSize( const basegfx::B2DSize& rSize )
{
    osl::MutexGuard aGuard( m_aMutex );

    maUserSize = rSize;
    updateCanvas();
}

void SlideView::setCursorShape( sal_Int16 nPointerShape )
{
    osl::MutexGuard const guard( m_aMutex );

    if (mxView.is())
        mxView->setMouseCursor( nPointerShape );
}

bool SlideView::isOnView(boost::shared_ptr<View> const& rView) const
{
    return rView.get() == this;
}

cppcanvas::CanvasSharedPtr SlideView::getCanvas() const
{
    osl::MutexGuard aGuard( m_aMutex );

    ENSURE_OR_THROW( mpCanvas, 
                      "SlideView::getCanvas(): Disposed" );

    return mpCanvas;
}

cppcanvas::CustomSpriteSharedPtr SlideView::createSprite(
    const basegfx::B2DSize& rSpriteSizePixel,
    double                  nPriority ) const          
{
    osl::MutexGuard aGuard( m_aMutex );

    ENSURE_OR_THROW( mpCanvas, "SlideView::createSprite(): Disposed" );

    cppcanvas::CustomSpriteSharedPtr pSprite(
        mpCanvas->createCustomSprite( rSpriteSizePixel ) );

    maSprites.addSprite( pSprite,
                         nPriority );

    return pSprite;
}

void SlideView::setPriority( const basegfx::B1DRange& /*rRange*/ )
{
    osl::MutexGuard aGuard( m_aMutex );

    OSL_ENSURE( false,
                "SlideView::setPriority() is a NOOP for slide view - "
                "content will always be shown in the background" );
}

basegfx::B2DHomMatrix SlideView::getTransformation() const
{
    osl::MutexGuard aGuard( m_aMutex );

    basegfx::B2DHomMatrix aMatrix;
    aMatrix.scale( 1.0/maUserSize.getX(), 1.0/maUserSize.getY() );

    return maViewTransform * aMatrix;
}

basegfx::B2DHomMatrix SlideView::getSpriteTransformation() const
{
    return getTransformation();
}

void SlideView::setClip( const basegfx::B2DPolyPolygon& rClip )
{
    osl::MutexGuard aGuard( m_aMutex );

    basegfx::B2DPolyPolygon aNewClip = prepareClip( rClip );
    
    if( aNewClip != maClip )
    {
        maClip = aNewClip;    
    
        updateClip();
    }
}

bool SlideView::resize( const ::basegfx::B2DRange& /*rArea*/ )
{
    osl::MutexGuard aGuard( m_aMutex );

    OSL_ENSURE( false,
                "SlideView::resize(): ignored for the View, can't change size "
                "effectively, anyway" );

    return false;
}

uno::Reference<presentation::XSlideShowView> SlideView::getUnoView() const
{
    osl::MutexGuard aGuard( m_aMutex );
    return mxView;
}

void SlideView::setIsSoundEnabled (const bool bValue)
{
    mbIsSoundEnabled = bValue;
}

bool SlideView::isSoundEnabled (void) const
{
    return mbIsSoundEnabled;
}

void SlideView::_dispose()
{
    dispose();
}

// XEventListener
void SlideView::disposing( lang::EventObject const& evt )
    throw (uno::RuntimeException)
{
    (void)evt;

    // no deregistration necessary anymore, XView has left:
    osl::MutexGuard const guard( m_aMutex );

    if (mxView.is()) 
    {
        OSL_ASSERT( evt.Source == mxView );
        mxView.clear();
    }

    dispose();
}

// XModifyListener
void SlideView::modified( const lang::EventObject& /*aEvent*/ )
    throw (uno::RuntimeException)
{
    osl::MutexGuard const guard( m_aMutex );

    OSL_ENSURE( mxView.is(), "SlideView::modified(): "
                "Disposed, but event received from XSlideShowView?!");

    if( !mxView.is() )
        return;
    
    geometry::AffineMatrix2D aViewTransform(
        mxView->getTransformation() );

    if( basegfx::fTools::equalZero(
            basegfx::B2DVector(aViewTransform.m00,
                               aViewTransform.m10).getLength()) ||
        basegfx::fTools::equalZero(
            basegfx::B2DVector(aViewTransform.m01,
                               aViewTransform.m11).getLength()) )
    {
        OSL_ENSURE( false, 
                    "SlideView::modified(): Singular matrix!" );

        canvas::tools::setIdentityAffineMatrix2D(aViewTransform);
    }
                
    // view transformation really changed?
    basegfx::B2DHomMatrix aNewTransform;
    basegfx::unotools::homMatrixFromAffineMatrix(
        aNewTransform,  
        aViewTransform );

    if( aNewTransform == maViewTransform )
        return; // No change, nothing to do
    
    maViewTransform = aNewTransform;

    updateCanvas();
    
    // notify view change. Don't call EventMultiplexer directly, this
    // might not be the main thread!
    mrEventQueue.addEvent(
        makeEvent( boost::bind( (bool (EventMultiplexer::*)(
                                     const uno::Reference<presentation::XSlideShowView>&))
                                &EventMultiplexer::notifyViewChanged,
                                boost::ref(mrEventMultiplexer), mxView ),
                   "EventMultiplexer::notifyViewChanged"));
}

// XPaintListener
void SlideView::windowPaint( const awt::PaintEvent& /*e*/ )
    throw (uno::RuntimeException)
{
    osl::MutexGuard aGuard( m_aMutex );

    OSL_ENSURE( mxView.is() && mpCanvas, "Disposed, but event received?!" );
    
    // notify view clobbering. Don't call EventMultiplexer directly,
    // this might not be the main thread!
    mrEventQueue.addEvent(
        makeEvent( boost::bind( &EventMultiplexer::notifyViewClobbered,
                                boost::ref(mrEventMultiplexer), mxView ),
                   "EventMultiplexer::notifyViewClobbered") );
}

void SlideView::updateCanvas()
{
    OSL_ENSURE( mpCanvas, 
                "SlideView::updateCanvasTransform(): Disposed" );

    if( !mpCanvas || !mxView.is())
        return;
    
    mpCanvas->clear(); // this is unnecessary, strictly speaking. but
                       // it makes the SlideView behave exactly like a
                       // sprite-based SlideViewLayer, because those
                       // are created from scratch after a resize
    clearAll();
    mpCanvas->setTransformation( getTransformation() );
    mpCanvas->setClip( 
        createClipPolygon( maClip,
                           mpCanvas,
                           maUserSize ));

    // forward update to viewlayers
    pruneLayers( true );
}

void SlideView::updateClip()
{
    OSL_ENSURE( mpCanvas, 
                "SlideView::updateClip(): Disposed" );

    if( !mpCanvas )
        return;
    
    mpCanvas->setClip( 
        createClipPolygon( maClip,
                           mpCanvas,
                           maUserSize ));

    pruneLayers( false );
}

void SlideView::pruneLayers( bool bWithViewLayerUpdate ) const
{
    ViewLayerVector aValidLayers;

    const basegfx::B2DHomMatrix& rCurrTransform( 
        getTransformation() );

    // check all layers for validity, and retain only the live ones
    ViewLayerVector::const_iterator       aCurr( maViewLayers.begin() );
    const ViewLayerVector::const_iterator aEnd( maViewLayers.end() );
    while( aCurr != aEnd )
    {
        boost::shared_ptr< SlideViewLayer > pCurrLayer( aCurr->lock() );
            
        if( pCurrLayer )
        {
            aValidLayers.push_back( pCurrLayer );
            
            if( bWithViewLayerUpdate )
                pCurrLayer->updateView( rCurrTransform,
                                        maUserSize );
        }

        ++aCurr;
    }

    // replace layer list with pruned one
    maViewLayers.swap( aValidLayers );
}

} // anonymous namespace

UnoViewSharedPtr createSlideView( uno::Reference< presentation::XSlideShowView> const& xView,
                                  EventQueue&                                          rEventQueue,
                                  EventMultiplexer&                                    rEventMultiplexer )
{
    boost::shared_ptr<SlideView> const that(
        comphelper::make_shared_from_UNO(
            new SlideView(xView, 
                          rEventQueue,
                          rEventMultiplexer)));

    // register listeners with XSlideShowView
    xView->addTransformationChangedListener( that.get() );
    xView->addPaintListener( that.get() );
    
    // set new transformation
    that->updateCanvas();
    
    return that;
}

} // namespace internal
} // namespace slideshow

