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

#include <com/sun/star/awt/XTopWindow.hpp>
#include <com/sun/star/awt/XTopWindowListener.hpp>
#include <com/sun/star/awt/XWindowListener.hpp>
#include <com/sun/star/frame/XBorderResizeListener.hpp>
#include <com/sun/star/frame/XControllerBorder.hpp>
#include <com/sun/star/script/ModuleType.hpp>
#include <com/sun/star/script/vba/VBAEventId.hpp>
#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
#include <com/sun/star/table/XCellRange.hpp>
#include <com/sun/star/util/XChangesListener.hpp>
#include <com/sun/star/util/XChangesNotifier.hpp>

#include <cppuhelper/implbase4.hxx>
#include <toolkit/unohlp.hxx>
#include <unotools/eventcfg.hxx>
#include <vbahelper/helperdecl.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>

#include "cellsuno.hxx"
#include "convuno.hxx"
#include "vbaapplication.hxx"

using namespace ::com::sun::star;
using namespace ::com::sun::star::script::vba::VBAEventId;
using namespace ::ooo::vba;

using ::rtl::OUString;

// ============================================================================

namespace {

/** Extracts a sheet index from the specified element of the passed sequence.
    The element may be an integer, a Calc range or ranges object, or a VBA Range object. */
SCTAB lclGetTabFromArgs( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException)
{
    VbaEventsHelperBase::checkArgument( rArgs, nIndex );

    // first try to extract a sheet index
    sal_Int32 nTab = -1;
    if( rArgs[ nIndex ] >>= nTab )
    {
        if( (nTab < 0) || (nTab > MAXTAB) )
            throw lang::IllegalArgumentException();
        return static_cast< SCTAB >( nTab );
    }

    // try VBA Range object
    uno::Reference< excel::XRange > xVbaRange = getXSomethingFromArgs< excel::XRange >( rArgs, nIndex );
    if( xVbaRange.is() )
    {
        uno::Reference< XHelperInterface > xVbaHelper( xVbaRange, uno::UNO_QUERY_THROW );
        // TODO: in the future, the parent may be an excel::XChart (chart sheet) -> will there be a common base interface?
        uno::Reference< excel::XWorksheet > xVbaSheet( xVbaHelper->getParent(), uno::UNO_QUERY_THROW );
        // VBA sheet index is 1-based
        return static_cast< SCTAB >( xVbaSheet->getIndex() - 1 );
    }

    // try single UNO range object
    uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable = getXSomethingFromArgs< sheet::XCellRangeAddressable >( rArgs, nIndex );
    if( xCellRangeAddressable.is() )
        return xCellRangeAddressable->getRangeAddress().Sheet;

    // at last, try UNO range list
    uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex );
    if( xRanges.is() )
    {
        uno::Sequence< table::CellRangeAddress > aRangeAddresses = xRanges->getRangeAddresses();
        if( aRangeAddresses.getLength() > 0 )
            return aRangeAddresses[ 0 ].Sheet;
    }

    throw lang::IllegalArgumentException();
}

/** Returns the AWT container window of the passed controller. */
uno::Reference< awt::XWindow > lclGetWindowForController( const uno::Reference< frame::XController >& rxController )
{
    if( rxController.is() ) try
    {
        uno::Reference< frame::XFrame > xFrame( rxController->getFrame(), uno::UNO_SET_THROW );
        return xFrame->getContainerWindow();
    }
    catch( uno::Exception& )
    {
    }
    return 0;
}

} // namespace

// ============================================================================

typedef ::cppu::WeakImplHelper4< awt::XTopWindowListener, awt::XWindowListener, frame::XBorderResizeListener, util::XChangesListener > ScVbaEventListener_BASE;

