/**************************************************************
 * 
 * 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 <rtl/ref.hxx>
#include <cppuhelper/compbase2.hxx>
#include <cppuhelper/basemutex.hxx>

#include <com/sun/star/awt/XMouseListener.hpp>
#include <com/sun/star/awt/XMouseMotionListener.hpp>
#include <com/sun/star/awt/SystemPointer.hpp>
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/awt/MouseButton.hpp>
#include <com/sun/star/presentation/XSlideShowView.hpp>

#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/numeric/ftools.hxx>

#include "tools.hxx"
#include "eventqueue.hxx"
#include "eventmultiplexer.hxx"
#include "listenercontainer.hxx"
#include "delayevent.hxx"
#include "unoview.hxx"
#include "unoviewcontainer.hxx"

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

#include <vector>
#include <hash_map>
#include <algorithm>

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

namespace boost
{
    // add operator== for weak_ptr
    template<typename T> bool operator==( weak_ptr<T> const& rLHS,
                                          weak_ptr<T> const& rRHS )
    {
        return !(rLHS<rRHS) && !(rRHS<rLHS);
    }
}

namespace slideshow {
namespace internal {

template <typename HandlerT>
class PrioritizedHandlerEntry
{
    typedef boost::shared_ptr<HandlerT> HandlerSharedPtrT;
    HandlerSharedPtrT mpHandler;
    double            mnPrio;
    
public:
    PrioritizedHandlerEntry( HandlerSharedPtrT const& pHandler, 
                             double                   nPrio ) :
        mpHandler(pHandler), 
        mnPrio(nPrio) 
    {}
    
    HandlerSharedPtrT const& getHandler() const { return mpHandler; }
    
    /// To sort according to priority
    bool operator<( PrioritizedHandlerEntry const& rRHS ) const 
    {
        // reversed order - high prioritized entries
        // should be at the beginning of the queue
        return mnPrio > rRHS.mnPrio;
    }
    
    /// To permit std::remove in removeHandler template
    bool operator==( PrioritizedHandlerEntry const& rRHS ) const 
    {
        // ignore prio, for removal, only the handler ptr matters
        return mpHandler == rRHS.mpHandler;
    }
};

template<typename T> inline T* get_pointer(PrioritizedHandlerEntry<T> const& handler)
{
    return handler.getHandler().get();
}



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


typedef cppu::WeakComponentImplHelper2<
    awt::XMouseListener,
    awt::XMouseMotionListener > Listener_UnoBase;

/** Listener class, to decouple UNO lifetime from EventMultiplexer

    This class gets registered as the XMouse(Motion)Listener on the
    XSlideViews, and passes on the events to the EventMultiplexer (via
    EventQueue indirection, to force the events into the main thread)
 */
class EventMultiplexerListener : private cppu::BaseMutex, 
                                 public Listener_UnoBase,
                                 private ::boost::noncopyable
{
public:
    EventMultiplexerListener( EventQueue&           rEventQueue,
                              EventMultiplexerImpl& rEventMultiplexer ) : 
        Listener_UnoBase( m_aMutex ),
        mpEventQueue( &rEventQueue ),
        mpEventMultiplexer( &rEventMultiplexer )
    {
    }

    // WeakComponentImplHelperBase::disposing
    virtual void SAL_CALL disposing();
    
private:
    virtual void SAL_CALL disposing( const lang::EventObject& Source )
        throw (uno::RuntimeException);

    // XMouseListener implementation
    virtual void SAL_CALL mousePressed( const awt::MouseEvent& e )
        throw (uno::RuntimeException);
    virtual void SAL_CALL mouseReleased( const awt::MouseEvent& e )
        throw (uno::RuntimeException);
    virtual void SAL_CALL mouseEntered( const awt::MouseEvent& e )
        throw (uno::RuntimeException);
    virtual void SAL_CALL mouseExited( const awt::MouseEvent& e )
        throw (uno::RuntimeException);
    
    // XMouseMotionListener implementation
    virtual void SAL_CALL mouseDragged( const awt::MouseEvent& e )
        throw (uno::RuntimeException);
    virtual void SAL_CALL mouseMoved( const awt::MouseEvent& e )
        throw (uno::RuntimeException);
    

    EventQueue*           mpEventQueue;
    EventMultiplexerImpl* mpEventMultiplexer;
};


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


struct EventMultiplexerImpl
{
    EventMultiplexerImpl( EventQueue&             rEventQueue,
                          UnoViewContainer const& rViewContainer ) :
        mrEventQueue(rEventQueue),
        mrViewContainer(rViewContainer),
        mxListener( new EventMultiplexerListener(rEventQueue,
                                                 *this) ),
        maNextEffectHandlers(),
        maSlideStartHandlers(),
        maSlideEndHandlers(),
        maAnimationStartHandlers(),
        maAnimationEndHandlers(),
        maSlideAnimationsEndHandlers(),
        maAudioStoppedHandlers(),
        maCommandStopAudioHandlers(),
        maPauseHandlers(),
        maViewHandlers(),
        maViewRepaintHandlers(),
        maShapeListenerHandlers(),
        maUserPaintEventHandlers(),
        maShapeCursorHandlers(),
        maMouseClickHandlers(),
        maMouseDoubleClickHandlers(),
        maMouseMoveHandlers(),
        maHyperlinkHandlers(),
        mnTimeout(0.0),
        mpTickEvent(),
        mbIsAutoMode(false)
    {}

