/**************************************************************
 *
 * 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 FORMS_SOURCE_CLICKABLEIMAGE_HXX
#define FORMS_SOURCE_CLICKABLEIMAGE_HXX

#include "FormComponent.hxx"
#include "EventThread.hxx"
#include "imgprod.hxx"
#include <tools/link.hxx>
#include <comphelper/propmultiplex.hxx>
#include <com/sun/star/form/XImageProducerSupplier.hpp>
#include <com/sun/star/form/FormButtonType.hpp>
#include <com/sun/star/form/XApproveActionListener.hpp>
#include <com/sun/star/form/XApproveActionBroadcaster.hpp>
#include <com/sun/star/form/submission/XSubmissionSupplier.hpp>
#include <com/sun/star/form/submission/XSubmission.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XDispatchProviderInterception.hpp>
#include <cppuhelper/implbase3.hxx>


class SfxMedium;

//.........................................................................
namespace frm
{
//.........................................................................

    class OImageProducerThread_Impl;
    class ControlFeatureInterception;
    //==================================================================
    // OClickableImageBaseModel
    //==================================================================
    typedef ::cppu::ImplHelper3 <   ::com::sun::star::form::XImageProducerSupplier
                                ,   ::com::sun::star::awt::XImageProducer
                                ,   ::com::sun::star::form::submission::XSubmissionSupplier
                                >   OClickableImageBaseModel_Base;

    class OClickableImageBaseModel  :public OClickableImageBaseModel_Base
                                    ,public OControlModel
                                    ,public OPropertyChangeListener
    {
    protected:
	    ::com::sun::star::form::FormButtonType	m_eButtonType;		// Art des Buttons (push,submit,reset)
	    ::rtl::OUString							m_sTargetURL;		// URL fuer den URL-Button
	    ::rtl::OUString							m_sTargetFrame;		// TargetFrame zum Oeffnen

        // ImageProducer stuff
	    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageProducer>  	m_xProducer;
	    SfxMedium*								m_pMedium;			// Download-Medium
	    ImageProducer*							m_pProducer;
	    sal_Bool								m_bDispatchUrlInternal; // property: is not allowed to set : 1
	    sal_Bool								m_bDownloading : 1;	// laeuft ein Download?
	    sal_Bool 								m_bProdStarted : 1;

        // XSubmission stuff
        ::com::sun::star::uno::Reference< ::com::sun::star::form::submission::XSubmission >
                                                m_xSubmissionDelegate;


	    DECL_STATIC_LINK( OClickableImageBaseModel, DataAvailableLink, void* );
	    DECL_STATIC_LINK( OClickableImageBaseModel, DownloadDoneLink, void* );

	    inline ImageProducer* GetImageProducer() { return m_pProducer; }

	    void StartProduction();
	    void SetURL(const ::rtl::OUString& rURL);
	    void DataAvailable();
	    void DownloadDone();

	    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
	    inline sal_Bool isDispatchUrlInternal() const { return m_bDispatchUrlInternal; }
	    inline void		setDispatchUrlInternal(sal_Bool _bDispatch) { m_bDispatchUrlInternal = _bDispatch; }

    public:
	    DECLARE_DEFAULT_XTOR( OClickableImageBaseModel );

	    // UNO Anbindung
	    DECLARE_UNO3_AGG_DEFAULTS(OClickableImageBaseModel, OControlModel);
	    virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);

    protected:
        // OComponentHelper
	    virtual void SAL_CALL disposing();

        // ::com::sun::star::form::XImageProducerSupplier
	    virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageProducer> SAL_CALL getImageProducer() throw (::com::sun::star::uno::RuntimeException) { return m_xProducer; }

        // OPropertySetHelper
	    virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
	    virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) throw (::com::sun::star::uno::Exception);

	    virtual sal_Bool SAL_CALL convertFastPropertyValue(::com::sun::star::uno::Any& rConvertedValue, ::com::sun::star::uno::Any& rOldValue, sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
		    throw(::com::sun::star::lang::IllegalArgumentException);

        using ::cppu::OPropertySetHelper::getFastPropertyValue;

        // OPropertyChangeListener
	    virtual void _propertyChanged(const ::com::sun::star::beans::PropertyChangeEvent&) throw(::com::sun::star::uno::RuntimeException);

        // XPropertyState
	    virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const;

        // XImageProducer
        virtual void SAL_CALL addConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& xConsumer ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL removeConsumer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XImageConsumer >& xConsumer ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL startProduction(  ) throw (::com::sun::star::uno::RuntimeException);

        // XSubmissionSupplier
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::submission::XSubmission > SAL_CALL getSubmission() throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL setSubmission( const ::com::sun::star::uno::Reference< ::com::sun::star::form::submission::XSubmission >& _submission ) throw (::com::sun::star::uno::RuntimeException);

        // XServiceInfo
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw (::com::sun::star::uno::RuntimeException);

        // XEventListener
        using OControlModel::disposing;

    public:
        struct GuardAccess { friend class ImageModelMethodGuard; private: GuardAccess() { } };
        ::osl::Mutex&   getMutex( GuardAccess ) { return m_aMutex; }
        ImageProducer*  getImageProducer( GuardAccess ) { return m_pProducer; }

    protected:
        using OControlModel::getMutex;

	    void implConstruct();

        // to be called from within the cloning-ctor of your derived class
        void implInitializeImageURL( );
    };

    //==================================================================
    // ImageModelMethodGuard
    //==================================================================
    class ImageModelMethodGuard : public ::osl::MutexGuard
    {
    private:
        typedef ::osl::MutexGuard   GuardBase;

    public:
        ImageModelMethodGuard( OClickableImageBaseModel& _rModel )
            :GuardBase( _rModel.getMutex( OClickableImageBaseModel::GuardAccess() ) )
        {
            if ( NULL == _rModel.getImageProducer( OClickableImageBaseModel::GuardAccess() ) )
                throw ::com::sun::star::lang::DisposedException(
                    ::rtl::OUString(),
                    static_cast< ::com::sun::star::form::XImageProducerSupplier* >( &_rModel )
                );
        }
    };

    //==================================================================
    // OClickableImageBaseControl
    //==================================================================
    typedef ::cppu::ImplHelper3 <   ::com::sun::star::form::XApproveActionBroadcaster
                                ,   ::com::sun::star::form::submission::XSubmission
                                ,   ::com::sun::star::frame::XDispatchProviderInterception
                                >   OClickableImageBaseControl_BASE;

    class OClickableImageBaseControl    :public OClickableImageBaseControl_BASE
                                        ,public OControl
    {
	    friend class OImageProducerThread_Impl;

    private:
	    OImageProducerThread_Impl*          m_pThread;
        ::cppu::OInterfaceContainerHelper   m_aSubmissionVetoListeners;
        ::std::auto_ptr< ControlFeatureInterception >
                                            m_pFeatureInterception;

    protected:
        ::cppu::OInterfaceContainerHelper m_aApproveActionListeners;
	    ::cppu::OInterfaceContainerHelper m_aActionListeners;
	    ::rtl::OUString m_aActionCommand;

        // XSubmission
        virtual void SAL_CALL submit(  ) throw (::com::sun::star::util::VetoException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL submitWithInteraction( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& aHandler ) throw (::com::sun::star::util::VetoException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL addSubmissionVetoListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::submission::XSubmissionVetoListener >& listener ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL removeSubmissionVetoListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::submission::XSubmissionVetoListener >& listener ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);

        // XServiceInfo
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw (::com::sun::star::uno::RuntimeException);

        // XEventListener
        using OControl::disposing;

    public:
	    OClickableImageBaseControl(
		    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory,
		    const ::rtl::OUString& _aService);
	    virtual ~OClickableImageBaseControl();

    protected:
        // UNO Anbindung
	    DECLARE_UNO3_AGG_DEFAULTS(OClickableImageBaseControl, OControl);
	    virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);

        // OComponentHelper
	    virtual void SAL_CALL disposing();

        // ::com::sun::star::form::XApproveActionBroadcaster
	    virtual void SAL_CALL addApproveActionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XApproveActionListener>& _rxListener)
		    throw(::com::sun::star::uno::RuntimeException);
	    virtual void SAL_CALL removeApproveActionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XApproveActionListener>& _rxListener)
		    throw(::com::sun::star::uno::RuntimeException);

        // XDispatchProviderInterception
        virtual void SAL_CALL registerDispatchProviderInterceptor( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& Interceptor ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL releaseDispatchProviderInterceptor( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& Interceptor ) throw (::com::sun::star::uno::RuntimeException);

    protected:
	    virtual void actionPerformed_Impl( sal_Bool bNotifyListener, const ::com::sun::star::awt::MouseEvent& rEvt );

        ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > _getTypes();

        /** approves the action by calling the approve listeners
            @return <TRUE/> if and only if the action has <em>not</em> been cancelled by a listener
        */
        bool    approveAction( );

        /** retrieves (and if necessary creates) the image producer thread.

            Must be called with our mutex locked
        */
        OImageProducerThread_Impl* getImageProducerThread();

    private:
        void implSubmit(
            const ::com::sun::star::awt::MouseEvent& _rEvent,
            const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& aHandler
        ) SAL_THROW((com::sun::star::util::VetoException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException));
    };

    //==================================================================
    // OImageProducerThread_Impl
    //==================================================================
    class OImageProducerThread_Impl: public OComponentEventThread
    {
    protected:

	    // Die folgende Methode wrrd gerufen um das Event unter Beruecksichtigung
	    // seines Typs zu duplizieren
	    virtual ::com::sun::star::lang::EventObject* cloneEvent( const ::com::sun::star::lang::EventObject* _pEvt ) const;

	    // Ein Event bearbeiten. Der Mutex ist dabei nicht gelockt, pCompImpl
	    // bleibt aber in jedem Fall gueltig.
	    virtual void processEvent( ::cppu::OComponentHelper *pCompImpl,
							    const ::com::sun::star::lang::EventObject*,
							    const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>&,
							    sal_Bool );

    public:
	    OImageProducerThread_Impl( OClickableImageBaseControl *pControl ) :
		    OComponentEventThread( pControl )
	    {}

	    void addEvent() { ::com::sun::star::lang::EventObject aEvt; OComponentEventThread::addEvent( &aEvt ); }

    protected:
        using OComponentEventThread::addEvent;
    };

//.........................................................................
}	// namespace frm
//.........................................................................

#endif // FORMS_SOURCE_CLICKABLEIMAGE_HXX