// This class is to process Workbook window related event
class ScVbaEventListener : public ScVbaEventListener_BASE
{
public :
    ScVbaEventListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell );
    virtual ~ScVbaEventListener();

    /** Starts listening to the passed document controller. */
    void startControllerListening( const uno::Reference< frame::XController >& rxController );
    /** Stops listening to the passed document controller. */
    void stopControllerListening( const uno::Reference< frame::XController >& rxController );

    // XTopWindowListener
    virtual void SAL_CALL windowOpened( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
    virtual void SAL_CALL windowClosing( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
    virtual void SAL_CALL windowClosed( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
    virtual void SAL_CALL windowMinimized( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
    virtual void SAL_CALL windowNormalized( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
    virtual void SAL_CALL windowActivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
    virtual void SAL_CALL windowDeactivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException);

    // XWindowListener
    virtual void SAL_CALL windowResized( const awt::WindowEvent& rEvent ) throw (uno::RuntimeException);
    virtual void SAL_CALL windowMoved( const awt::WindowEvent& rEvent ) throw (uno::RuntimeException);
    virtual void SAL_CALL windowShown( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
    virtual void SAL_CALL windowHidden( const lang::EventObject& rEvent ) throw (uno::RuntimeException);

    // XBorderResizeListener
    virtual void SAL_CALL borderWidthsChanged( const uno::Reference< uno::XInterface >& rSource, const frame::BorderWidths& aNewSize ) throw (uno::RuntimeException);

    // XChangesListener
    virtual void SAL_CALL changesOccurred( const util::ChangesEvent& rEvent ) throw (uno::RuntimeException);

    // XEventListener
    virtual void SAL_CALL disposing( const lang::EventObject& rEvent ) throw (uno::RuntimeException);

private:
    /** Starts listening to the document model. */
    void startModelListening();
    /** Stops listening to the document model. */
    void stopModelListening();

    /** Returns the controller for the passed VCL window. */
    uno::Reference< frame::XController > getControllerForWindow( Window* pWindow ) const;

    /** Calls the Workbook_Window[Activate|Deactivate] event handler. */
    void processWindowActivateEvent( Window* pWindow, bool bActivate );
    /** Posts a Workbook_WindowResize user event. */
    void postWindowResizeEvent( Window* pWindow );
    /** Callback link for Application::PostUserEvent(). */
    DECL_LINK( processWindowResizeEvent, Window* );

private:
    typedef ::std::map< Window*, uno::Reference< frame::XController > > WindowControllerMap;
    
    ::osl::Mutex        maMutex;
    ScVbaEventsHelper&  mrVbaEvents;
    uno::Reference< frame::XModel > mxModel;
    ScDocShell*         mpDocShell;
    WindowControllerMap maControllers;          /// Maps VCL top windows to their controllers.
    Window*             mpActiveWindow;         /// Currently activated window, to prevent multiple (de)activation.
    bool                mbWindowResized;        /// True = window resize system event processed.
    bool                mbBorderChanged;        /// True = borders changed system event processed.
    bool                mbDisposed;
};

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

ScVbaEventListener::ScVbaEventListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ) :
    mrVbaEvents( rVbaEvents ),
    mxModel( rxModel ),
    mpDocShell( pDocShell ),
    mpActiveWindow( 0 ),
    mbWindowResized( false ),
    mbBorderChanged( false ),
    mbDisposed( !rxModel.is() )
{
    if( !mxModel.is() )
        return;

    startModelListening();
    try
    {
        uno::Reference< frame::XController > xController( mxModel->getCurrentController(), uno::UNO_QUERY_THROW );
        startControllerListening( xController );
    }
    catch( uno::Exception& )
    {
    }
}

ScVbaEventListener::~ScVbaEventListener()
{
}

void ScVbaEventListener::startControllerListening( const uno::Reference< frame::XController >& rxController )
{
    ::osl::MutexGuard aGuard( maMutex );

    uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( rxController );
    if( xWindow.is() )
        try { xWindow->addWindowListener( this ); } catch( uno::Exception& ) {}

    uno::Reference< awt::XTopWindow > xTopWindow( xWindow, uno::UNO_QUERY );
    if( xTopWindow.is() )
        try { xTopWindow->addTopWindowListener( this ); } catch( uno::Exception& ) {}

    uno::Reference< frame::XControllerBorder > xControllerBorder( rxController, uno::UNO_QUERY );
    if( xControllerBorder.is() )
        try { xControllerBorder->addBorderResizeListener( this ); } catch( uno::Exception& ) {}

    if( Window* pWindow = VCLUnoHelper::GetWindow( xWindow ) )
        maControllers[ pWindow ] = rxController;
}

void ScVbaEventListener::stopControllerListening( const uno::Reference< frame::XController >& rxController )
{
    ::osl::MutexGuard aGuard( maMutex );

    uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( rxController );
    if( xWindow.is() )
        try { xWindow->removeWindowListener( this ); } catch( uno::Exception& ) {}

    uno::Reference< awt::XTopWindow > xTopWindow( xWindow, uno::UNO_QUERY );
    if( xTopWindow.is() )
        try { xTopWindow->removeTopWindowListener( this ); } catch( uno::Exception& ) {}

    uno::Reference< frame::XControllerBorder > xControllerBorder( rxController, uno::UNO_QUERY );
    if( xControllerBorder.is() )
        try { xControllerBorder->removeBorderResizeListener( this ); } catch( uno::Exception& ) {}

    if( Window* pWindow = VCLUnoHelper::GetWindow( xWindow ) )
    {
        maControllers.erase( pWindow );
        if( pWindow == mpActiveWindow )
            mpActiveWindow = 0;
    }
}

void SAL_CALL ScVbaEventListener::windowOpened( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
{
}

void SAL_CALL ScVbaEventListener::windowClosing( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
{
}

void SAL_CALL ScVbaEventListener::windowClosed( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
{
}

void SAL_CALL ScVbaEventListener::windowMinimized( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
{
}

void SAL_CALL ScVbaEventListener::windowNormalized( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
{
}

void SAL_CALL ScVbaEventListener::windowActivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( maMutex );

    if( !mbDisposed )
    {
        uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY );
        Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
        OSL_TRACE( "ScVbaEventListener::windowActivated - pWindow = 0x%x, mpActiveWindow = 0x%x", pWindow, mpActiveWindow );
        // do not fire activation event multiple time for the same window
        if( pWindow && (pWindow != mpActiveWindow) )
        {
            // if another window is active, fire deactivation event first
            if( mpActiveWindow )
                processWindowActivateEvent( mpActiveWindow, false );
            // fire activation event for the new window
            processWindowActivateEvent( pWindow, true );
            mpActiveWindow = pWindow;
        }
    }
}

void SAL_CALL ScVbaEventListener::windowDeactivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( maMutex );

    if( !mbDisposed )
    {
        uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY );
        Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
        OSL_TRACE( "ScVbaEventListener::windowDeactivated - pWindow = 0x%x, mpActiveWindow = 0x%x", pWindow, mpActiveWindow );
        // do not fire the deactivation event, if the window is not active (prevent multiple deactivation)
        if( pWindow && (pWindow == mpActiveWindow) )
            processWindowActivateEvent( pWindow, false );
        // forget pointer to the active window
        mpActiveWindow = 0;
    }
}

void SAL_CALL ScVbaEventListener::windowResized( const awt::WindowEvent& rEvent ) throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( maMutex );

    mbWindowResized = true;
    if( !mbDisposed && mbBorderChanged )
    {
        uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY );
        postWindowResizeEvent( VCLUnoHelper::GetWindow( xWindow ) );
    }
}

void SAL_CALL ScVbaEventListener::windowMoved( const awt::WindowEvent& /*rEvent*/ ) throw (uno::RuntimeException)
{
}

void SAL_CALL ScVbaEventListener::windowShown( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
{
}

void SAL_CALL ScVbaEventListener::windowHidden( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
{
}

void SAL_CALL ScVbaEventListener::borderWidthsChanged( const uno::Reference< uno::XInterface >& rSource, const frame::BorderWidths& /*aNewSize*/ ) throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( maMutex );

    mbBorderChanged = true;
    if( !mbDisposed && mbWindowResized )
    {
        uno::Reference< frame::XController > xController( rSource, uno::UNO_QUERY );
        uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( xController );
        postWindowResizeEvent( VCLUnoHelper::GetWindow( xWindow ) );
    }
}

void SAL_CALL ScVbaEventListener::changesOccurred( const util::ChangesEvent& rEvent ) throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( maMutex );

    sal_Int32 nCount = rEvent.Changes.getLength();
    if( mbDisposed || !mpDocShell || (nCount == 0) )
        return;

    util::ElementChange aChange = rEvent.Changes[ 0 ];
    OUString sOperation;
    aChange.Accessor >>= sOperation;
    if( !sOperation.equalsIgnoreAsciiCaseAscii("cell-change") )
        return;

    if( nCount == 1 )
    {
        uno::Reference< table::XCellRange > xRangeObj;
        aChange.ReplacedElement >>= xRangeObj;
        if( xRangeObj.is() )
        {
            uno::Sequence< uno::Any > aArgs( 1 );
            aArgs[0] <<= xRangeObj;
            mrVbaEvents.processVbaEventNoThrow( WORKSHEET_CHANGE, aArgs );
        }
        return;
    }

    ScRangeList aRangeList;
    for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
    {
        aChange = rEvent.Changes[ nIndex ];
        aChange.Accessor >>= sOperation;
        uno::Reference< table::XCellRange > xRangeObj;
        aChange.ReplacedElement >>= xRangeObj;
        if( xRangeObj.is() && sOperation.equalsIgnoreAsciiCaseAscii("cell-change") )
        {
            uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable( xRangeObj, uno::UNO_QUERY );
            if( xCellRangeAddressable.is() )
            {
                ScRange aRange;
                ScUnoConversion::FillScRange( aRange, xCellRangeAddressable->getRangeAddress() );
                aRangeList.Append( aRange );
            }
        }
    }

    if( aRangeList.Count() > 0 )
    {
        uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( mpDocShell, aRangeList ) );
        uno::Sequence< uno::Any > aArgs(1);
        aArgs[0] <<= xRanges;
        mrVbaEvents.processVbaEventNoThrow( WORKSHEET_CHANGE, aArgs );
    }
}

void SAL_CALL ScVbaEventListener::disposing( const lang::EventObject& rEvent ) throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( maMutex );

    uno::Reference< frame::XModel > xModel( rEvent.Source, uno::UNO_QUERY );
    if( xModel.is() )
    {
        OSL_ENSURE( xModel.get() == mxModel.get(), "ScVbaEventListener::disposing - disposing from unknown model" );
        stopModelListening();
        mbDisposed = true;
        return;
    }

    uno::Reference< frame::XController > xController( rEvent.Source, uno::UNO_QUERY );
    if( xController.is() )
    {
        stopControllerListening( xController );
        return;
    }
}