    ~EventMultiplexerImpl()
    {
        if( mxListener.is() )
            mxListener->dispose();
    }

    /// Remove all handlers
    void clear();

    // actual handler callbacks (get called from the UNO interface
    // listeners via event queue)
    void mousePressed( const awt::MouseEvent& e );
    void mouseReleased( const awt::MouseEvent& e );
    void mouseDragged( const awt::MouseEvent& e );
    void mouseMoved( const awt::MouseEvent& e );

    bool isMouseListenerRegistered() const;
    
    typedef ThreadUnsafeListenerContainer<
        PrioritizedHandlerEntry<EventHandler>,
        std::vector<
            PrioritizedHandlerEntry<EventHandler> > >     ImplNextEffectHandlers;
    typedef PrioritizedHandlerEntry<MouseEventHandler>    ImplMouseHandlerEntry;
    typedef ThreadUnsafeListenerContainer<
        ImplMouseHandlerEntry,
        std::vector<ImplMouseHandlerEntry> >              ImplMouseHandlers;
    typedef ThreadUnsafeListenerContainer<
        EventHandlerSharedPtr,
        std::vector<EventHandlerSharedPtr> >              ImplEventHandlers;
    typedef ThreadUnsafeListenerContainer<
        AnimationEventHandlerSharedPtr,
        std::vector<AnimationEventHandlerSharedPtr> >     ImplAnimationHandlers;
    typedef ThreadUnsafeListenerContainer<
        PauseEventHandlerSharedPtr,
        std::vector<PauseEventHandlerSharedPtr> >         ImplPauseHandlers;
    typedef ThreadUnsafeListenerContainer<
        ViewEventHandlerWeakPtr,
        std::vector<ViewEventHandlerWeakPtr> >            ImplViewHandlers;
    typedef ThreadUnsafeListenerContainer<
        ViewRepaintHandlerSharedPtr,
        std::vector<ViewRepaintHandlerSharedPtr> >        ImplRepaintHandlers;
    typedef ThreadUnsafeListenerContainer<
        ShapeListenerEventHandlerSharedPtr,
        std::vector<ShapeListenerEventHandlerSharedPtr> > ImplShapeListenerHandlers;
    typedef ThreadUnsafeListenerContainer<
        UserPaintEventHandlerSharedPtr,
        std::vector<UserPaintEventHandlerSharedPtr> >     ImplUserPaintEventHandlers;
    typedef ThreadUnsafeListenerContainer<
        ShapeCursorEventHandlerSharedPtr,
        std::vector<ShapeCursorEventHandlerSharedPtr> >   ImplShapeCursorHandlers;
    typedef ThreadUnsafeListenerContainer<
        PrioritizedHandlerEntry<HyperlinkHandler>,
        std::vector<PrioritizedHandlerEntry<HyperlinkHandler> > > ImplHyperLinkHandlers;
    
    template <typename XSlideShowViewFunc>
    void forEachView( XSlideShowViewFunc pViewMethod );
    
    UnoViewSharedPtr findUnoView(const uno::Reference<
                                   presentation::XSlideShowView>& xView) const;

    template< typename RegisterFunction > 
    void addMouseHandler( ImplMouseHandlers&                rHandlerContainer,
                          const MouseEventHandlerSharedPtr& rHandler,
                          double                            nPriority,
                          RegisterFunction                  pRegisterListener );

    bool notifyAllAnimationHandlers( ImplAnimationHandlers const& rContainer,
                                     AnimationNodeSharedPtr const& rNode );
    
    bool notifyMouseHandlers(
        const ImplMouseHandlers& rQueue,
        bool (MouseEventHandler::*pHandlerMethod)(
            const awt::MouseEvent& ),
        const awt::MouseEvent& e );
    
    bool notifyNextEffect();
    
    /// Called for automatic nextEffect 
    void tick();
    
    /// Schedules a tick event
    void scheduleTick();
    
    /// Schedules tick events, if mbIsAutoMode is true
    void handleTicks();

    
    EventQueue&                         mrEventQueue;
    UnoViewContainer const&             mrViewContainer;
    ::rtl::Reference<
        EventMultiplexerListener>       mxListener;
    
    ImplNextEffectHandlers              maNextEffectHandlers;
    ImplEventHandlers                   maSlideStartHandlers;
    ImplEventHandlers                   maSlideEndHandlers;
    ImplAnimationHandlers               maAnimationStartHandlers;
    ImplAnimationHandlers               maAnimationEndHandlers;
    ImplEventHandlers                   maSlideAnimationsEndHandlers;
    ImplAnimationHandlers               maAudioStoppedHandlers;
    ImplAnimationHandlers               maCommandStopAudioHandlers;
    ImplPauseHandlers                   maPauseHandlers;
    ImplViewHandlers                    maViewHandlers;
    ImplRepaintHandlers                 maViewRepaintHandlers;
    ImplShapeListenerHandlers           maShapeListenerHandlers;
    ImplUserPaintEventHandlers          maUserPaintEventHandlers;
    ImplShapeCursorHandlers             maShapeCursorHandlers;
    ImplMouseHandlers                   maMouseClickHandlers;
    ImplMouseHandlers                   maMouseDoubleClickHandlers;
    ImplMouseHandlers                   maMouseMoveHandlers;
    ImplHyperLinkHandlers               maHyperlinkHandlers;

