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

#include "sfx2/userinputinterception.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/awt/MouseButton.hpp>
#include <com/sun/star/awt/KeyModifier.hpp>
/** === end UNO includes === **/

#include <cppuhelper/interfacecontainer.hxx>
#include <cppuhelper/weak.hxx>
#include <vcl/event.hxx>
#include <vcl/window.hxx>

//........................................................................
namespace sfx2
{
//........................................................................

	/** === begin UNO using === **/
	using ::com::sun::star::uno::Reference;
	using ::com::sun::star::uno::XInterface;
	using ::com::sun::star::uno::UNO_QUERY;
	using ::com::sun::star::uno::UNO_QUERY_THROW;
	using ::com::sun::star::uno::UNO_SET_THROW;
	using ::com::sun::star::uno::Exception;
	using ::com::sun::star::uno::RuntimeException;
	using ::com::sun::star::uno::Any;
	using ::com::sun::star::uno::makeAny;
	using ::com::sun::star::awt::MouseEvent;
	using ::com::sun::star::awt::KeyEvent;
	using ::com::sun::star::awt::InputEvent;
    using ::com::sun::star::awt::XKeyHandler;
    using ::com::sun::star::awt::XMouseClickHandler;
    using ::com::sun::star::lang::DisposedException;
	/** === end UNO using === **/
    namespace MouseButton = ::com::sun::star::awt::MouseButton;
    namespace KeyModifier = ::com::sun::star::awt::KeyModifier;

    struct UserInputInterception_Data
    {
    public:
        ::cppu::OWeakObject&                m_rControllerImpl;
        ::cppu::OInterfaceContainerHelper   m_aKeyHandlers;
        ::cppu::OInterfaceContainerHelper   m_aMouseClickHandlers;

    public:
        UserInputInterception_Data( ::cppu::OWeakObject& _rControllerImpl, ::osl::Mutex& _rMutex )
            :m_rControllerImpl( _rControllerImpl )
            ,m_aKeyHandlers( _rMutex )
            ,m_aMouseClickHandlers( _rMutex )
        {
        }
    };

    namespace
    {
        template< class VLCEVENT >
        void lcl_initModifiers( InputEvent& _rEvent, const VLCEVENT& _rVclEvent )
        {
	        _rEvent.Modifiers = 0;

            if ( _rVclEvent.IsShift() )
		        _rEvent.Modifiers |= KeyModifier::SHIFT;
	        if ( _rVclEvent.IsMod1() )
		        _rEvent.Modifiers |= KeyModifier::MOD1;
	        if ( _rVclEvent.IsMod2() )
		        _rEvent.Modifiers |= KeyModifier::MOD2;
                if ( _rVclEvent.IsMod3() )
                        _rEvent.Modifiers |= KeyModifier::MOD3;
        }

        void lcl_initKeyEvent( KeyEvent& rEvent, const ::KeyEvent& rEvt )
        {
            lcl_initModifiers( rEvent, rEvt.GetKeyCode() );

	        rEvent.KeyCode = rEvt.GetKeyCode().GetCode();
	        rEvent.KeyChar = rEvt.GetCharCode();
	        rEvent.KeyFunc = sal::static_int_cast< sal_Int16 >( rEvt.GetKeyCode().GetFunction());
        }

        void lcl_initMouseEvent( MouseEvent& rEvent, const ::MouseEvent& rEvt )
        {
            lcl_initModifiers( rEvent, rEvt );

	        rEvent.Buttons = 0;
	        if ( rEvt.IsLeft() )
		        rEvent.Buttons |= MouseButton::LEFT;
	        if ( rEvt.IsRight() )
		        rEvent.Buttons |= MouseButton::RIGHT;
	        if ( rEvt.IsMiddle() )
		        rEvent.Buttons |= MouseButton::MIDDLE;

	        rEvent.X = rEvt.GetPosPixel().X();
	        rEvent.Y = rEvt.GetPosPixel().Y();
	        rEvent.ClickCount = rEvt.GetClicks();
	        rEvent.PopupTrigger = sal_False;
        }

    }

	//====================================================================
	//= UserInputInterception
	//====================================================================
	//--------------------------------------------------------------------
    UserInputInterception::UserInputInterception( ::cppu::OWeakObject& _rControllerImpl, ::osl::Mutex& _rMutex )
        :m_pData( new UserInputInterception_Data( _rControllerImpl, _rMutex ) )
    {
    }