// private --------------------------------------------------------------------

void ScVbaEventListener::startModelListening()
{
    try
    {
        uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW );
        xChangesNotifier->addChangesListener( this );
    }
    catch( uno::Exception& )
    {
    }
}

void ScVbaEventListener::stopModelListening()
{
    try
    {
        uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW );
        xChangesNotifier->removeChangesListener( this );
    }
    catch( uno::Exception& )
    {
    }
}

uno::Reference< frame::XController > ScVbaEventListener::getControllerForWindow( Window* pWindow ) const
{
    WindowControllerMap::const_iterator aIt = maControllers.find( pWindow );
    return (aIt == maControllers.end()) ? uno::Reference< frame::XController >() : aIt->second;
}

void ScVbaEventListener::processWindowActivateEvent( Window* pWindow, bool bActivate )
{
    uno::Reference< frame::XController > xController = getControllerForWindow( pWindow );
    if( xController.is() )
    {
        uno::Sequence< uno::Any > aArgs( 1 );
        aArgs[ 0 ] <<= xController;
        mrVbaEvents.processVbaEventNoThrow( bActivate ? WORKBOOK_WINDOWACTIVATE : WORKBOOK_WINDOWDEACTIVATE, aArgs );
    }
}

void ScVbaEventListener::postWindowResizeEvent( Window* pWindow )
{
    // check that the passed window is still alive (it must be registered in maControllers)
    if( pWindow && (maControllers.count( pWindow ) > 0) )
    {
        mbWindowResized = mbBorderChanged = false;
        acquire();  // ensure we don't get deleted before the timer fires
        Application::PostUserEvent( LINK( this, ScVbaEventListener, processWindowResizeEvent ), pWindow );
    }
}