    /// automatic next effect mode timeout
    double                        mnTimeout;
    
    /** Holds ptr to optional tick event weakly
        
        When event queue is cleansed, the next
        setAutomaticMode(true) call is then able to
        regenerate the event.
    */
    ::boost::weak_ptr< Event >    mpTickEvent;
    bool                          mbIsAutoMode;
};


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


void SAL_CALL EventMultiplexerListener::disposing()
{
    osl::MutexGuard const guard( m_aMutex );
    mpEventQueue = NULL;
    mpEventMultiplexer = NULL;
}

void SAL_CALL EventMultiplexerListener::disposing(
    const lang::EventObject& /*rSource*/ ) throw (uno::RuntimeException)
{
    // there's no real point in acting on this message - after all,
    // the event sources are the XSlideShowViews, which must be
    // explicitely removed from the slideshow via
    // XSlideShow::removeView(). thus, if a XSlideShowView has
    // properly removed itself from the slideshow, it will not be
    // found here. and if it hasn't, there'll be other references at
    // other places within the slideshow, anyway...
}

void SAL_CALL EventMultiplexerListener::mousePressed(
    const awt::MouseEvent& e ) throw (uno::RuntimeException)
{
    osl::MutexGuard const guard( m_aMutex );
    
    // notify mouse press. Don't call handlers directly, this
    // might not be the main thread!
    if( mpEventQueue )
        mpEventQueue->addEvent(
            makeEvent( boost::bind( &EventMultiplexerImpl::mousePressed,
                                    mpEventMultiplexer, 
                                    e ),
                       "EventMultiplexerImpl::mousePressed") );
}

void SAL_CALL EventMultiplexerListener::mouseReleased(
    const awt::MouseEvent& e ) throw (uno::RuntimeException)
{
    osl::MutexGuard const guard( m_aMutex );

    // notify mouse release. Don't call handlers directly,
    // this might not be the main thread!
    if( mpEventQueue )
        mpEventQueue->addEvent(
            makeEvent( boost::bind( &EventMultiplexerImpl::mouseReleased,
                                    mpEventMultiplexer, 
                                    e ),
                       "EventMultiplexerImpl::mouseReleased") );
}

void SAL_CALL EventMultiplexerListener::mouseEntered(
    const awt::MouseEvent& /*e*/ ) throw (uno::RuntimeException)
{
    // not used here
}

void SAL_CALL EventMultiplexerListener::mouseExited(
    const awt::MouseEvent& /*e*/ ) throw (uno::RuntimeException)
{
    // not used here
}

// XMouseMotionListener implementation
void SAL_CALL EventMultiplexerListener::mouseDragged(
    const awt::MouseEvent& e ) throw (uno::RuntimeException)
{
    osl::MutexGuard const guard( m_aMutex );
    
    // notify mouse drag. Don't call handlers directly, this
    // might not be the main thread!
    if( mpEventQueue )
        mpEventQueue->addEvent(
            makeEvent( boost::bind( &EventMultiplexerImpl::mouseDragged,
                                    mpEventMultiplexer, 
                                    e ),
                       "EventMultiplexerImpl::mouseDragged") );
}

void SAL_CALL EventMultiplexerListener::mouseMoved(
    const awt::MouseEvent& e ) throw (uno::RuntimeException)
{
    osl::MutexGuard const guard( m_aMutex );

    // notify mouse move. Don't call handlers directly, this
    // might not be the main thread!
    if( mpEventQueue )
        mpEventQueue->addEvent(
            makeEvent( boost::bind( &EventMultiplexerImpl::mouseMoved,
                                    mpEventMultiplexer, 
                                    e ),
                       "EventMultiplexerImpl::mouseMoved") );
}


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


bool EventMultiplexerImpl::notifyAllAnimationHandlers( ImplAnimationHandlers const& rContainer,
                                                       AnimationNodeSharedPtr const& rNode ) 
{
    return rContainer.applyAll(
        boost::bind( &AnimationEventHandler::handleAnimationEvent,
                     _1, boost::cref(rNode) ) );
}

template <typename XSlideShowViewFunc>
void EventMultiplexerImpl::forEachView( XSlideShowViewFunc pViewMethod )
{
    if( pViewMethod )
    {
        // (un)register mouse listener on all views
        for( UnoViewVector::const_iterator aIter( mrViewContainer.begin() ),
                 aEnd( mrViewContainer.end() ); aIter != aEnd; ++aIter ) 
        {
            uno::Reference<presentation::XSlideShowView> xView ((*aIter)->getUnoView());
            if (xView.is())
            {
                (xView.get()->*pViewMethod)( mxListener.get() );
            }
            else
            {
                OSL_ASSERT(xView.is());
            }
        }
    }
}

UnoViewSharedPtr EventMultiplexerImpl::findUnoView(
    const uno::Reference<presentation::XSlideShowView>& xView) const
{
    // find view from which the change originated
    UnoViewVector::const_iterator       aIter;
    const UnoViewVector::const_iterator aEnd ( mrViewContainer.end() );
    if( (aIter=std::find_if( mrViewContainer.begin(),
                             aEnd,
                             boost::bind( 
                                 std::equal_to<uno::Reference<presentation::XSlideShowView> >(),
                                 boost::cref( xView ),
                                 boost::bind( &UnoView::getUnoView, _1 )))) == aEnd )
    {
        OSL_ENSURE(false, "EventMultiplexer::findUnoView(): unexpected message source" );
        return UnoViewSharedPtr();
    }

    return *aIter;
}

