/**************************************************************
 * 
 * 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_forms.hxx"
#include "clickableimage.hxx"
#include "controlfeatureinterception.hxx"
#include "urltransformer.hxx"
#include "componenttools.hxx"
#include <com/sun/star/form/XSubmit.hpp>
#include <com/sun/star/awt/SystemPointer.hpp>
#include <com/sun/star/form/FormComponentType.hpp>
#include <com/sun/star/frame/XDispatch.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/awt/ActionEvent.hpp>
#include <com/sun/star/awt/XActionListener.hpp>
#include <tools/urlobj.hxx>
#include <tools/debug.hxx>
#include <vcl/svapp.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/objsh.hxx>
#include <vos/mutex.hxx>
#include "services.hxx"
#include <comphelper/container.hxx>
#include <comphelper/listenernotification.hxx>
#include <svtools/imageresourceaccess.hxx>
#define LOCAL_URL_PREFIX	'#'

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

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::sdb;
    using namespace ::com::sun::star::sdbc;
    using namespace ::com::sun::star::sdbcx;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::container;
    using namespace ::com::sun::star::form;
    using namespace ::com::sun::star::awt;
    using namespace ::com::sun::star::io;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::util;
    using namespace ::com::sun::star::frame;
    using namespace ::com::sun::star::form::submission;
    using ::com::sun::star::awt::MouseEvent;
    using ::com::sun::star::task::XInteractionHandler;

    //==================================================================
    // OClickableImageBaseControl
    //==================================================================
    //------------------------------------------------------------------------------
    Sequence<Type> OClickableImageBaseControl::_getTypes()
    {
        static Sequence<Type> aTypes;
        if (!aTypes.getLength())
            aTypes = concatSequences(OControl::_getTypes(), OClickableImageBaseControl_BASE::getTypes());
        return aTypes;
    }

    //------------------------------------------------------------------------------
    OClickableImageBaseControl::OClickableImageBaseControl(const Reference<XMultiServiceFactory>& _rxFactory, const ::rtl::OUString& _aService)
        :OControl(_rxFactory, _aService)
        ,m_pThread(NULL)
        ,m_aSubmissionVetoListeners( m_aMutex )
        ,m_aApproveActionListeners( m_aMutex )
        ,m_aActionListeners( m_aMutex )
    {
        m_pFeatureInterception.reset( new ControlFeatureInterception( _rxFactory ) );
    }

    //------------------------------------------------------------------------------
    OClickableImageBaseControl::~OClickableImageBaseControl()
    {
        if (!OComponentHelper::rBHelper.bDisposed)
        {
            acquire();
            dispose();
        }
    }

    // UNO Anbindung
    //------------------------------------------------------------------------------
    Any SAL_CALL OClickableImageBaseControl::queryAggregation(const Type& _rType) throw (RuntimeException)
    {
        Any aReturn = OControl::queryAggregation(_rType);
        if (!aReturn.hasValue())
            aReturn = OClickableImageBaseControl_BASE::queryInterface(_rType);
        return aReturn;
    }

    // XApproveActionBroadcaster
    //------------------------------------------------------------------------------
    void OClickableImageBaseControl::addApproveActionListener(
            const Reference<XApproveActionListener>& l) throw( RuntimeException )
    {
        m_aApproveActionListeners.addInterface(l);
    }

    //------------------------------------------------------------------------------
    void OClickableImageBaseControl::removeApproveActionListener(
            const Reference<XApproveActionListener>& l) throw( RuntimeException )
    {
        m_aApproveActionListeners.removeInterface(l);
    }

    //--------------------------------------------------------------------
    void SAL_CALL OClickableImageBaseControl::registerDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
    {
        m_pFeatureInterception->registerDispatchProviderInterceptor( _rxInterceptor  );
    }
    
    //--------------------------------------------------------------------
    void SAL_CALL OClickableImageBaseControl::releaseDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
    {
        m_pFeatureInterception->releaseDispatchProviderInterceptor( _rxInterceptor  );
    }

    // OComponentHelper
    //------------------------------------------------------------------------------
    void OClickableImageBaseControl::disposing()
    {
        EventObject aEvent( static_cast< XWeak* >( this ) );
        m_aApproveActionListeners.disposeAndClear( aEvent );
        m_aActionListeners.disposeAndClear( aEvent );
        m_aSubmissionVetoListeners.disposeAndClear( aEvent );
        m_pFeatureInterception->dispose();

        {
            ::osl::MutexGuard aGuard( m_aMutex );
            if( m_pThread )
            {
                m_pThread->release();
                m_pThread = NULL;
            }
        }

        OControl::disposing();
    }

    //------------------------------------------------------------------------------
    OImageProducerThread_Impl* OClickableImageBaseControl::getImageProducerThread()
    {
	    if ( !m_pThread )
	    {
		    m_pThread = new OImageProducerThread_Impl( this );
		    m_pThread->acquire();
		    m_pThread->create();
	    }
        return m_pThread;
    }

    //------------------------------------------------------------------------------
    bool OClickableImageBaseControl::approveAction( )
    {
        sal_Bool bCancelled = sal_False;
        EventObject aEvent( static_cast< XWeak* >( this ) );

        ::cppu::OInterfaceIteratorHelper aIter( m_aApproveActionListeners );
        while( !bCancelled && aIter.hasMoreElements() )
        {
            // Jede approveAction-Methode muss thread-safe sein!!!
            if( !static_cast< XApproveActionListener* >( aIter.next() )->approveAction( aEvent ) )
                bCancelled = sal_True;
        }

        return !bCancelled;
    }

    //------------------------------------------------------------------------------
    // Diese Methode wird auch aus einem Thread gerufen und muss deshalb
    // thread-safe sein.
    void OClickableImageBaseControl::actionPerformed_Impl(sal_Bool bNotifyListener, const MouseEvent& rEvt)
    {
        if( bNotifyListener )
        {
            if ( !approveAction() )
                return;
        }

        // Ob der Rest des Codes Thread-Safe ist weiss man nicht genau. Deshalb
        // wird das meiste bei gelocktem Solar-Mutex erledigen.
        Reference<XPropertySet>  xSet;
        Reference< XInterface > xModelsParent;
        FormButtonType eButtonType = FormButtonType_PUSH;
        {
            ::vos::OGuard aGuard( Application::GetSolarMutex() );

            // Parent holen
            Reference<XFormComponent>  xComp(getModel(), UNO_QUERY);
            if (!xComp.is())
                return;

            xModelsParent = xComp->getParent();
            if (!xModelsParent.is())
                return;

            // which button type?
            xSet = xSet.query( xComp );
            if ( !xSet.is() )
                return;
            xSet->getPropertyValue(PROPERTY_BUTTONTYPE) >>= eButtonType;
        }

        switch (eButtonType)
        {
            case FormButtonType_RESET:
            {
                // reset-Methoden muessen thread-safe sein!
                Reference<XReset>  xReset(xModelsParent, UNO_QUERY);
                if (!xReset.is())
                    return;

                xReset->reset();
            }
            break;

            case FormButtonType_SUBMIT:
            {
                // if some outer component can provide an interaction handler, use it
                Reference< XInteractionHandler > xHandler( m_pFeatureInterception->queryDispatch( "private:/InteractionHandler" ), UNO_QUERY );
                try
                {
                    implSubmit( rEvt, xHandler );
                }
                catch( const Exception& )
                {
                    // ignore
                }
            }
            break;

            case FormButtonType_URL:
            {
                ::vos::OGuard aGuard( Application::GetSolarMutex() );

                Reference< XModel >  xModel = getXModel(xModelsParent);
                if (!xModel.is())
                    return;

                ///////////////////////////////////////////////////////////////////////
                // Jetzt URL ausfuehren
                Reference< XController >  xController = xModel->getCurrentController();
                if (!xController.is())
                    return;

                Reference< XFrame >  xFrame = xController->getFrame();
                if( !xFrame.is() )
                    return;

                URL aURL;
                aURL.Complete =
                    getString(xSet->getPropertyValue(PROPERTY_TARGET_URL));

			    if (aURL.Complete.getLength() && (LOCAL_URL_PREFIX == aURL.Complete.getStr()[0]))
			    {	// the URL contains a local URL only. Since the URLTransformer does not handle this case correctly
				    // (it can't: it does not know the document URL), we have to take care for this ourself.
				    // The real solution would be to not allow such relative URLs (there is a rule that at runtime, all
				    // URLs have to be absolute), but for compatibility reasons this is no option.
				    // The more as the user does not want to see a local URL as "file://<path>/<document>#mark" if it
				    // could be "#mark" as well.
				    // If we someday say that this hack (yes, it's kind of a hack) is not sustainable anymore, the complete
				    // solutiuon would be:
				    // * recognize URLs consisting of a mark only while _reading_ the document
				    // * for this, allow the INetURLObject (which at the moment is invoked when reading URLs) to
				    //   transform such mark-only URLs into correct absolute URLs
				    // * at the UI, show only the mark
				    // * !!!! recognize every SAVEAS on the document, so the absolute URL can be adjusted. This seems
				    // rather impossible !!!
				    // 89752 - 23.07.2001 - frank.schoenheit@sun.com
				    aURL.Mark = aURL.Complete;
				    aURL.Complete = xModel->getURL();
				    aURL.Complete += aURL.Mark;
			    }

			    sal_Bool bDispatchUrlInternal = sal_False;
			    xSet->getPropertyValue(PROPERTY_DISPATCHURLINTERNAL) >>= bDispatchUrlInternal;
			    if ( bDispatchUrlInternal )
			    {
                    m_pFeatureInterception->getTransformer().parseSmartWithAsciiProtocol( aURL, INET_FILE_SCHEME );

				    ::rtl::OUString aTargetFrame;
				    xSet->getPropertyValue(PROPERTY_TARGET_FRAME) >>= aTargetFrame;

				    Reference< XDispatch >  xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch( aURL, aTargetFrame,
						    FrameSearchFlag::SELF | FrameSearchFlag::PARENT |
						    FrameSearchFlag::SIBLINGS | FrameSearchFlag::CREATE );

				    Sequence<PropertyValue> aArgs(1);
				    PropertyValue& rProp = aArgs.getArray()[0];
				    rProp.Name = ::rtl::OUString::createFromAscii("Referer");
				    rProp.Value <<= xModel->getURL();

				    if (xDisp.is())
					    xDisp->dispatch( aURL, aArgs );
			    }
			    else
			    {
				    URL aHyperLink = m_pFeatureInterception->getTransformer().getStrictURLFromAscii( ".uno:OpenHyperlink" );

				    Reference< XDispatch >  xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch(aHyperLink, ::rtl::OUString() , 0);

				    if ( xDisp.is() )
				    {
					    Sequence<PropertyValue> aProps(3);
					    aProps[0].Name  = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL"));
					    aProps[0].Value <<= aURL.Complete;

					    aProps[1].Name  = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FrameName"));
					    aProps[1].Value = xSet->getPropertyValue(PROPERTY_TARGET_FRAME);

					    aProps[2].Name  = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer"));
					    aProps[2].Value <<= xModel->getURL();

					    xDisp->dispatch( aHyperLink, aProps );
				    }
			    }
            }   break;
            default:
            {
                    // notify the action listeners for a push button
                ActionEvent aEvt(static_cast<XWeak*>(this), m_aActionCommand);
                m_aActionListeners.notifyEach( &XActionListener::actionPerformed, aEvt );
            }
        }
    }


    //--------------------------------------------------------------------
    void SAL_CALL OClickableImageBaseControl::addSubmissionVetoListener( const Reference< submission::XSubmissionVetoListener >& listener ) throw (NoSupportException, RuntimeException)
    {
        m_aSubmissionVetoListeners.addInterface( listener );
    }

    //--------------------------------------------------------------------
    void SAL_CALL OClickableImageBaseControl::removeSubmissionVetoListener( const Reference< submission::XSubmissionVetoListener >& listener ) throw (NoSupportException, RuntimeException)
    {
        m_aSubmissionVetoListeners.removeInterface( listener );
    }

    //--------------------------------------------------------------------
    void SAL_CALL OClickableImageBaseControl::submitWithInteraction( const Reference< XInteractionHandler >& _rxHandler ) throw (VetoException, WrappedTargetException, RuntimeException)
    {
        implSubmit( MouseEvent(), _rxHandler );
    }

    //--------------------------------------------------------------------
    void SAL_CALL OClickableImageBaseControl::submit(  ) throw (VetoException, WrappedTargetException, RuntimeException)
    {
        implSubmit( MouseEvent(), NULL );
    }

    //--------------------------------------------------------------------
    Sequence< ::rtl::OUString > SAL_CALL OClickableImageBaseControl::getSupportedServiceNames(  ) throw (RuntimeException)
    {
	    Sequence< ::rtl::OUString > aSupported = OControl::getSupportedServiceNames();
	    aSupported.realloc( aSupported.getLength() + 1 );

	    ::rtl::OUString* pArray = aSupported.getArray();
	    pArray[ aSupported.getLength() - 1 ] = FRM_SUN_CONTROL_SUBMITBUTTON;

        return aSupported;
    }

    //--------------------------------------------------------------------
    void OClickableImageBaseControl::implSubmit( const MouseEvent& _rEvent, const Reference< XInteractionHandler >& _rxHandler ) SAL_THROW((VetoException, WrappedTargetException, RuntimeException))
    {
        try
        {
            // allow the veto listeners to join the game
            m_aSubmissionVetoListeners.notifyEach( &XSubmissionVetoListener::submitting, EventObject( *this ) );

            // see whether there's an "submit interceptor" set at our model
            Reference< submission::XSubmissionSupplier > xSubmissionSupp( getModel(), UNO_QUERY );
            Reference< XSubmission > xSubmission;
            if ( xSubmissionSupp.is() )
                xSubmission = xSubmissionSupp->getSubmission();

            if ( xSubmission.is() )
            {
                if ( !_rxHandler.is() )
                    xSubmission->submit();
                else
                    xSubmission->submitWithInteraction( _rxHandler );
            }
            else
            {
                // no "interceptor" -> ordinary (old-way) submission
                Reference< XChild > xChild( getModel(), UNO_QUERY );
                Reference< XSubmit > xParentSubmission;
                if ( xChild.is() )
                    xParentSubmission = xParentSubmission.query( xChild->getParent() );
                if ( xParentSubmission.is() )
                    xParentSubmission->submit( this, _rEvent );
            }
        }
        catch( const VetoException& )
        {
            // allowed to leave
            throw;
        }
        catch( const RuntimeException& )
        {
            // allowed to leave
            throw;
        }
        catch( const WrappedTargetException& e )
        {
            // allowed to leave
            throw;
        }
        catch( const Exception& e )
        {
            OSL_ENSURE( sal_False, "OClickableImageBaseControl::implSubmit: caught an unknown exception!" );
            throw WrappedTargetException( ::rtl::OUString(), *this, makeAny( e ) );
        }
    }

    //==================================================================
    // OClickableImageBaseModel
    //==================================================================
    //------------------------------------------------------------------------------
    Sequence<Type> OClickableImageBaseModel::_getTypes()
    {
	    return concatSequences(
            OControlModel::_getTypes(),
            OClickableImageBaseModel_Base::getTypes()
        );
    }

    //------------------------------------------------------------------
    DBG_NAME( OClickableImageBaseModel )
    //------------------------------------------------------------------
    OClickableImageBaseModel::OClickableImageBaseModel( const Reference< XMultiServiceFactory >& _rxFactory, const ::rtl::OUString& _rUnoControlModelTypeName,
		    const ::rtl::OUString& rDefault )
	    :OControlModel( _rxFactory, _rUnoControlModelTypeName, rDefault )
	    ,OPropertyChangeListener(m_aMutex)
	    ,m_pMedium(NULL)
	    ,m_pProducer( NULL )
	    ,m_bDispatchUrlInternal(sal_False)
	    ,m_bDownloading(sal_False)
	    ,m_bProdStarted(sal_False)
    {
	    DBG_CTOR( OClickableImageBaseModel, NULL );
	    implConstruct();
	    m_eButtonType = FormButtonType_PUSH;
    }

    //------------------------------------------------------------------
    OClickableImageBaseModel::OClickableImageBaseModel( const OClickableImageBaseModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
	    :OControlModel( _pOriginal, _rxFactory )
	    ,OPropertyChangeListener( m_aMutex )
	    ,m_pMedium( NULL )
	    ,m_pProducer( NULL )
	    ,m_bDispatchUrlInternal(sal_False)
	    ,m_bDownloading( sal_False )
	    ,m_bProdStarted( sal_False )
    {
	    DBG_CTOR( OClickableImageBaseModel, NULL );
	    implConstruct();

	    // copy properties
	    m_eButtonType			= _pOriginal->m_eButtonType;
	    m_sTargetURL			= _pOriginal->m_sTargetURL;
	    m_sTargetFrame			= _pOriginal->m_sTargetFrame;
	    m_bDispatchUrlInternal	= _pOriginal->m_bDispatchUrlInternal;
    }

    //------------------------------------------------------------------------------
    void OClickableImageBaseModel::implInitializeImageURL( )
    {
        osl_incrementInterlockedCount( &m_refCount );
        {
            // simulate a propertyChanged event for the ImageURL
            // 2003-05-15 - #109591# - fs@openoffice.org
            Any aImageURL;
            getFastPropertyValue( aImageURL, PROPERTY_ID_IMAGE_URL );
            _propertyChanged( PropertyChangeEvent( *this, PROPERTY_IMAGE_URL, sal_False, PROPERTY_ID_IMAGE_URL, Any( ), aImageURL ) );
        }
        osl_decrementInterlockedCount( &m_refCount );
    }

    //------------------------------------------------------------------------------
    void OClickableImageBaseModel::implConstruct()
    {
	    m_pProducer = new ImageProducer;
        increment( m_refCount );
	    {
		    m_xProducer = m_pProducer;

		    if ( m_xAggregateSet.is() )
		    {
			    OPropertyChangeMultiplexer* pMultiplexer = new OPropertyChangeMultiplexer( this, m_xAggregateSet );
			    pMultiplexer->addProperty( PROPERTY_IMAGE_URL );
		    }
	    }
        decrement(m_refCount);
    }

    //------------------------------------------------------------------------------
    OClickableImageBaseModel::~OClickableImageBaseModel()
    {
        if (!OComponentHelper::rBHelper.bDisposed)
        {
            acquire();
            dispose();
        }
        DBG_ASSERT(m_pMedium == NULL, "OClickableImageBaseModel::~OClickableImageBaseModel : leaving a memory leak ...");
            // spaetestens im dispose sollte das aufgeraeumt worden sein

	    DBG_DTOR( OClickableImageBaseModel, NULL );
    }

    // XImageProducer
    //--------------------------------------------------------------------
    void SAL_CALL OClickableImageBaseModel::addConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
    {
        ImageModelMethodGuard aGuard( *this );
        GetImageProducer()->addConsumer( _rxConsumer );
    }

    //--------------------------------------------------------------------
    void SAL_CALL OClickableImageBaseModel::removeConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
    {
        ImageModelMethodGuard aGuard( *this );
        GetImageProducer()->removeConsumer( _rxConsumer );
    }

    //--------------------------------------------------------------------
    void SAL_CALL OClickableImageBaseModel::startProduction(  ) throw (RuntimeException)
    {
        ImageModelMethodGuard aGuard( *this );
        GetImageProducer()->startProduction();
    }

    //--------------------------------------------------------------------
    Reference< submission::XSubmission > SAL_CALL OClickableImageBaseModel::getSubmission() throw (RuntimeException)
    {
        return m_xSubmissionDelegate;
    }

    //--------------------------------------------------------------------
    void SAL_CALL OClickableImageBaseModel::setSubmission( const Reference< submission::XSubmission >& _submission ) throw (RuntimeException)
    {
        m_xSubmissionDelegate = _submission;
    }

    //--------------------------------------------------------------------
    Sequence< ::rtl::OUString > SAL_CALL OClickableImageBaseModel::getSupportedServiceNames(  ) throw (RuntimeException)
    {
	    Sequence< ::rtl::OUString > aSupported = OControlModel::getSupportedServiceNames();
	    aSupported.realloc( aSupported.getLength() + 1 );

	    ::rtl::OUString* pArray = aSupported.getArray();
	    pArray[ aSupported.getLength() - 1 ] = FRM_SUN_COMPONENT_SUBMITBUTTON;

        return aSupported;
    }

    // OComponentHelper
    //------------------------------------------------------------------------------
    void OClickableImageBaseModel::disposing()
    {
        OControlModel::disposing();
        if (m_pMedium)
        {
            delete m_pMedium;
            m_pMedium = NULL;
        }

        m_xProducer = NULL;
        m_pProducer = NULL;
    }

    //------------------------------------------------------------------------------
    Any SAL_CALL OClickableImageBaseModel::queryAggregation(const Type& _rType) throw (RuntimeException)
    {
        // order matters:
        // we definately want to "overload" the XImageProducer interface of our aggregate,
        // thus check OClickableImageBaseModel_Base (which provides this) first
        Any aReturn = OClickableImageBaseModel_Base::queryInterface( _rType );

        // BUT: _don't_ let it feel responsible for the XTypeProvider interface
        // (as this is implemented by our base class in the proper way)
        if  (   _rType.equals( ::getCppuType( static_cast< Reference< XTypeProvider >* >( NULL ) ) )
            ||  !aReturn.hasValue()
            )
            aReturn = OControlModel::queryAggregation( _rType );

        return aReturn;
    }

    //------------------------------------------------------------------------------
    void OClickableImageBaseModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
    {
        switch (nHandle)
        {
            case PROPERTY_ID_BUTTONTYPE				: rValue <<= m_eButtonType; break;
            case PROPERTY_ID_TARGET_URL				: rValue <<= m_sTargetURL; break;
            case PROPERTY_ID_TARGET_FRAME			: rValue <<= m_sTargetFrame; break;
		    case PROPERTY_ID_DISPATCHURLINTERNAL	: rValue <<= m_bDispatchUrlInternal; break;
            default:
                OControlModel::getFastPropertyValue(rValue, nHandle);
        }
    }

    //------------------------------------------------------------------------------
    void OClickableImageBaseModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( Exception)
    {
        switch (nHandle)
        {
            case PROPERTY_ID_BUTTONTYPE :
                DBG_ASSERT(isA(rValue, static_cast<FormButtonType*>(NULL)), "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
                rValue >>= m_eButtonType;
                break;

            case PROPERTY_ID_TARGET_URL :
                DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
                rValue >>= m_sTargetURL;
                break;

            case PROPERTY_ID_TARGET_FRAME :
                DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
                rValue >>= m_sTargetFrame;
                break;

		    case PROPERTY_ID_DISPATCHURLINTERNAL:
			    DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
                rValue >>= m_bDispatchUrlInternal;
			    break;

            default:
                OControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue);
        }
    }

    //------------------------------------------------------------------------------
    sal_Bool OClickableImageBaseModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
                                throw( IllegalArgumentException )
    {
        switch (nHandle)
        {
            case PROPERTY_ID_BUTTONTYPE :
			    return tryPropertyValueEnum( rConvertedValue, rOldValue, rValue, m_eButtonType );

            case PROPERTY_ID_TARGET_URL :
                return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sTargetURL);

            case PROPERTY_ID_TARGET_FRAME :
                return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sTargetFrame);

		    case PROPERTY_ID_DISPATCHURLINTERNAL :
                return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bDispatchUrlInternal);

            default:
                return OControlModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
        }
    }

    //------------------------------------------------------------------------------
    void OClickableImageBaseModel::StartProduction()
    {
        ImageProducer *pImgProd = GetImageProducer();
        // grab the ImageURL
        rtl::OUString sURL;
        getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ImageURL") ) ) >>= sURL;       
        if (!m_pMedium)
        {
            if ( ::svt::GraphicAccess::isSupportedURL( sURL )  )
                pImgProd->SetImage( sURL );
            else 
                // caution: the medium may be NULL if somebody gave us a invalid URL to work with
                // 11/24/2000 - 79667 - FS
                pImgProd->SetImage(String());
            m_bDownloading = sal_False;
            return;
        }
        if (m_pMedium->GetErrorCode()==0)
        {
            SvStream* pStream = m_pMedium->GetInStream();

            pImgProd->SetImage(*pStream);
            pImgProd->startProduction();
            m_bProdStarted = sal_True;
        }
        else
        {
            pImgProd->SetImage(String());
            delete m_pMedium;
            m_pMedium = 0;
            m_bDownloading = sal_False;
        }
    }

    //------------------------------------------------------------------------------
    void OClickableImageBaseModel::SetURL( const ::rtl::OUString& rURL )
    {
        if (m_pMedium || !rURL.getLength())
        {
            // Den Stream am Producer freigeben, bevor das Medium geloscht wird.
            GetImageProducer()->SetImage(String());
            delete m_pMedium;
            m_pMedium = NULL;
        }

        // the SfxMedium is not allowed to be created with an invalid URL, so we have to check this first
        // 23.01.2001 - 81927 - FS
        INetURLObject aUrl(rURL);
        if (INET_PROT_NOT_VALID == aUrl.GetProtocol())
            // we treat an invalid URL like we would treat no URL
            return;

        if (rURL.getLength() && !::svt::GraphicAccess::isSupportedURL( rURL ) ) 
       {
            if (m_pMedium)
                delete m_pMedium;

            m_pMedium = new SfxMedium(rURL, STREAM_STD_READ, sal_False);
            m_pMedium->SetDataAvailableLink(
                    STATIC_LINK(this, OClickableImageBaseModel, DataAvailableLink));

            // Das XModel suchen, um an die Object-Shell oder zumindest den
            // Referer zu gelangen.
            // Das Model findet man allerdings nur beim Laden von HTML-Dokumenten
            // und dann, wenn die URL in einem bereits geladenen Dokument
            // geaendert wird. Waehrend des Ladens kommt man nicht an das
            // Model ran.
            Reference< XModel >  xModel;
            InterfaceRef  xIfc( *this );
            while( !xModel.is() && xIfc.is() )
            {
                Reference<XChild>  xChild( xIfc, UNO_QUERY );
                xIfc = xChild->getParent();
                query_interface(xIfc, xModel);
            }

            // Die Object-Shell suchen, indem wir
            // ueber alle Object-Shells iterieren und deren XModel mit dem
            // eigenen vergleichen. Als Optimierung probieren wir aber erstmal
            // die aktuelle Object-Shell.
            // wir unser XModel mit dem aller Object
            SfxObjectShell *pObjSh = 0;

            if( xModel.is() )
            {
                SfxObjectShell *pTestObjSh = SfxObjectShell::Current();
                if( pTestObjSh )
                {
                    Reference< XModel >  xTestModel = pTestObjSh->GetModel();
                    if( xTestModel == xModel )
                        pObjSh = pTestObjSh;
                }
                if( !pObjSh )
                {
                    pTestObjSh = SfxObjectShell::GetFirst();
                    while( !pObjSh && pTestObjSh )
                    {
                        Reference< XModel > xTestModel = pTestObjSh->GetModel();
                        if( xTestModel == xModel )
                            pObjSh = pTestObjSh;
                        else
                            pTestObjSh = SfxObjectShell::GetNext( *pTestObjSh );
                    }
                }
            }

    #ifdef USE_REGISTER_TRANSFER
            if( pObjSh )
            {
                // Medium registrieren, damit abgebrochen werden kann
                pObjSh->RegisterTransfer( *m_pMedium );

                // Target-Frame uebertragen, damit auch javascript:-URLs
                // "geladen" werden koennen.
                const SfxMedium *pShMedium = pObjSh->GetMedium();
                if( pShMedium )
                    m_pMedium->SetLoadTargetFrame(pShMedium->GetLoadTargetFrame());
            }
            else
            {
                // Keine Object-Shell, aber ein Medium? Dann uebernehmen wir
                // zumindest den Referer.
                if( xModel.is() )
                {
                    ::rtl::OUString sReferer( xModel->getURL() );
                    if( sReferer.getLength() )
                        m_pMedium->SetReferer( OUStringToString(sReferer, CHARSET_SYSTEM) );
                }
            }
    #else
            if( pObjSh )
            {
                // Target-Frame uebertragen, damit auch javascript:-URLs
                // "geladen" werden koennen.
                const SfxMedium *pShMedium = pObjSh->GetMedium();
                if( pShMedium )
                    m_pMedium->SetLoadTargetFrame(pShMedium->GetLoadTargetFrame());
            }

            if( xModel.is() )
            {
                ::rtl::OUString sReferer( xModel->getURL() );
                if( sReferer.getLength() )
                    m_pMedium->SetReferer( sReferer );
            }
    #endif

            // Downloading-Flag auf sal_True setzen. Es werden dann auch
            // Data-Available-Links, wenn wir in den Pending-Staus gelangen.
            m_bDownloading = sal_True;
            m_bProdStarted = sal_False;

            // Download anstossen (Achtung: Kann auch synchron sein).
            m_pMedium->DownLoad(STATIC_LINK(this, OClickableImageBaseModel, DownloadDoneLink));
        }
        else
        {
            if ( ::svt::GraphicAccess::isSupportedURL( rURL )  )
                GetImageProducer()->SetImage( rURL );
            GetImageProducer()->startProduction();
        }
    }

    //------------------------------------------------------------------------------
    void OClickableImageBaseModel::DataAvailable()
    {
        if (!m_bProdStarted)
            StartProduction();

        GetImageProducer()->NewDataAvailable();
    }

    //------------------------------------------------------------------------------
    void OClickableImageBaseModel::DownloadDone()
    {
        DataAvailable();
        m_bDownloading = sal_False;
    }

    //------------------------------------------------------------------------------
    IMPL_STATIC_LINK( OClickableImageBaseModel, DownloadDoneLink, void*, EMPTYARG )
    {
        ::osl::MutexGuard aGuard( pThis->m_aMutex );
        pThis->DownloadDone();
        return 0;
    }

    //------------------------------------------------------------------------------
    IMPL_STATIC_LINK( OClickableImageBaseModel, DataAvailableLink, void*, EMPTYARG )
    {
        ::osl::MutexGuard aGuard( pThis->m_aMutex );
        pThis->DataAvailable();
        return 0;
    }

    //------------------------------------------------------------------------------
    void OClickableImageBaseModel::_propertyChanged( const PropertyChangeEvent& rEvt )
        throw( RuntimeException )
    {
        // Wenn eine URL gesetzt worden ist, muss die noch an den ImageProducer
        // weitergereicht werden.
        ::osl::MutexGuard aGuard(m_aMutex);
        SetURL( getString(rEvt.NewValue) );
    }

    // -----------------------------------------------------------------------------
    Any OClickableImageBaseModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
    {
	    switch (nHandle)
	    {
            case PROPERTY_ID_BUTTONTYPE				: return makeAny( FormButtonType_PUSH );
            case PROPERTY_ID_TARGET_URL				:
            case PROPERTY_ID_TARGET_FRAME			: return makeAny( ::rtl::OUString() );
		    case PROPERTY_ID_DISPATCHURLINTERNAL	: return makeAny( sal_False );
		    default:
			    return OControlModel::getPropertyDefaultByHandle(nHandle);
	    }
    }

    //==================================================================
    // OImageProducerThread_Impl
    //==================================================================
    //------------------------------------------------------------------
    EventObject* OImageProducerThread_Impl::cloneEvent( const EventObject* _pEvt ) const
    {
        return new EventObject( *_pEvt );
    }

    //------------------------------------------------------------------
    void OImageProducerThread_Impl::processEvent( ::cppu::OComponentHelper *pCompImpl,
                                                const EventObject* pEvt,
                                                const Reference<XControl>&,
                                                sal_Bool )
    {
        ((OClickableImageBaseControl *)pCompImpl)->actionPerformed_Impl( sal_True, *(MouseEvent *)pEvt );
    }

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