IMPL_LINK( ScVbaEventListener, processWindowResizeEvent, Window*, EMPTYARG pWindow )
{
    ::osl::MutexGuard aGuard( maMutex );

    /*  Check that the passed window is still alive (it must be registered in
        maControllers). While closing a document, postWindowResizeEvent() may
        be called on the last window which posts a user event via
        Application::PostUserEvent to call this event handler. VCL will trigger
        the handler some time later. Sometimes, the window gets deleted before.
        This is handled via the disposing() function which removes the window
        pointer from the member maControllers. Thus, checking whether
        maControllers contains pWindow ensures that the window is still alive. */
    if( !mbDisposed && pWindow && (maControllers.count( pWindow ) > 0) )
    {
        // do not fire event unless all mouse buttons have been released
        Window::PointerState aPointerState = pWindow->GetPointerState();
        if( (aPointerState.mnState & (MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT)) == 0 )
        {
            uno::Reference< frame::XController > xController = getControllerForWindow( pWindow );
            if( xController.is() )
            {
                uno::Sequence< uno::Any > aArgs( 1 );
                aArgs[ 0 ] <<= xController;
                // #163419# do not throw exceptions into application core
                mrVbaEvents.processVbaEventNoThrow( WORKBOOK_WINDOWRESIZE, aArgs );
            }
        }
    }
    release();
    return 0;
}

// ============================================================================