template< typename RegisterFunction > 
void EventMultiplexerImpl::addMouseHandler(
    ImplMouseHandlers&                rHandlerContainer,
    const MouseEventHandlerSharedPtr& rHandler,
    double                            nPriority,
    RegisterFunction                  pRegisterListener )
{
    ENSURE_OR_THROW(
        rHandler,
        "EventMultiplexer::addMouseHandler(): Invalid handler" );
    
    // register mouse listener on all views
    forEachView( pRegisterListener );
    
    // add into sorted container:
    rHandlerContainer.addSorted( 
        typename ImplMouseHandlers::container_type::value_type( 
            rHandler,
            nPriority ));
}

bool EventMultiplexerImpl::isMouseListenerRegistered() const
{
    return !(maMouseClickHandlers.isEmpty() &&
             maMouseDoubleClickHandlers.isEmpty());
}

void EventMultiplexerImpl::tick()
{
    if( !mbIsAutoMode )
        return; // this event is just a left-over, ignore
    
    notifyNextEffect();
    
    if( !maNextEffectHandlers.isEmpty() )
    {
        // still handlers left, schedule next timeout
        // event. Will also set mbIsTickEventOn back to true
        scheduleTick();
    }
}

void EventMultiplexerImpl::scheduleTick()
{
    EventSharedPtr pEvent(
        makeDelay( boost::bind( &EventMultiplexerImpl::tick, 
                                this ),
                   mnTimeout,
                   "EventMultiplexerImpl::tick with delay"));

    // store weak reference to generated event, to notice when
    // the event queue gets cleansed (we then have to
    // regenerate the tick event!)
    mpTickEvent = pEvent;

    // enabled auto mode: simply schedule a timeout event,
    // which will eventually call our tick() method
    mrEventQueue.addEventForNextRound( pEvent );
}
                
void EventMultiplexerImpl::handleTicks()
{
    if( !mbIsAutoMode )
        return; // nothing to do, don't need no ticks

    EventSharedPtr pTickEvent( mpTickEvent.lock() );
    if( pTickEvent )
        return; // nothing to do, there's already a tick
                // pending

    // schedule initial tick (which reschedules itself 
    // after that, all by itself)
    scheduleTick();
}


void EventMultiplexerImpl::clear()
{
    // deregister from all views.
    if( isMouseListenerRegistered() )
    {
        for( UnoViewVector::const_iterator aIter=mrViewContainer.begin(), 
                 aEnd=mrViewContainer.end();
             aIter!=aEnd;
             ++aIter )
        {
			if( (*aIter)->getUnoView().is() )
				(*aIter)->getUnoView()->removeMouseListener( mxListener.get() );
        }
    }

    if( !maMouseMoveHandlers.isEmpty() )
    {
        for( UnoViewVector::const_iterator aIter=mrViewContainer.begin(), 
                 aEnd=mrViewContainer.end();
             aIter!=aEnd;
             ++aIter )
        {
			if( (*aIter)->getUnoView().is() )
	            (*aIter)->getUnoView()->removeMouseMotionListener( mxListener.get() );
        }
    }

    // clear all handlers (releases all references)
    maNextEffectHandlers.clear();
    maSlideStartHandlers.clear();
    maSlideEndHandlers.clear();
    maAnimationStartHandlers.clear();
    maAnimationEndHandlers.clear();
    maSlideAnimationsEndHandlers.clear();
    maAudioStoppedHandlers.clear();
    maCommandStopAudioHandlers.clear();
    maPauseHandlers.clear();
    maViewHandlers.clear();
    maViewRepaintHandlers.clear();
    maMouseClickHandlers.clear();
    maMouseDoubleClickHandlers.clear();
    maMouseMoveHandlers.clear();
    maHyperlinkHandlers.clear();
    mpTickEvent.reset();
}

// XMouseListener implementation
bool EventMultiplexerImpl::notifyMouseHandlers(
    const ImplMouseHandlers& rQueue,
    bool (MouseEventHandler::*pHandlerMethod)( const awt::MouseEvent& ),
    const awt::MouseEvent& e )
{
    uno::Reference<presentation::XSlideShowView> xView(
        e.Source, uno::UNO_QUERY );
    
    ENSURE_OR_RETURN_FALSE( xView.is(), "EventMultiplexer::notifyHandlers(): "
                       "event source is not an XSlideShowView" );

    // find corresponding view (to map mouse position into user
    // coordinate space)
    UnoViewVector::const_iterator       aIter;
    const UnoViewVector::const_iterator aBegin( mrViewContainer.begin() );
    const UnoViewVector::const_iterator aEnd  ( mrViewContainer.end() );
    if( (aIter=::std::find_if(
             aBegin, aEnd, 
             boost::bind( std::equal_to< uno::Reference<
                          presentation::XSlideShowView > >(),
                          boost::cref( xView ),
                          boost::bind( &UnoView::getUnoView, _1 ) ) ) ) == aEnd)
    {
        ENSURE_OR_RETURN_FALSE(
            false, "EventMultiplexer::notifyHandlers(): "
            "event source not found under registered views" );
    }

    // convert mouse position to user coordinate space
    ::basegfx::B2DPoint     aPosition( e.X, e.Y );
    ::basegfx::B2DHomMatrix aMatrix( (*aIter)->getTransformation() );
    if( !aMatrix.invert() )
        ENSURE_OR_THROW( false, "EventMultiplexer::notifyHandlers():"
                          " view matrix singular" );
    aPosition *= aMatrix;

    awt::MouseEvent aEvent( e );
    aEvent.X = ::basegfx::fround( aPosition.getX() );
    aEvent.Y = ::basegfx::fround( aPosition.getY() );

    // fire event on handlers, try in order of precedence. If
    // one high-priority handler rejects the event
    // (i.e. returns false), try next handler.
    return rQueue.apply(
        boost::bind(
            pHandlerMethod,
            boost::bind( 
                &ImplMouseHandlers::container_type::value_type::getHandler, 
                _1 ),
            aEvent ));
}

