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