ScVbaEventsHelper::ScVbaEventsHelper( const uno::Sequence< uno::Any >& rArgs, const uno::Reference< uno::XComponentContext >& xContext ) :
    VbaEventsHelperBase( rArgs, xContext ),
    mbOpened( false )
{
    mpDocShell = dynamic_cast< ScDocShell* >( mpShell ); // mpShell from base class
    mpDoc = mpDocShell ? mpDocShell->GetDocument() : 0;

    if( !mxModel.is() || !mpDocShell || !mpDoc )
        return;

#define REGISTER_EVENT( eventid, moduletype, classname, eventname, cancelindex, worksheet ) \
    registerEventHandler( eventid, moduletype, classname "_" eventname, cancelindex, uno::Any( worksheet ) )
#define REGISTER_AUTO_EVENT( eventid, eventname ) \
    REGISTER_EVENT( AUTO_##eventid, script::ModuleType::NORMAL, "Auto", eventname, -1, false )
#define REGISTER_WORKBOOK_EVENT( eventid, eventname, cancelindex ) \
    REGISTER_EVENT( WORKBOOK_##eventid, script::ModuleType::DOCUMENT, "Workbook", eventname, cancelindex, false )
#define REGISTER_WORKSHEET_EVENT( eventid, eventname, cancelindex ) \
    REGISTER_EVENT( WORKSHEET_##eventid, script::ModuleType::DOCUMENT, "Worksheet", eventname, cancelindex, true ); \
    REGISTER_EVENT( (USERDEFINED_START + WORKSHEET_##eventid), script::ModuleType::DOCUMENT, "Workbook", "Sheet" eventname, (((cancelindex) >= 0) ? ((cancelindex) + 1) : -1), false )

    // global
    REGISTER_AUTO_EVENT( OPEN,  "Open" );
    REGISTER_AUTO_EVENT( CLOSE, "Close" );

    // Workbook
    REGISTER_WORKBOOK_EVENT( ACTIVATE,            "Activate",           -1 );
    REGISTER_WORKBOOK_EVENT( DEACTIVATE,          "Deactivate",         -1 );
    REGISTER_WORKBOOK_EVENT( OPEN,                "Open",               -1 );
    REGISTER_WORKBOOK_EVENT( BEFORECLOSE,         "BeforeClose",        0 );
    REGISTER_WORKBOOK_EVENT( BEFOREPRINT,         "BeforePrint",        0 );
    REGISTER_WORKBOOK_EVENT( BEFORESAVE,          "BeforeSave",         1 );
    REGISTER_WORKBOOK_EVENT( AFTERSAVE,           "AfterSave",          -1 );
    REGISTER_WORKBOOK_EVENT( NEWSHEET,            "NewSheet",           -1 );
    REGISTER_WORKBOOK_EVENT( WINDOWACTIVATE,      "WindowActivate",     -1 );
    REGISTER_WORKBOOK_EVENT( WINDOWDEACTIVATE,    "WindowDeactivate",   -1 );
    REGISTER_WORKBOOK_EVENT( WINDOWRESIZE,        "WindowResize",       -1 );

    // Worksheet events. All events have a corresponding workbook event.
    REGISTER_WORKSHEET_EVENT( ACTIVATE,           "Activate",           -1 );
    REGISTER_WORKSHEET_EVENT( DEACTIVATE,         "Deactivate",         -1 );
    REGISTER_WORKSHEET_EVENT( BEFOREDOUBLECLICK,  "BeforeDoubleClick",  1 );
    REGISTER_WORKSHEET_EVENT( BEFORERIGHTCLICK,   "BeforeRightClick",   1 );
    REGISTER_WORKSHEET_EVENT( CALCULATE,          "Calculate",          -1 );
    REGISTER_WORKSHEET_EVENT( CHANGE,             "Change",             -1 );
    REGISTER_WORKSHEET_EVENT( SELECTIONCHANGE,    "SelectionChange",    -1 );
    REGISTER_WORKSHEET_EVENT( FOLLOWHYPERLINK,    "FollowHyperlink",    -1 );

#undef REGISTER_WORKSHEET_EVENT
#undef REGISTER_WORKBOOK_EVENT
#undef REGISTER_AUTO_EVENT
#undef REGISTER_EVENT
}

ScVbaEventsHelper::~ScVbaEventsHelper()
{
}

void SAL_CALL ScVbaEventsHelper::notifyEvent( const css::document::EventObject& rEvent ) throw (css::uno::RuntimeException)
{
    static const uno::Sequence< uno::Any > saEmptyArgs;
    if( (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_OPENDOC )) ||
        (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_CREATEDOC )) )  // CREATEDOC triggered e.g. during VBA Workbooks.Add
    {
        processVbaEventNoThrow( WORKBOOK_OPEN, saEmptyArgs );
    }
    else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_ACTIVATEDOC ) )
    {
        processVbaEventNoThrow( WORKBOOK_ACTIVATE, saEmptyArgs );
    }
    else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_DEACTIVATEDOC ) )
    {
        processVbaEventNoThrow( WORKBOOK_DEACTIVATE, saEmptyArgs );
    }
    else if( (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEDOCDONE )) ||
             (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEASDOCDONE )) ||
             (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVETODOCDONE )) )
    {
        uno::Sequence< uno::Any > aArgs( 1 );
        aArgs[ 0 ] <<= true;
        processVbaEventNoThrow( WORKBOOK_AFTERSAVE, aArgs );
    }
    else if( (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEDOCFAILED )) ||
             (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEASDOCFAILED )) ||
             (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVETODOCFAILED )) )
    {
        uno::Sequence< uno::Any > aArgs( 1 );
        aArgs[ 0 ] <<= false;
        processVbaEventNoThrow( WORKBOOK_AFTERSAVE, aArgs );
    }
    else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_CLOSEDOC ) )
    {
        /*  Trigger the WORKBOOK_WINDOWDEACTIVATE and WORKBOOK_DEACTIVATE
            events and stop listening to the model (done in base class). */
        uno::Reference< frame::XController > xController( mxModel->getCurrentController() );
        if( xController.is() )
        {
            uno::Sequence< uno::Any > aArgs( 1 );
            aArgs[ 0 ] <<= xController;
            processVbaEventNoThrow( WORKBOOK_WINDOWDEACTIVATE, aArgs );
        }
        processVbaEventNoThrow( WORKBOOK_DEACTIVATE, saEmptyArgs );
    }
    else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_VIEWCREATED ) )
    {
        uno::Reference< frame::XController > xController( mxModel->getCurrentController() );
        if( mxListener.get() && xController.is() )
            mxListener->startControllerListening( xController );
    }
    VbaEventsHelperBase::notifyEvent( rEvent );
}