void EventMultiplexerImpl::mousePressed( const awt::MouseEvent& e )
{
    // fire double-click events for every second click
    sal_Int32 nCurrClickCount = e.ClickCount;
    while( nCurrClickCount > 1 &&
           notifyMouseHandlers( maMouseDoubleClickHandlers,
                                &MouseEventHandler::handleMousePressed,
                                e ))
    {
        nCurrClickCount -= 2;
    }

    // fire single-click events for all remaining clicks
    while( nCurrClickCount > 0 && 
           notifyMouseHandlers( maMouseClickHandlers,
                                &MouseEventHandler::handleMousePressed,
                                e ))
    {
        --nCurrClickCount;
    }
}

void EventMultiplexerImpl::mouseReleased( const awt::MouseEvent& e )
{
    // fire double-click events for every second click
    sal_Int32 nCurrClickCount = e.ClickCount;
    while( nCurrClickCount > 1 &&
           notifyMouseHandlers( maMouseDoubleClickHandlers,
                                &MouseEventHandler::handleMouseReleased,
                                e ))
    {
        nCurrClickCount -= 2;
    }

    // fire single-click events for all remaining clicks
    while( nCurrClickCount > 0 && 
           notifyMouseHandlers( maMouseClickHandlers,
                                &MouseEventHandler::handleMouseReleased,
                                e ))
    {
        --nCurrClickCount;
    }
}

void EventMultiplexerImpl::mouseDragged( const awt::MouseEvent& e )
{
    notifyMouseHandlers( maMouseMoveHandlers, 
                         &MouseEventHandler::handleMouseDragged, 
                         e );
}

void EventMultiplexerImpl::mouseMoved( const awt::MouseEvent& e )
{
    notifyMouseHandlers( maMouseMoveHandlers,
                         &MouseEventHandler::handleMouseMoved, 
                         e );
}

bool EventMultiplexerImpl::notifyNextEffect()
{
    // fire event on handlers, try in order of precedence. If one
    // high-priority handler rejects the event (i.e. returns false),
    // try next handler.
    return maNextEffectHandlers.apply(
        boost::bind(
            &EventHandler::handleEvent,
            boost::bind( 
                &ImplNextEffectHandlers::container_type::value_type::getHandler,
                _1 )) );
}

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


EventMultiplexer::EventMultiplexer( EventQueue&             rEventQueue,
                                    UnoViewContainer const& rViewContainer ) :
    mpImpl( new EventMultiplexerImpl(rEventQueue, rViewContainer) )
{
}

EventMultiplexer::~EventMultiplexer()
{
    // outline because of EventMultiplexerImpl's incomplete type
}

void EventMultiplexer::clear()
{
    mpImpl->clear();
}

void EventMultiplexer::setAutomaticMode( bool bIsAuto )
{
    if( bIsAuto == mpImpl->mbIsAutoMode )
        return; // no change, nothing to do

    mpImpl->mbIsAutoMode = bIsAuto;

    mpImpl->handleTicks();
}

bool EventMultiplexer::getAutomaticMode() const
{
    return mpImpl->mbIsAutoMode;
}

void EventMultiplexer::setAutomaticTimeout( double nTimeout )
{
    mpImpl->mnTimeout = nTimeout;
}

double EventMultiplexer::getAutomaticTimeout() const
{
    return mpImpl->mnTimeout;
}

void EventMultiplexer::addNextEffectHandler(
    EventHandlerSharedPtr const& rHandler,
    double                       nPriority )
{
    mpImpl->maNextEffectHandlers.addSorted(
        EventMultiplexerImpl::ImplNextEffectHandlers::container_type::value_type(
            rHandler,
            nPriority) );

    // Enable tick events, if not done already
    mpImpl->handleTicks();
}
        
void EventMultiplexer::removeNextEffectHandler(
    const EventHandlerSharedPtr& rHandler )
{
    mpImpl->maNextEffectHandlers.remove(
        EventMultiplexerImpl::ImplNextEffectHandlers::container_type::value_type(
            rHandler,
            0.0) );
}

void EventMultiplexer::addSlideStartHandler(
    const EventHandlerSharedPtr& rHandler )
{
    mpImpl->maSlideStartHandlers.add( rHandler );
}

void EventMultiplexer::removeSlideStartHandler(
    const EventHandlerSharedPtr& rHandler )
{
    mpImpl->maSlideStartHandlers.remove( rHandler );
}