    //--------------------------------------------------------------------
    UserInputInterception::~UserInputInterception()
    {
    }

    //--------------------------------------------------------------------
    void UserInputInterception::addKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException)
    {
        if ( _rxHandler.is() )
	        m_pData->m_aKeyHandlers.addInterface( _rxHandler );
    }

    //--------------------------------------------------------------------
    void UserInputInterception::removeKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException)
    {
        m_pData->m_aKeyHandlers.removeInterface( _rxHandler );
    }

    //--------------------------------------------------------------------
    void UserInputInterception::addMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException)
    {
        if ( _rxHandler.is() )
	        m_pData->m_aMouseClickHandlers.addInterface( _rxHandler );
    }

    //--------------------------------------------------------------------
    void UserInputInterception::removeMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException)
    {
        m_pData->m_aMouseClickHandlers.removeInterface( _rxHandler );
    }

    //--------------------------------------------------------------------
    bool UserInputInterception::hasKeyHandlers() const
    {
        return m_pData->m_aKeyHandlers.getLength() > 0;
    }

    //--------------------------------------------------------------------
    bool UserInputInterception::hasMouseClickListeners() const
    {
        return m_pData->m_aMouseClickHandlers.getLength() > 0;
    }

    //--------------------------------------------------------------------
    bool UserInputInterception::handleNotifyEvent( const NotifyEvent& _rEvent )
    {
        Reference < XInterface > xHoldAlive( m_pData->m_rControllerImpl );

        sal_uInt16 nType = _rEvent.GetType();
        bool bHandled = false;

		switch ( nType )
        {
            case EVENT_KEYINPUT:
            case EVENT_KEYUP:
            {
                KeyEvent aEvent;
                lcl_initKeyEvent( aEvent, *_rEvent.GetKeyEvent() );
                if ( _rEvent.GetWindow() )
                    aEvent.Source = _rEvent.GetWindow()->GetComponentInterface();

                ::cppu::OInterfaceIteratorHelper aIterator( m_pData->m_aKeyHandlers );
                while ( aIterator.hasMoreElements() )
                {
                    Reference< XKeyHandler > xHandler( static_cast< XKeyHandler* >( aIterator.next() ) );
                    if ( !xHandler.is() )
                        continue;

                    try
                    {
                        if ( nType == EVENT_KEYINPUT )
                            bHandled = xHandler->keyPressed( aEvent );
                        else
                            bHandled = xHandler->keyReleased( aEvent );
                    }
                    catch( const DisposedException& e )
                    {
                        if ( e.Context == xHandler )
                            aIterator.remove();
                    }
                    catch( const RuntimeException& )
                    {
                        throw;
                    }
                    catch( const Exception& )
                    {
                    }
                }
            }
            break;

            case EVENT_MOUSEBUTTONDOWN:
            case EVENT_MOUSEBUTTONUP:
            {
                MouseEvent aEvent;
                lcl_initMouseEvent( aEvent, *_rEvent.GetMouseEvent() );
                if ( _rEvent.GetWindow() )
                    aEvent.Source = _rEvent.GetWindow()->GetComponentInterface();

                ::cppu::OInterfaceIteratorHelper aIterator( m_pData->m_aMouseClickHandlers );
                while ( aIterator.hasMoreElements() )
                {
                    Reference< XMouseClickHandler > xHandler( static_cast< XMouseClickHandler* >( aIterator.next() ) );
                    if ( !xHandler.is() )
                        continue;

                    try
                    {
                        if ( nType == EVENT_MOUSEBUTTONDOWN )
                            bHandled = xHandler->mousePressed( aEvent );
                        else
                            bHandled = xHandler->mouseReleased( aEvent );
                    }
                    catch( const DisposedException& e )
                    {
                        if ( e.Context == xHandler )
                            aIterator.remove();
                    }
                    catch( const RuntimeException& )
                    {
                        throw;
                    }
                    catch( const Exception& )
                    {
                    }
                }
            }
            break;

            default:
                OSL_ENSURE( false, "UserInputInterception::handleNotifyEvent: illegal event type!" );
                break;
        }

        return bHandled;
    }

//........................................................................
} // namespace sfx2
//........................................................................