// protected ------------------------------------------------------------------

bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue,
        const EventHandlerInfo& rInfo, const uno::Sequence< uno::Any >& rArgs ) throw (uno::RuntimeException)
{
    // document and document shell are needed during event processing
    if( !mpShell || !mpDoc )
        throw uno::RuntimeException();

    /*  For document events: check if events are enabled via the
        Application.EnableEvents symbol (this is an Excel-only attribute).
        Check this again for every event, as the event handler may change the
        state of the EnableEvents symbol. Global events such as AUTO_OPEN and
        AUTO_CLOSE are always enabled. */
    bool bExecuteEvent = (rInfo.mnModuleType != script::ModuleType::DOCUMENT) || ScVbaApplication::getDocumentEventsEnabled();

    // framework and Calc fire a few events before 'OnLoad', ignore them
    if( bExecuteEvent )
        bExecuteEvent = (rInfo.mnEventId == WORKBOOK_OPEN) ? !mbOpened : mbOpened;

    // special handling for some events
    if( bExecuteEvent ) switch( rInfo.mnEventId )
    {
        case WORKBOOK_OPEN:
        {
            // execute delayed Activate event too (see above)
            rEventQueue.push_back( WORKBOOK_ACTIVATE );
            uno::Sequence< uno::Any > aArgs( 1 );
            aArgs[ 0 ] <<= mxModel->getCurrentController();
            rEventQueue.push_back( EventQueueEntry( WORKBOOK_WINDOWACTIVATE, aArgs ) );
            rEventQueue.push_back( AUTO_OPEN );
            // remember initial selection
            maOldSelection <<= mxModel->getCurrentSelection();
        }
        break;
        case WORKSHEET_SELECTIONCHANGE:
            // if selection is not changed, then do not fire the event
            bExecuteEvent = isSelectionChanged( rArgs, 0 );
        break;
    }

    if( bExecuteEvent )
    {
        // add workbook event associated to a sheet event
        bool bSheetEvent = false;
        if( (rInfo.maUserData >>= bSheetEvent) && bSheetEvent )
            rEventQueue.push_back( EventQueueEntry( rInfo.mnEventId + USERDEFINED_START, rArgs ) );
    }

    return bExecuteEvent;
}

