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



#ifndef _UNOCONTROLS_MULTIPLEXER_HXX
#define _UNOCONTROLS_MULTIPLEXER_HXX

//____________________________________________________________________________________________________________
//	includes of other projects
//____________________________________________________________________________________________________________

#include <com/sun/star/awt/XKeyListener.hpp>
#include <com/sun/star/awt/XPaintListener.hpp>
#include <com/sun/star/awt/KeyEvent.hpp>
#include <com/sun/star/awt/KeyModifier.hpp>
#include <com/sun/star/awt/XMouseMotionListener.hpp>
#include <com/sun/star/awt/FocusEvent.hpp>
#include <com/sun/star/awt/XWindowListener.hpp>
#include <com/sun/star/awt/XActivateListener.hpp>
#include <com/sun/star/awt/MouseEvent.hpp>
#include <com/sun/star/awt/XTopWindowListener.hpp>
#include <com/sun/star/awt/PaintEvent.hpp>
#include <com/sun/star/awt/InputEvent.hpp>
#include <com/sun/star/awt/KeyGroup.hpp>
#include <com/sun/star/awt/Key.hpp>
#include <com/sun/star/awt/WindowEvent.hpp>
#include <com/sun/star/awt/XMouseListener.hpp>
#include <com/sun/star/awt/KeyFunction.hpp>
#include <com/sun/star/awt/FocusChangeReason.hpp>
#include <com/sun/star/awt/MouseButton.hpp>
#include <com/sun/star/awt/XFocusListener.hpp>
#include <com/sun/star/awt/XTopWindow.hpp>
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/awt/PosSize.hpp>
#include <cppuhelper/weak.hxx>
#include <cppuhelper/interfacecontainer.hxx>
//____________________________________________________________________________________________________________
//	includes of my own project
//____________________________________________________________________________________________________________

//____________________________________________________________________________________________________________
//	"namespaces"
//____________________________________________________________________________________________________________