void EventMultiplexer::addSlideEndHandler(
    const EventHandlerSharedPtr& rHandler )
{
    mpImpl->maSlideEndHandlers.add( rHandler );
}

void EventMultiplexer::removeSlideEndHandler(
    const EventHandlerSharedPtr& rHandler )
{
    mpImpl->maSlideEndHandlers.remove( rHandler );
}

void EventMultiplexer::addAnimationStartHandler(
    const AnimationEventHandlerSharedPtr& rHandler )
{
    mpImpl->maAnimationStartHandlers.add( rHandler );
}

void EventMultiplexer::removeAnimationStartHandler(
    const AnimationEventHandlerSharedPtr& rHandler )
{
    mpImpl->maAnimationStartHandlers.remove( rHandler );
}

void EventMultiplexer::addAnimationEndHandler(
    const AnimationEventHandlerSharedPtr& rHandler )
{
    mpImpl->maAnimationEndHandlers.add( rHandler );
}

void EventMultiplexer::removeAnimationEndHandler(
    const AnimationEventHandlerSharedPtr& rHandler )
{
    mpImpl->maAnimationEndHandlers.remove( rHandler );
}

void EventMultiplexer::addSlideAnimationsEndHandler(
    const EventHandlerSharedPtr& rHandler )
{
    mpImpl->maSlideAnimationsEndHandlers.add( rHandler );
}

void EventMultiplexer::removeSlideAnimationsEndHandler(
    const EventHandlerSharedPtr& rHandler )
{
    mpImpl->maSlideAnimationsEndHandlers.remove( rHandler );
}

void EventMultiplexer::addAudioStoppedHandler(
    const AnimationEventHandlerSharedPtr& rHandler )
{
    mpImpl->maAudioStoppedHandlers.add( rHandler );
}

void EventMultiplexer::removeAudioStoppedHandler(
    const AnimationEventHandlerSharedPtr& rHandler )
{
    mpImpl->maAudioStoppedHandlers.remove( rHandler );
}

void EventMultiplexer::addCommandStopAudioHandler(
    const AnimationEventHandlerSharedPtr& rHandler )
{
    mpImpl->maCommandStopAudioHandlers.add( rHandler );
}

void EventMultiplexer::removeCommandStopAudioHandler(
    const AnimationEventHandlerSharedPtr& rHandler )
{
    mpImpl->maCommandStopAudioHandlers.remove( rHandler );
}

void EventMultiplexer::addPauseHandler(
    const PauseEventHandlerSharedPtr& rHandler )
{
    mpImpl->maPauseHandlers.add( rHandler );
}

void EventMultiplexer::removePauseHandler(
    const PauseEventHandlerSharedPtr&  rHandler )
{
    mpImpl->maPauseHandlers.remove( rHandler );
}

void EventMultiplexer::addViewHandler(
    const ViewEventHandlerWeakPtr& rHandler )
{
    mpImpl->maViewHandlers.add( rHandler );
}

void EventMultiplexer::removeViewHandler( const ViewEventHandlerWeakPtr& rHandler )
{
    mpImpl->maViewHandlers.remove( rHandler );
}

void EventMultiplexer::addViewRepaintHandler( const ViewRepaintHandlerSharedPtr& rHandler )
{
    mpImpl->maViewRepaintHandlers.add( rHandler );
}

void EventMultiplexer::removeViewRepaintHandler( const ViewRepaintHandlerSharedPtr& rHandler )
{
    mpImpl->maViewRepaintHandlers.remove( rHandler );
}

void EventMultiplexer::addShapeListenerHandler( const ShapeListenerEventHandlerSharedPtr& rHandler )
{
    mpImpl->maShapeListenerHandlers.add( rHandler );
}

void EventMultiplexer::removeShapeListenerHandler( const ShapeListenerEventHandlerSharedPtr& rHandler )
{
    mpImpl->maShapeListenerHandlers.remove( rHandler );
}

void EventMultiplexer::addUserPaintHandler( const UserPaintEventHandlerSharedPtr& rHandler )
{
    mpImpl->maUserPaintEventHandlers.add( rHandler );
}

void EventMultiplexer::removeUserPaintHandler( const UserPaintEventHandlerSharedPtr& rHandler )
{
    mpImpl->maUserPaintEventHandlers.remove( rHandler );
}

void EventMultiplexer::addShapeCursorHandler( const ShapeCursorEventHandlerSharedPtr& rHandler )
{
    mpImpl->maShapeCursorHandlers.add( rHandler );
}

void EventMultiplexer::removeShapeCursorHandler( const ShapeCursorEventHandlerSharedPtr& rHandler )
{
    mpImpl->maShapeCursorHandlers.remove( rHandler );
}

void EventMultiplexer::addClickHandler(
    const MouseEventHandlerSharedPtr& rHandler,
    double                            nPriority )
{
    mpImpl->addMouseHandler(
        mpImpl->maMouseClickHandlers,
        rHandler,
        nPriority,
        mpImpl->isMouseListenerRegistered()
        ? NULL
        : &presentation::XSlideShowView::addMouseListener );
}

void EventMultiplexer::removeClickHandler(
    const MouseEventHandlerSharedPtr&  rHandler )
{
    mpImpl->maMouseClickHandlers.remove( 
        EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
            rHandler,
            0.0) );

    if( !mpImpl->isMouseListenerRegistered() )
        mpImpl->forEachView( &presentation::XSlideShowView::removeMouseListener );
}