uno::Sequence< uno::Any > ScVbaEventsHelper::implBuildArgumentList( const EventHandlerInfo& rInfo,
        const uno::Sequence< uno::Any >& rArgs ) throw (lang::IllegalArgumentException)
{
    // fill arguments for workbook events associated to sheet events according to sheet events, sheet will be added below
    bool bSheetEventAsBookEvent = rInfo.mnEventId > USERDEFINED_START;
    sal_Int32 nEventId = bSheetEventAsBookEvent ? (rInfo.mnEventId - USERDEFINED_START) : rInfo.mnEventId;

    uno::Sequence< uno::Any > aVbaArgs;
    switch( nEventId )
    {
        // *** Workbook ***

        // no arguments
        case WORKBOOK_ACTIVATE:
        case WORKBOOK_DEACTIVATE:
        case WORKBOOK_OPEN:
        break;
        // 1 arg: cancel
        case WORKBOOK_BEFORECLOSE:
        case WORKBOOK_BEFOREPRINT:
            aVbaArgs.realloc( 1 );
            // current cancel state will be inserted by caller
        break;
        // 2 args: saveAs, cancel
        case WORKBOOK_BEFORESAVE:
            aVbaArgs.realloc( 2 );
            checkArgumentType< bool >( rArgs, 0 );
            aVbaArgs[ 0 ] = rArgs[ 0 ];
            // current cancel state will be inserted by caller
        break;
        // 1 arg: success
        case WORKBOOK_AFTERSAVE:
            aVbaArgs.realloc( 1 );
            checkArgumentType< bool >( rArgs, 0 );
            aVbaArgs[ 0 ] = rArgs[ 0 ];
        break;
        // 1 arg: window
        case WORKBOOK_WINDOWACTIVATE:
        case WORKBOOK_WINDOWDEACTIVATE:
        case WORKBOOK_WINDOWRESIZE:
            aVbaArgs.realloc( 1 );
            aVbaArgs[ 0 ] = createWindow( rArgs, 0 );
        break;
        // 1 arg: worksheet
        case WORKBOOK_NEWSHEET:
            aVbaArgs.realloc( 1 );
            aVbaArgs[ 0 ] = createWorksheet( rArgs, 0 );
        break;

        // *** Worksheet ***

        // no arguments
        case WORKSHEET_ACTIVATE:
        case WORKSHEET_CALCULATE:
        case WORKSHEET_DEACTIVATE:
        break;
        // 1 arg: range
        case WORKSHEET_CHANGE:
        case WORKSHEET_SELECTIONCHANGE:
            aVbaArgs.realloc( 1 );
            aVbaArgs[ 0 ] = createRange( rArgs, 0 );
        break;
        // 2 args: range, cancel
        case WORKSHEET_BEFOREDOUBLECLICK:
        case WORKSHEET_BEFORERIGHTCLICK:
            aVbaArgs.realloc( 2 );
            aVbaArgs[ 0 ] = createRange( rArgs, 0 );
            // current cancel state will be inserted by caller
        break;
        // 1 arg: hyperlink
        case WORKSHEET_FOLLOWHYPERLINK:
            aVbaArgs.realloc( 1 );
            aVbaArgs[ 0 ] = createHyperlink( rArgs, 0 );
        break;
    }

    /*  For workbook events associated to sheet events, the workbook event gets
        the same arguments but with a Worksheet object in front of them. */
    if( bSheetEventAsBookEvent )
    {
        sal_Int32 nLength = aVbaArgs.getLength();
        uno::Sequence< uno::Any > aVbaArgs2( nLength + 1 );
        aVbaArgs2[ 0 ] = createWorksheet( rArgs, 0 );
        for( sal_Int32 nIndex = 0; nIndex < nLength; ++nIndex )
            aVbaArgs2[ nIndex + 1 ] = aVbaArgs[ nIndex ];
        aVbaArgs = aVbaArgs2;
    }

    return aVbaArgs;
}

void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue,
        const EventHandlerInfo& rInfo, bool bCancel ) throw (uno::RuntimeException)
{
    switch( rInfo.mnEventId )
    {
        case WORKBOOK_OPEN:
            mbOpened = true;
            // register the listeners
            if( !mxListener.is() )
                mxListener = new ScVbaEventListener( *this, mxModel, mpDocShell );
        break;
        case WORKBOOK_BEFORECLOSE:
            /*  Execute Auto_Close only if not cancelled by event handler, but
                before UI asks user whether to cancel closing the document. */
            if( !bCancel )
                rEventQueue.push_back( AUTO_CLOSE );
        break;
    }
}

OUString ScVbaEventsHelper::implGetDocumentModuleName( const EventHandlerInfo& rInfo,
        const uno::Sequence< uno::Any >& rArgs ) const throw (lang::IllegalArgumentException)
{
    bool bSheetEvent = false;
    rInfo.maUserData >>= bSheetEvent;
    SCTAB nTab = bSheetEvent ? lclGetTabFromArgs( rArgs, 0 ) : -1;
    if( bSheetEvent && (nTab < 0) )
        throw lang::IllegalArgumentException();

    String aCodeName;
    if( bSheetEvent )
        mpDoc->GetCodeName( nTab, aCodeName );
    else
        aCodeName = mpDoc->GetCodeName();
    return aCodeName;
}

// private --------------------------------------------------------------------