namespace unocontrols{

#define	UNO3_OWEAKOBJECT							::cppu::OWeakObject
#define	UNO3_XWINDOW								::com::sun::star::awt::XWindow
#define	UNO3_REFERENCE								::com::sun::star::uno::Reference
#define	UNO3_WEAKREFERENCE							::com::sun::star::uno::WeakReference
#define	UNO3_MUTEX									::osl::Mutex
#define	UNO3_XWINDOWLISTENER						::com::sun::star::awt::XWindowListener
#define	UNO3_XKEYLISTENER							::com::sun::star::awt::XKeyListener
#define	UNO3_XMOUSELISTENER							::com::sun::star::awt::XMouseListener
#define	UNO3_XMOUSEMOTIONLISTENER					::com::sun::star::awt::XMouseMotionListener
#define	UNO3_XPAINTLISTENER							::com::sun::star::awt::XPaintListener
#define	UNO3_XTOPWINDOWLISTENER						::com::sun::star::awt::XTopWindowListener
#define	UNO3_XFOCUSLISTENER							::com::sun::star::awt::XFocusListener
#define	UNO3_ANY									::com::sun::star::uno::Any
#define	UNO3_TYPE									::com::sun::star::uno::Type
#define	UNO3_RUNTIMEEXCEPTION						::com::sun::star::uno::RuntimeException
#define	UNO3_XINTERFACE								::com::sun::star::uno::XInterface
#define	UNO3_EVENTOBJECT							::com::sun::star::lang::EventObject
#define	UNO3_FOCUSEVENT								::com::sun::star::awt::FocusEvent
#define	UNO3_WINDOWEVENT							::com::sun::star::awt::WindowEvent
#define	UNO3_KEYEVENT								::com::sun::star::awt::KeyEvent
#define	UNO3_MOUSEEVENT								::com::sun::star::awt::MouseEvent
#define	UNO3_PAINTEVENT								::com::sun::star::awt::PaintEvent
#define	UNO3_OMULTITYPEINTERFACECONTAINERHELPER		::cppu::OMultiTypeInterfaceContainerHelper

//____________________________________________________________________________________________________________
//	class
//____________________________________________________________________________________________________________

class OMRCListenerMultiplexerHelper	: public UNO3_XFOCUSLISTENER
									, public UNO3_XWINDOWLISTENER
									, public UNO3_XKEYLISTENER
									, public UNO3_XMOUSELISTENER
									, public UNO3_XMOUSEMOTIONLISTENER
									, public UNO3_XPAINTLISTENER
									, public UNO3_XTOPWINDOWLISTENER
									, public UNO3_OWEAKOBJECT
{

//____________________________________________________________________________________________________________
//	public methods
//____________________________________________________________________________________________________________

public:

	//________________________________________________________________________________________________________
	//	construct/destruct
	//________________________________________________________________________________________________________

	/**_______________________________________________________________________________________________________
		@short		constructor
		@descr		Create a Multiplexer of XWindowEvents.

		@seealso	-

		@param		rControl	The control. All listeners think that this is the original broadcaster.
		@param		rPeer		The peer from which the original events are dispatched. Null is allowed.

		@return		-

		@onerror	-
	*/

	OMRCListenerMultiplexerHelper(	const	UNO3_REFERENCE< UNO3_XWINDOW >&	xControl	,
									const	UNO3_REFERENCE< UNO3_XWINDOW >&	xPeer		);

	/**_______________________________________________________________________________________________________
		@short		copy-constructor
		@descr

		@seealso	-

		@param		rCopyInstance	C++-Reference to instance to make copy from.

		@return		-

		@onerror	-
	*/

	OMRCListenerMultiplexerHelper( const OMRCListenerMultiplexerHelper& aCopyInstance );

	/**_______________________________________________________________________________________________________
		@short		destructor
		@descr		-

		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

	~OMRCListenerMultiplexerHelper();

	//________________________________________________________________________________________________________
	//	XInterface
	//________________________________________________________________________________________________________

	/**_______________________________________________________________________________________________________
		@short		give answer, if interface is supported
		@descr		The interfaces are searched by type.

		@seealso	XInterface

		@param      "rType" is the type of searched interface.

		@return		Any		information about found interface

		@onerror	A RuntimeException is thrown.
	*/

	virtual UNO3_ANY SAL_CALL queryInterface( const UNO3_TYPE& aType ) throw( UNO3_RUNTIMEEXCEPTION );

	/**_______________________________________________________________________________________________________
		@short		increment refcount
		@descr		-

		@seealso	XInterface
		@seealso	release()

		@param		-

		@return		-

		@onerror	A RuntimeException is thrown.
	*/

    virtual void SAL_CALL acquire() throw();

	/**_______________________________________________________________________________________________________
		@short		decrement refcount
		@descr		-

		@seealso	XInterface
		@seealso	acquire()

		@param		-

		@return		-

		@onerror	A RuntimeException is thrown.
	*/

    virtual void SAL_CALL release() throw();

	//________________________________________________________________________________________________________
	//	operator
	//________________________________________________________________________________________________________

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

	operator UNO3_REFERENCE< UNO3_XINTERFACE >() const;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

	OMRCListenerMultiplexerHelper& operator= ( const OMRCListenerMultiplexerHelper& aCopyInstance );

	//________________________________________________________________________________________________________
	//	container methods
	//________________________________________________________________________________________________________

	/**_______________________________________________________________________________________________________
		@short		Remove all listeners from the previous set peer and add the needed listeners to rPeer.
		@descr		-

		@seealso	-

		@param		rPeer		The peer from which the original events are dispatched. Null is allowed.

		@return		-

		@onerror	-
	*/

	void setPeer( const UNO3_REFERENCE< UNO3_XWINDOW >& xPeer );

	/**_______________________________________________________________________________________________________
		@short		Remove all listeners and send a disposing message.
		@descr		-

		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

	void disposeAndClear();

	/**_______________________________________________________________________________________________________
		@short		Add the specified listener to the source.
		@descr		-

		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    void advise(	const	UNO3_TYPE&							aType		,
					const	UNO3_REFERENCE< UNO3_XINTERFACE >&	xListener	);

	/**_______________________________________________________________________________________________________
		@short		Remove the specified listener from the source.
		@descr		-

		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    void unadvise(	const	UNO3_TYPE&							aType		,
					const	UNO3_REFERENCE< UNO3_XINTERFACE >&	xListener	);

	//________________________________________________________________________________________________________
	//	XEventListener
	//________________________________________________________________________________________________________

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

	virtual void SAL_CALL disposing(const UNO3_EVENTOBJECT& aSource) throw( UNO3_RUNTIMEEXCEPTION ) ;

	//________________________________________________________________________________________________________
	//	XFocusListener
	//________________________________________________________________________________________________________

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL focusGained(const UNO3_FOCUSEVENT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL focusLost(const UNO3_FOCUSEVENT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	//________________________________________________________________________________________________________
	//	XWindowListener
	//________________________________________________________________________________________________________

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL windowResized(const UNO3_WINDOWEVENT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL windowMoved(const UNO3_WINDOWEVENT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL windowShown(const UNO3_EVENTOBJECT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL windowHidden(const UNO3_EVENTOBJECT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	//________________________________________________________________________________________________________
	//	XKeyListener
	//________________________________________________________________________________________________________

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL keyPressed( const UNO3_KEYEVENT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL keyReleased( const UNO3_KEYEVENT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	//________________________________________________________________________________________________________
	//	XMouseListener
	//________________________________________________________________________________________________________

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL mousePressed(const UNO3_MOUSEEVENT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL mouseReleased(const UNO3_MOUSEEVENT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL mouseEntered(const UNO3_MOUSEEVENT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL mouseExited(const UNO3_MOUSEEVENT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	//________________________________________________________________________________________________________
	//	XMouseMotionListener
	//________________________________________________________________________________________________________

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL mouseDragged(const UNO3_MOUSEEVENT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL mouseMoved(const UNO3_MOUSEEVENT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	//________________________________________________________________________________________________________
	//	XPaintListener
	//________________________________________________________________________________________________________

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL windowPaint(const UNO3_PAINTEVENT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	//________________________________________________________________________________________________________
	//	XTopWindowListener
	//________________________________________________________________________________________________________

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

	virtual void SAL_CALL windowOpened( const UNO3_EVENTOBJECT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

	virtual void SAL_CALL windowClosing( const UNO3_EVENTOBJECT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL windowClosed( const UNO3_EVENTOBJECT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

	virtual void SAL_CALL windowMinimized( const UNO3_EVENTOBJECT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

	virtual void SAL_CALL windowNormalized( const UNO3_EVENTOBJECT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL windowActivated( const UNO3_EVENTOBJECT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

	/**_______________________________________________________________________________________________________
		@short		-
		@descr		-

		@seealso	-
		@seealso	-

		@param		-

		@return		-

		@onerror	-
	*/

    virtual void SAL_CALL windowDeactivated( const UNO3_EVENTOBJECT& aEvent ) throw( UNO3_RUNTIMEEXCEPTION ) ;

//____________________________________________________________________________________________________________
//	protected methods
//____________________________________________________________________________________________________________

protected:

	/**_______________________________________________________________________________________________________
		@short		Remove the listener from the peer.
		@descr		-

		@seealso	-

		@param		xPeer	The peer from which the listener is removed.
		@param		rType	The listener type, which specify the type of the listener.

		@return		-

		@onerror	-
	*/

	void impl_adviseToPeer(	const	UNO3_REFERENCE< UNO3_XWINDOW >&	xPeer	,
							const	UNO3_TYPE&						aType	);

	/**_______________________________________________________________________________________________________
		@short		Add the listener to the peer.
		@descr		-

		@seealso	-

		@param		xPeer	The peer to which the listener is added.
		@param		rType	The listener type, which specify the type of the listener.

		@return		-

		@onerror	-
	*/

	void impl_unadviseFromPeer(	const	UNO3_REFERENCE< UNO3_XWINDOW >&	xPeer	,
								const	UNO3_TYPE&						aType	);

//____________________________________________________________________________________________________________
//	private variables
//____________________________________________________________________________________________________________

private:

	UNO3_MUTEX									m_aMutex			;
	UNO3_REFERENCE< UNO3_XWINDOW >				m_xPeer				;	/// The source of the events. Normally this is the peer object.
	UNO3_WEAKREFERENCE< UNO3_XWINDOW >          m_xControl			;
	UNO3_OMULTITYPEINTERFACECONTAINERHELPER		m_aListenerHolder	;

};	// class OMRCListenerMultiplexerHelper

}	// namespace unocontrols

#endif	// ifndef _UNOCONTROLS_MULTIPLEXER_HXX