void EventMultiplexer::addDoubleClickHandler(
    const MouseEventHandlerSharedPtr&   rHandler,
    double                              nPriority )
{
    mpImpl->addMouseHandler(
        mpImpl->maMouseDoubleClickHandlers,
        rHandler,
        nPriority,
        mpImpl->isMouseListenerRegistered()
        ? NULL
        : &presentation::XSlideShowView::addMouseListener );
}

void EventMultiplexer::removeDoubleClickHandler(
    const MouseEventHandlerSharedPtr&    rHandler )
{
    mpImpl->maMouseDoubleClickHandlers.remove( 
        EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
            rHandler,
            0.0) );

    if( !mpImpl->isMouseListenerRegistered() )
        mpImpl->forEachView( &presentation::XSlideShowView::removeMouseListener );
}

void EventMultiplexer::addMouseMoveHandler(
    const MouseEventHandlerSharedPtr& rHandler,
    double                            nPriority )
{
    mpImpl->addMouseHandler(
        mpImpl->maMouseMoveHandlers,
        rHandler,
        nPriority,
        mpImpl->maMouseMoveHandlers.isEmpty()
        ? &presentation::XSlideShowView::addMouseMotionListener
        : NULL );
}

void EventMultiplexer::removeMouseMoveHandler(
    const MouseEventHandlerSharedPtr&  rHandler )
{
    mpImpl->maMouseMoveHandlers.remove( 
        EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
            rHandler,
            0.0) );

    if( mpImpl->maMouseMoveHandlers.isEmpty() )
        mpImpl->forEachView(
            &presentation::XSlideShowView::removeMouseMotionListener );
}

void EventMultiplexer::addHyperlinkHandler( const HyperlinkHandlerSharedPtr& rHandler, 
                                            double                           nPriority )
{
    mpImpl->maHyperlinkHandlers.addSorted(
        EventMultiplexerImpl::ImplHyperLinkHandlers::container_type::value_type(
            rHandler,
            nPriority) );
}

void EventMultiplexer::removeHyperlinkHandler( const HyperlinkHandlerSharedPtr& rHandler )
{
    mpImpl->maHyperlinkHandlers.remove( 
        EventMultiplexerImpl::ImplHyperLinkHandlers::container_type::value_type(
            rHandler,
            0.0) );
}

bool EventMultiplexer::notifyShapeListenerAdded( 
    const uno::Reference<presentation::XShapeEventListener>& xListener,
    const uno::Reference<drawing::XShape>&                   xShape )
{
    return mpImpl->maShapeListenerHandlers.applyAll(
        boost::bind(&ShapeListenerEventHandler::listenerAdded,
                    _1,
                    boost::cref(xListener),
                    boost::cref(xShape)) );
}

bool EventMultiplexer::notifyShapeListenerRemoved( 
    const uno::Reference<presentation::XShapeEventListener>& xListener,
    const uno::Reference<drawing::XShape>&                   xShape )
{
    return mpImpl->maShapeListenerHandlers.applyAll(
        boost::bind(&ShapeListenerEventHandler::listenerRemoved,
                    _1,
                    boost::cref(xListener),
                    boost::cref(xShape)) );
}

bool EventMultiplexer::notifyShapeCursorChange( 
    const uno::Reference<drawing::XShape>&  xShape, 
    sal_Int16                               nPointerShape )
{
    return mpImpl->maShapeCursorHandlers.applyAll(
        boost::bind(&ShapeCursorEventHandler::cursorChanged,
                    _1,
                    boost::cref(xShape),
                    nPointerShape));
}

bool EventMultiplexer::notifyUserPaintColor( RGBColor const& rUserColor )
{
    return mpImpl->maUserPaintEventHandlers.applyAll(
        boost::bind(&UserPaintEventHandler::colorChanged,
                    _1,
                    boost::cref(rUserColor)));
}

bool EventMultiplexer::notifyUserPaintStrokeWidth( double rUserStrokeWidth )
{
    return mpImpl->maUserPaintEventHandlers.applyAll(
        boost::bind(&UserPaintEventHandler::widthChanged,
		    _1,
                    rUserStrokeWidth));
}

bool EventMultiplexer::notifyUserPaintDisabled()
{
    return mpImpl->maUserPaintEventHandlers.applyAll(
        boost::mem_fn(&UserPaintEventHandler::disable));
}

bool EventMultiplexer::notifySwitchPenMode(){
    return mpImpl->maUserPaintEventHandlers.applyAll(
	    boost::mem_fn(&UserPaintEventHandler::switchPenMode));
}

bool EventMultiplexer::notifySwitchEraserMode(){
    return mpImpl->maUserPaintEventHandlers.applyAll(
	    boost::mem_fn(&UserPaintEventHandler::switchEraserMode));
}

//adding erasing all ink features with UserPaintOverlay
bool EventMultiplexer::notifyEraseAllInk( bool const& rEraseAllInk )
{
	return mpImpl->maUserPaintEventHandlers.applyAll(
        boost::bind(&UserPaintEventHandler::eraseAllInkChanged,
                    _1,
                    boost::cref(rEraseAllInk)));
}

//adding erasing features with UserPaintOverlay	
bool EventMultiplexer::notifyEraseInkWidth( sal_Int32 rEraseInkSize )
{
	return mpImpl->maUserPaintEventHandlers.applyAll(
        boost::bind(&UserPaintEventHandler::eraseInkWidthChanged,
                    _1,
                    boost::cref(rEraseInkSize)));
}
	