namespace {

/** Compares the passed range lists representing sheet selections. Ignores
    selections that refer to different sheets (returns false in this case). */
bool lclSelectionChanged( const ScRangeList& rLeft, const ScRangeList& rRight )
{
    // one of the range lists empty? -> return false, if both lists empty
    bool bLeftEmpty = rLeft.Count() == 0;
    bool bRightEmpty = rRight.Count() == 0;
    if( bLeftEmpty || bRightEmpty )
        return !(bLeftEmpty && bRightEmpty);

    // check sheet indexes of the range lists (assuming that all ranges in a list are on the same sheet)
    if( rLeft.GetObject( 0 )->aStart.Tab() != rRight.GetObject( 0 )->aStart.Tab() )
        return false;

    // compare all ranges
    return rLeft != rRight;
}

} // namespace

bool ScVbaEventsHelper::isSelectionChanged( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException, uno::RuntimeException)
{
    uno::Reference< uno::XInterface > xOldSelection( maOldSelection, uno::UNO_QUERY );
    uno::Reference< uno::XInterface > xNewSelection = getXSomethingFromArgs< uno::XInterface >( rArgs, nIndex, false );
    ScCellRangesBase* pOldCellRanges = ScCellRangesBase::getImplementation( xOldSelection );
    ScCellRangesBase* pNewCellRanges = ScCellRangesBase::getImplementation( xNewSelection );
    bool bChanged = !pOldCellRanges || !pNewCellRanges || lclSelectionChanged( pOldCellRanges->GetRangeList(), pNewCellRanges->GetRangeList() );
    maOldSelection <<= xNewSelection;
    return bChanged;
}

uno::Any ScVbaEventsHelper::createWorksheet( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
        throw (lang::IllegalArgumentException, uno::RuntimeException)
{
    // extract sheet index, will throw, if parameter is invalid
    SCTAB nTab = lclGetTabFromArgs( rArgs, nIndex );
    return uno::Any( excel::getUnoSheetModuleObj( mxModel, nTab ) );
}

uno::Any ScVbaEventsHelper::createRange( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
        throw (lang::IllegalArgumentException, uno::RuntimeException)
{
    // it is possible to pass an existing VBA Range object
    uno::Reference< excel::XRange > xVbaRange = getXSomethingFromArgs< excel::XRange >( rArgs, nIndex );
    if( !xVbaRange.is() )
    {
        uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex );
        uno::Reference< table::XCellRange > xRange = getXSomethingFromArgs< table::XCellRange >( rArgs, nIndex );
        if ( !xRanges.is() && !xRange.is() )
            throw lang::IllegalArgumentException();

        uno::Sequence< uno::Any > aArgs( 2 );
        if ( xRanges.is() )
        {
            aArgs[ 0 ] <<= excel::getUnoSheetModuleObj( xRanges );
            aArgs[ 1 ] <<= xRanges;
        }
        else
        {
            aArgs[ 0 ] <<= excel::getUnoSheetModuleObj( xRange );
            aArgs[ 1 ] <<= xRange;
        }
        xVbaRange.set( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Range", aArgs ), uno::UNO_QUERY_THROW );
    }
    return uno::Any( xVbaRange );
}

uno::Any ScVbaEventsHelper::createHyperlink( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
        throw (lang::IllegalArgumentException, uno::RuntimeException)
{
    uno::Reference< table::XCell > xCell = getXSomethingFromArgs< table::XCell >( rArgs, nIndex, false );
    uno::Sequence< uno::Any > aArgs( 2 );
    aArgs[ 0 ] <<= excel::getUnoSheetModuleObj( xCell );
    aArgs[ 1 ] <<= xCell;
    uno::Reference< uno::XInterface > xHyperlink( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Hyperlink", aArgs ), uno::UNO_SET_THROW );
    return uno::Any( xHyperlink );
}

uno::Any ScVbaEventsHelper::createWindow( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
        throw (lang::IllegalArgumentException, uno::RuntimeException)
{
    uno::Sequence< uno::Any > aArgs( 3 );
    aArgs[ 0 ] <<= getVBADocument( mxModel );
    aArgs[ 1 ] <<= mxModel;
    aArgs[ 2 ] <<= getXSomethingFromArgs< frame::XController >( rArgs, nIndex, false );
    uno::Reference< uno::XInterface > xWindow( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Window", aArgs ), uno::UNO_SET_THROW );
    return uno::Any( xWindow );
}

// ============================================================================

namespace vbaeventshelper
{
namespace sdecl = comphelper::service_decl;
sdecl::class_<ScVbaEventsHelper, sdecl::with_args<true> > serviceImpl;
extern sdecl::ServiceDecl const serviceDecl(
    serviceImpl,
    "ScVbaEventsHelper",
    "com.sun.star.script.vba.VBASpreadsheetEventProcessor" );
}

// ============================================================================