bool EventMultiplexer::notifyNextEffect()
{
    return mpImpl->notifyNextEffect();
}

bool EventMultiplexer::notifySlideStartEvent()
{
    return mpImpl->maSlideStartHandlers.applyAll(
        boost::mem_fn(&EventHandler::handleEvent) );
}

bool EventMultiplexer::notifySlideEndEvent()
{
    return mpImpl->maSlideEndHandlers.applyAll(
        boost::mem_fn(&EventHandler::handleEvent) );
}

bool EventMultiplexer::notifyAnimationStart(
    const AnimationNodeSharedPtr& rNode )
{
    return mpImpl->notifyAllAnimationHandlers( mpImpl->maAnimationStartHandlers, 
                                               rNode );
}

bool EventMultiplexer::notifyAnimationEnd(
    const AnimationNodeSharedPtr& rNode )
{
    return mpImpl->notifyAllAnimationHandlers( mpImpl->maAnimationEndHandlers, 
                                               rNode );
}

bool EventMultiplexer::notifySlideAnimationsEnd()
{
    return mpImpl->maSlideAnimationsEndHandlers.applyAll(
        boost::mem_fn(&EventHandler::handleEvent));
}

bool EventMultiplexer::notifyAudioStopped(
    const AnimationNodeSharedPtr& rNode )
{
    return mpImpl->notifyAllAnimationHandlers( 
        mpImpl->maAudioStoppedHandlers, 
        rNode );
}

bool EventMultiplexer::notifyCommandStopAudio(
    const AnimationNodeSharedPtr& rNode )
{
    return mpImpl->notifyAllAnimationHandlers( 
        mpImpl->maCommandStopAudioHandlers, 
        rNode );
}

bool EventMultiplexer::notifyPauseMode( bool bPauseShow )
{
    return mpImpl->maPauseHandlers.applyAll(
        boost::bind( &PauseEventHandler::handlePause,
                     _1, bPauseShow ));
}

bool EventMultiplexer::notifyViewAdded( const UnoViewSharedPtr& rView )
{
    ENSURE_OR_THROW( rView, "EventMultiplexer::notifyViewAdded(): Invalid view");

    // register event listener
    uno::Reference<presentation::XSlideShowView> const rUnoView(
        rView->getUnoView() );

    if( mpImpl->isMouseListenerRegistered() )
        rUnoView->addMouseListener( 
            mpImpl->mxListener.get() );

    if( !mpImpl->maMouseMoveHandlers.isEmpty() )
        rUnoView->addMouseMotionListener( 
            mpImpl->mxListener.get() );

    return mpImpl->maViewHandlers.applyAll(
        boost::bind( &ViewEventHandler::viewAdded,
                     _1,
                     boost::cref(rView) ));
}

bool EventMultiplexer::notifyViewRemoved( const UnoViewSharedPtr& rView )
{
    ENSURE_OR_THROW( rView,
                      "EventMultiplexer::removeView(): Invalid view" );
    
    // revoke event listeners           
    uno::Reference<presentation::XSlideShowView> const rUnoView(
        rView->getUnoView() );

    if( mpImpl->isMouseListenerRegistered() )
        rUnoView->removeMouseListener( 
            mpImpl->mxListener.get() );

    if( !mpImpl->maMouseMoveHandlers.isEmpty() )
        rUnoView->removeMouseMotionListener( 
            mpImpl->mxListener.get() );

    return mpImpl->maViewHandlers.applyAll(
        boost::bind( &ViewEventHandler::viewRemoved,
                     _1,
                     boost::cref(rView) ));
}

bool EventMultiplexer::notifyViewChanged( const UnoViewSharedPtr& rView )
{
    return mpImpl->maViewHandlers.applyAll(
        boost::bind( &ViewEventHandler::viewChanged,
                     _1,
                     boost::cref(rView) ));
}

bool EventMultiplexer::notifyViewChanged( const uno::Reference<presentation::XSlideShowView>& xView )
{
    UnoViewSharedPtr pView( mpImpl->findUnoView(xView) );

    if( !pView )
        return false; // view not registered here

    return notifyViewChanged( pView );
}

bool EventMultiplexer::notifyViewsChanged()
{
    return mpImpl->maViewHandlers.applyAll(
        boost::mem_fn( &ViewEventHandler::viewsChanged ));
}

bool EventMultiplexer::notifyViewClobbered( 
    const uno::Reference<presentation::XSlideShowView>& xView )
{
    UnoViewSharedPtr pView( mpImpl->findUnoView(xView) );

    if( !pView )
        return false; // view not registered here

    return mpImpl->maViewRepaintHandlers.applyAll(
        boost::bind( &ViewRepaintHandler::viewClobbered,
                     _1,
                     boost::cref(pView) ));
}

bool EventMultiplexer::notifyHyperlinkClicked(
    rtl::OUString const& hyperLink )
{
    return mpImpl->maHyperlinkHandlers.apply(
        boost::bind(&HyperlinkHandler::handleHyperlink,
                    _1,
                    boost::cref(hyperLink)) );
}

bool EventMultiplexer::notifySlideTransitionStarted()
{
	return true;
}

} // namespace internal
} // namespace presentation

