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

#include "property.hrc"
#include "frm_resource.hrc"
#include "frm_resource.hxx"
#include "services.hxx"
#include "componenttools.hxx"

#include <svtools/imageresourceaccess.hxx>
#include <unotools/ucblockbytes.hxx>
#include <sfx2/filedlghelper.hxx>
#include <com/sun/star/awt/XPopupMenu.hpp>
#include <com/sun/star/awt/PopupMenuDirection.hpp>
#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
#include <com/sun/star/ui/dialogs/XFilePicker.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/awt/MouseButton.hpp>
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/awt/XDialog.hpp>
#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/io/NotConnectedException.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/graphic/GraphicObject.hpp>
#include <tools/urlobj.hxx>
#include <tools/stream.hxx>
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>
#include <vcl/svapp.hxx>
#include <unotools/streamhelper.hxx>
#include <comphelper/extract.hxx>
#include <comphelper/guarding.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <svl/urihelper.hxx>

#include <memory>

#define ID_OPEN_GRAPHICS			1
#define	ID_CLEAR_GRAPHICS			2

//.........................................................................
namespace frm
{
//.........................................................................
using namespace ::com::sun::star;
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::ui::dialogs;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::graphic;
using namespace ::com::sun::star::frame;

//==============================================================================
//= OImageControlModel
//==============================================================================
namespace
{
    enum ImageStoreType
    {
        ImageStoreBinary,
        ImageStoreLink,

        ImageStoreInvalid
    };

    ImageStoreType lcl_getImageStoreType( const sal_Int32 _nFieldType )
    {
	    // binary/longvarchar types could be used to store images in binary representation
	    if  (   ( _nFieldType == DataType::BINARY )
            ||  ( _nFieldType == DataType::VARBINARY )
		    ||  ( _nFieldType == DataType::LONGVARBINARY )
            ||  ( _nFieldType == DataType::OTHER )
            ||  ( _nFieldType == DataType::OBJECT )
            ||  ( _nFieldType == DataType::BLOB )
		    ||  ( _nFieldType == DataType::LONGVARCHAR )
			||  ( _nFieldType == DataType::CLOB )
            )
		    return ImageStoreBinary;

        // char types could be used to store links to images
        if  (   ( _nFieldType == DataType::CHAR )
            ||  ( _nFieldType == DataType::VARCHAR )
            )
            return ImageStoreLink;

        return ImageStoreInvalid;
    }
}

//==============================================================================
// OImageControlModel
//==============================================================================

//------------------------------------------------------------------------------
InterfaceRef SAL_CALL OImageControlModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
{
	return *(new OImageControlModel(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OImageControlModel::_getTypes()
{
	return concatSequences(
        OBoundControlModel::_getTypes(),
        OImageControlModel_Base::getTypes()
    );
}

DBG_NAME(OImageControlModel)
//------------------------------------------------------------------
OImageControlModel::OImageControlModel(const Reference<XMultiServiceFactory>& _rxFactory)
	:OBoundControlModel( _rxFactory, VCL_CONTROLMODEL_IMAGECONTROL, FRM_SUN_CONTROL_IMAGECONTROL, sal_False, sal_False, sal_False )
					// use the old control name for compytibility reasons
	,m_pImageProducer( NULL )
    ,m_bExternalGraphic( true )
	,m_bReadOnly( sal_False )
    ,m_sImageURL()
    ,m_xGraphicObject()
{
	DBG_CTOR( OImageControlModel, NULL );
	m_nClassId = FormComponentType::IMAGECONTROL;
    initOwnValueProperty( PROPERTY_IMAGE_URL );

	implConstruct();
}

//------------------------------------------------------------------
OImageControlModel::OImageControlModel( const OImageControlModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory )
	:OBoundControlModel( _pOriginal, _rxFactory )
				// use the old control name for compytibility reasons
	,m_pImageProducer( NULL )
    ,m_bExternalGraphic( true )
	,m_bReadOnly( _pOriginal->m_bReadOnly )
    ,m_sImageURL( _pOriginal->m_sImageURL )
    ,m_xGraphicObject( _pOriginal->m_xGraphicObject )
{
	DBG_CTOR( OImageControlModel, NULL );
	implConstruct();

    osl_incrementInterlockedCount( &m_refCount );
    {
        // simulate a propertyChanged event for the ImageURL
        // 2003-05-15 - #109591# - fs@openoffice.org
        ::osl::MutexGuard aGuard( m_aMutex );
        impl_handleNewImageURL_lck( eOther );
    }
    osl_decrementInterlockedCount( &m_refCount );
}

//------------------------------------------------------------------
void OImageControlModel::implConstruct()
{
	m_pImageProducer = new ImageProducer;
	m_xImageProducer = m_pImageProducer;
    m_pImageProducer->SetDoneHdl( LINK( this, OImageControlModel, OnImageImportDone ) );
}

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

	DBG_DTOR(OImageControlModel,NULL);
}

// XCloneable
//------------------------------------------------------------------------------
IMPLEMENT_DEFAULT_CLONING( OImageControlModel )

// XServiceInfo
//------------------------------------------------------------------------------
StringSequence	OImageControlModel::getSupportedServiceNames() throw()
{
	StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
	aSupported.realloc(aSupported.getLength() + 1);

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

//------------------------------------------------------------------------------
Any SAL_CALL OImageControlModel::queryAggregation(const Type& _rType) throw (RuntimeException)
{
    // oder matters: we want to "override" the XImageProducer interface of the aggreate with out
    // own XImageProducer interface, thus we need to query OImageControlModel_Base first
    Any aReturn = OImageControlModel_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 = OBoundControlModel::queryAggregation( _rType );

	return aReturn;
}

//------------------------------------------------------------------------------
sal_Bool OImageControlModel::approveDbColumnType( sal_Int32 _nColumnType )
{
	return ImageStoreInvalid != lcl_getImageStoreType( _nColumnType );
}

//------------------------------------------------------------------------------
void OImageControlModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
{
	switch (nHandle)
	{
        case PROPERTY_ID_READONLY:
            rValue <<= (sal_Bool)m_bReadOnly;
            break;
        case PROPERTY_ID_IMAGE_URL:
            rValue <<= m_sImageURL;
            break;
        case PROPERTY_ID_GRAPHIC:
            rValue <<= m_xGraphicObject.is() ? m_xGraphicObject->getGraphic() : Reference< XGraphic >();
            break;
		default:
			OBoundControlModel::getFastPropertyValue(rValue, nHandle);
	}
}

//------------------------------------------------------------------------------
void OImageControlModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( ::com::sun::star::uno::Exception)
{
	switch (nHandle)
	{
		case PROPERTY_ID_READONLY :
			DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "OImageControlModel::setFastPropertyValue_NoBroadcast : invalid type !" );
			m_bReadOnly = getBOOL(rValue);
			break;

        case PROPERTY_ID_IMAGE_URL:
            OSL_VERIFY( rValue >>= m_sImageURL );
            impl_handleNewImageURL_lck( eOther );
            {
                ControlModelLock aLock( *this );
                    // that's a fake ... onValuePropertyChange expects to receive the only lock to our instance,
                    // but we're already called with our mutex locked ...
                onValuePropertyChange( aLock );
            }
            break;

        case PROPERTY_ID_GRAPHIC:
        {
            Reference< XGraphic > xGraphic;
            OSL_VERIFY( rValue >>= xGraphic );
            if ( !xGraphic.is() )
                m_xGraphicObject.clear();
            else
            {
                m_xGraphicObject = GraphicObject::create( m_aContext.getUNOContext() );
                m_xGraphicObject->setGraphic( xGraphic );
            }

            if ( m_bExternalGraphic )
            {
                // if that's an external graphic, i.e. one which has not been loaded by ourselves in response to a
                // new image URL, then also adjust our ImageURL.
                ::rtl::OUString sNewImageURL;
                if ( m_xGraphicObject.is() )
                {
                    sNewImageURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
				    sNewImageURL = sNewImageURL + m_xGraphicObject->getUniqueID();
                }
                m_sImageURL = sNewImageURL;
                // TODO: speaking strictly, this would need to be notified, since ImageURL is a bound property. However,
                // this method here is called with a locked mutex, so we cannot simply call listeners ...
                // I think the missing notification (and thus clients which potentially cannot observe the change)
                // is less severe than the potential deadlock ...
            }
        }
        break;

        default:
			OBoundControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue);
            break;
	}
}

//------------------------------------------------------------------------------
sal_Bool OImageControlModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
								throw( IllegalArgumentException )
{
	switch (nHandle)
	{
		case PROPERTY_ID_READONLY :
			return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bReadOnly);

        case PROPERTY_ID_IMAGE_URL:
            return tryPropertyValue( rConvertedValue, rOldValue, rValue, m_sImageURL );

        case PROPERTY_ID_GRAPHIC:
        {
            const Reference< XGraphic > xGraphic( getFastPropertyValue( PROPERTY_ID_GRAPHIC ), UNO_QUERY );
            return tryPropertyValue( rConvertedValue, rOldValue, rValue, xGraphic );
        }

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

//------------------------------------------------------------------------------
void OImageControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const
{
	BEGIN_DESCRIBE_PROPERTIES( 4, OBoundControlModel )
        DECL_IFACE_PROP2( GRAPHIC,   XGraphic,        BOUND, TRANSIENT );
        DECL_PROP1      ( IMAGE_URL, ::rtl::OUString, BOUND );
		DECL_BOOL_PROP1 ( READONLY,                   BOUND );
        DECL_PROP1      ( TABINDEX,  sal_Int16,       BOUND );
	END_DESCRIBE_PROPERTIES();
}

//------------------------------------------------------------------------------
void OImageControlModel::describeAggregateProperties( Sequence< Property >& /* [out] */ o_rAggregateProperties ) const
{
    OBoundControlModel::describeAggregateProperties( o_rAggregateProperties );
    // remove ImageULR and Graphic properties, we "overload" them. This is because our aggregate synchronizes those
    // two, but we have an own sychronization mechanism.
    RemoveProperty( o_rAggregateProperties, PROPERTY_IMAGE_URL );
    RemoveProperty( o_rAggregateProperties, PROPERTY_GRAPHIC );
}

//------------------------------------------------------------------------------
::rtl::OUString OImageControlModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
{
	return FRM_COMPONENT_IMAGECONTROL;	// old (non-sun) name for compatibility !
}

//------------------------------------------------------------------------------
void OImageControlModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
{
	// Basisklasse
	OBoundControlModel::write(_rxOutStream);
	// Version
	_rxOutStream->writeShort(0x0003);
	// Name
	_rxOutStream->writeBoolean(m_bReadOnly);
	writeHelpTextCompatibly(_rxOutStream);
	// from version 0x0003 : common properties
	writeCommonProperties(_rxOutStream);
}

//------------------------------------------------------------------------------
void OImageControlModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
{
	OBoundControlModel::read(_rxInStream);

	// Version
	sal_uInt16 nVersion = _rxInStream->readShort();
	switch (nVersion)
	{
		case 0x0001:
			m_bReadOnly = _rxInStream->readBoolean();
			break;
		case 0x0002:
			m_bReadOnly = _rxInStream->readBoolean();
			readHelpTextCompatibly(_rxInStream);
			break;
		case 0x0003:
			m_bReadOnly = _rxInStream->readBoolean();
			readHelpTextCompatibly(_rxInStream);
			readCommonProperties(_rxInStream);
			break;
		default :
			DBG_ERROR("OImageControlModel::read : unknown version !");
			m_bReadOnly = sal_False;
			defaultCommonProperties();
			break;
	}
	// Nach dem Lesen die Defaultwerte anzeigen
	if ( getControlSource().getLength() )
	{	// (not if we don't have a control source - the "State" property acts like it is persistent, then
		::osl::MutexGuard aGuard(m_aMutex);	// resetNoBroadcast expects this mutex guarding
		resetNoBroadcast();
	}
}

//------------------------------------------------------------------------------
sal_Bool OImageControlModel::impl_updateStreamForURL_lck( const ::rtl::OUString& _rURL, ValueChangeInstigator _eInstigator )
{
    // create a stream for the image specified by the URL
    ::std::auto_ptr< SvStream > pImageStream;
    Reference< XInputStream > xImageStream;

    if ( ::svt::GraphicAccess::isSupportedURL( _rURL ) )
    {
        xImageStream = ::svt::GraphicAccess::getImageXStream( getContext().getLegacyServiceFactory(), _rURL );
    }
    else
    {
        pImageStream.reset( ::utl::UcbStreamHelper::CreateStream( _rURL, STREAM_READ ) );
        sal_Bool bSetNull = ( pImageStream.get() == NULL ) || ( ERRCODE_NONE != pImageStream->GetErrorCode() );

        if ( !bSetNull )
        {
	        // get the size of the stream
	        pImageStream->Seek(STREAM_SEEK_TO_END);
	        sal_Int32 nSize = (sal_Int32)pImageStream->Tell();
	        if (pImageStream->GetBufferSize() < 8192)
		        pImageStream->SetBufferSize(8192);
	        pImageStream->Seek(STREAM_SEEK_TO_BEGIN);

            xImageStream = new ::utl::OInputStreamHelper( new SvLockBytes( pImageStream.get(), sal_False ), nSize );
        }
    }

    if ( xImageStream.is() )
    {
        if ( m_xColumnUpdate.is() )
            m_xColumnUpdate->updateBinaryStream( xImageStream, xImageStream->available() );
        else
            setControlValue( makeAny( xImageStream ), _eInstigator );
        xImageStream->closeInput();
        return sal_True;
    }

    return sal_False;
}

//------------------------------------------------------------------------------
sal_Bool OImageControlModel::impl_handleNewImageURL_lck( ValueChangeInstigator _eInstigator )
{
    switch ( lcl_getImageStoreType( getFieldType() ) )
    {
    case ImageStoreBinary:
        if ( impl_updateStreamForURL_lck( m_sImageURL, _eInstigator ) )
            return sal_True;
        break;

    case ImageStoreLink:
    {
        ::rtl::OUString sCommitURL( m_sImageURL );
        if ( m_sDocumentURL.getLength() )
            sCommitURL = URIHelper::simpleNormalizedMakeRelative( m_sDocumentURL, sCommitURL );
        OSL_ENSURE( m_xColumnUpdate.is(), "OImageControlModel::impl_handleNewImageURL_lck: no bound field, but ImageStoreLink?!" );
        if ( m_xColumnUpdate.is() )
        {
            m_xColumnUpdate->updateString( sCommitURL );
            return sal_True;
        }
    }
    break;

    case ImageStoreInvalid:
        OSL_ENSURE( false, "OImageControlModel::impl_handleNewImageURL_lck: image storage type type!" );
        break;
    }

    // if we're here, then the above code was unable to update our field/control from the given URL
    // => fall back to NULL/VOID
	if ( m_xColumnUpdate.is() )
        m_xColumnUpdate->updateNull();
    else
        setControlValue( Any(), _eInstigator );

    return sal_True;
}

//------------------------------------------------------------------------------
sal_Bool OImageControlModel::commitControlValueToDbColumn( bool _bPostReset )
{
    if ( _bPostReset )
    {
        // since this is a "commit after reset", we can simply update the column
        // with null - this is our "default" which we were just reset to
        if ( m_xColumnUpdate.is() )
            m_xColumnUpdate->updateNull();
    }
    else
    {
	    ::osl::MutexGuard aGuard(m_aMutex);
        return impl_handleNewImageURL_lck( eDbColumnBinding );
    }

    return sal_True;
}

//------------------------------------------------------------------------------
namespace
{
    bool lcl_isValidDocumentURL( const ::rtl::OUString& _rDocURL )
    {
        return ( _rDocURL.getLength() && !_rDocURL.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:object" ) ) );
    }
}

//------------------------------------------------------------------------------
void OImageControlModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
{
    OBoundControlModel::onConnectedDbColumn( _rxForm );

    try
    {
        Reference< XModel > xDocument( getXModel( *this ) );
        if ( xDocument.is() )
        {
            m_sDocumentURL = xDocument->getURL();
            if ( !lcl_isValidDocumentURL( m_sDocumentURL ) )
            {
                Reference< XChild > xAsChild( xDocument, UNO_QUERY );
                while ( xAsChild.is() && !lcl_isValidDocumentURL( m_sDocumentURL ) )
                {
                    xDocument.set( xAsChild->getParent(), UNO_QUERY );
                    if ( xDocument.is() )
                        m_sDocumentURL = xDocument->getURL();
                    xAsChild.set( xDocument, UNO_QUERY );
                }
            }
        }
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
}

//------------------------------------------------------------------------------
void OImageControlModel::onDisconnectedDbColumn()
{
    OBoundControlModel::onDisconnectedDbColumn();

    m_sDocumentURL = ::rtl::OUString();
}

//------------------------------------------------------------------------------
Any OImageControlModel::translateDbColumnToControlValue()
{
    switch ( lcl_getImageStoreType( getFieldType() ) )
    {
    case ImageStoreBinary: 
    {
        Reference< XInputStream > xImageStream( m_xColumn->getBinaryStream() );
        if ( m_xColumn->wasNull() )
            xImageStream.clear();
        return makeAny( xImageStream );
    }
    case ImageStoreLink:
    {
        ::rtl::OUString sImageLink( m_xColumn->getString() );
        if ( m_sDocumentURL.getLength() )
            sImageLink = INetURLObject::GetAbsURL( m_sDocumentURL, sImageLink );
        return makeAny( sImageLink );
    }
    case ImageStoreInvalid:
        OSL_ENSURE( false, "OImageControlModel::translateDbColumnToControlValue: invalid field type!" );
        break;
    }
    return Any();
}

//------------------------------------------------------------------------------
Any OImageControlModel::getControlValue( ) const
{
    return makeAny( m_sImageURL );
}

//------------------------------------------------------------------------------
void OImageControlModel::doSetControlValue( const Any& _rValue )
{
    DBG_ASSERT( GetImageProducer() && m_xImageProducer.is(), "OImageControlModel::doSetControlValue: no image producer!" );
    if ( !GetImageProducer() || !m_xImageProducer.is() )
        return;

    bool bStartProduction = false;
    switch ( lcl_getImageStoreType( getFieldType() ) )
    {
    case ImageStoreBinary:
    {
        // give the image producer the stream
        Reference< XInputStream > xInStream;
        _rValue >>= xInStream;
        GetImageProducer()->setImage( xInStream );
        bStartProduction = true;
    }
    break; 

    case ImageStoreLink:
    {
        ::rtl::OUString sImageURL;
        _rValue >>= sImageURL;
        GetImageProducer()->SetImage( sImageURL );
        bStartProduction = true;
    }
    break;

    case ImageStoreInvalid:
        OSL_ENSURE( false, "OImageControlModel::doSetControlValue: invalid field type!" );
        break;

    }   // switch ( lcl_getImageStoreType( getFieldType() ) )

    if ( bStartProduction )
    {
        // start production
        Reference< XImageProducer > xProducer = m_xImageProducer;
        {
            // release our mutex once (it's acquired in the calling method!), as starting the image production may
	        // result in the locking of the solar mutex (unfortunally the default implementation of our aggregate,
	        // VCLXImageControl, does this locking)
	        // FS - 74438 - 30.03.00
	        MutexRelease aRelease(m_aMutex);
	        xProducer->startProduction();
        }
    }
}

// OComponentHelper
//------------------------------------------------------------------
void SAL_CALL OImageControlModel::disposing()
{
	OBoundControlModel::disposing();
}

//------------------------------------------------------------------------------
void OImageControlModel::resetNoBroadcast()
{
    if ( hasField() )          // only reset when we are connected to a column
        OBoundControlModel::resetNoBroadcast( );
}

//--------------------------------------------------------------------
Reference< XImageProducer > SAL_CALL OImageControlModel::getImageProducer() throw ( RuntimeException)
{
    return this;
}

//--------------------------------------------------------------------
void SAL_CALL OImageControlModel::addConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
{
    GetImageProducer()->addConsumer( _rxConsumer );
}

//--------------------------------------------------------------------
void SAL_CALL OImageControlModel::removeConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
{
    GetImageProducer()->removeConsumer( _rxConsumer );
}

//--------------------------------------------------------------------
void SAL_CALL OImageControlModel::startProduction(  ) throw (RuntimeException)
{
    GetImageProducer()->startProduction();
}

//------------------------------------------------------------------------------
IMPL_LINK( OImageControlModel, OnImageImportDone, ::Graphic*, i_pGraphic )
{
    const Reference< XGraphic > xGraphic( i_pGraphic != NULL ? Image( i_pGraphic->GetBitmapEx() ).GetXGraphic() : NULL );
    m_bExternalGraphic = false;
    try
    {
        setPropertyValue( PROPERTY_GRAPHIC, makeAny( xGraphic ) );
    }
    catch ( const Exception& )
    {
        DBG_UNHANDLED_EXCEPTION();
    }
    m_bExternalGraphic = true;
    return 1L;
}

//==================================================================
// OImageControlControl
//==================================================================

//------------------------------------------------------------------
InterfaceRef SAL_CALL OImageControlControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
{
	return *(new OImageControlControl(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OImageControlControl::_getTypes()
{
    return concatSequences(
        OBoundControl::_getTypes(),
        OImageControlControl_Base::getTypes()
    );
}

//------------------------------------------------------------------------------
OImageControlControl::OImageControlControl(const Reference<XMultiServiceFactory>& _rxFactory)
	:OBoundControl(_rxFactory, VCL_CONTROL_IMAGECONTROL)
    ,m_aModifyListeners( m_aMutex )
{
	increment(m_refCount);
	{
		// als Focus- und MouseListener anmelden
		Reference< XWindow > xComp;
		query_aggregation( m_xAggregate, xComp );
		if ( xComp.is() )
			xComp->addMouseListener( this );
	}
	decrement(m_refCount);
}

//------------------------------------------------------------------------------
Any SAL_CALL OImageControlControl::queryAggregation(const Type& _rType) throw (RuntimeException)
{
    Any aReturn = OBoundControl::queryAggregation( _rType );
    if ( !aReturn.hasValue() )
        aReturn = ::cppu::queryInterface(
            _rType,
            static_cast< XMouseListener* >( this ),
            static_cast< XModifyBroadcaster* >( this )
        );

    return aReturn;
}

//------------------------------------------------------------------------------
StringSequence	OImageControlControl::getSupportedServiceNames() throw()
{
	StringSequence aSupported = OBoundControl::getSupportedServiceNames();
	aSupported.realloc(aSupported.getLength() + 1);

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

//------------------------------------------------------------------------------
void SAL_CALL OImageControlControl::addModifyListener( const Reference< XModifyListener >& _Listener ) throw (RuntimeException)
{
    m_aModifyListeners.addInterface( _Listener );
}

//------------------------------------------------------------------------------
void SAL_CALL OImageControlControl::removeModifyListener( const Reference< XModifyListener >& _Listener ) throw (RuntimeException)
{
    m_aModifyListeners.removeInterface( _Listener );
}

//------------------------------------------------------------------------------
void SAL_CALL OImageControlControl::disposing()
{
    EventObject aEvent( *this );
	m_aModifyListeners.disposeAndClear( aEvent );

    OBoundControl::disposing();
}

//------------------------------------------------------------------------------
void SAL_CALL OImageControlControl::disposing( const EventObject& _Event ) throw(RuntimeException)
{
    OBoundControl::disposing( _Event );
}

//------------------------------------------------------------------------------
void OImageControlControl::implClearGraphics( sal_Bool _bForce )
{
	Reference< XPropertySet > xSet( getModel(), UNO_QUERY );
	if ( xSet.is() )
    {
        if ( _bForce )
        {
            ::rtl::OUString sOldImageURL;
            xSet->getPropertyValue( PROPERTY_IMAGE_URL ) >>= sOldImageURL;

            if ( !sOldImageURL.getLength() )
                // the ImageURL is already empty, so simply setting a new empty one would not suffice
                // (since it would be ignored)
                xSet->setPropertyValue( PROPERTY_IMAGE_URL, makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:emptyImage" ) ) ) );
                    // (the concrete URL we're passing here doens't matter. It's important that
                    // the model cannot resolve it to a a valid resource describing an image stream
        }

        xSet->setPropertyValue( PROPERTY_IMAGE_URL, makeAny( ::rtl::OUString() ) );
    }
}

//------------------------------------------------------------------------------
bool OImageControlControl::implInsertGraphics()
{
	Reference< XPropertySet > xSet( getModel(), UNO_QUERY );
	if ( !xSet.is() )
		return false;

	::rtl::OUString sTitle = FRM_RES_STRING(RID_STR_IMPORT_GRAPHIC);
	// build some arguments for the upcoming dialog
	try
	{
		::sfx2::FileDialogHelper aDialog( TemplateDescription::FILEOPEN_LINK_PREVIEW, SFXWB_GRAPHIC );
		aDialog.SetTitle( sTitle );

		Reference< XFilePickerControlAccess > xController( aDialog.GetFilePicker(), UNO_QUERY_THROW );
		xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, ::cppu::bool2any(sal_True));

		Reference<XPropertySet> xBoundField;
		if ( hasProperty( PROPERTY_BOUNDFIELD, xSet ) )
			xSet->getPropertyValue( PROPERTY_BOUNDFIELD ) >>= xBoundField;
		sal_Bool bHasField = xBoundField.is();

        // if the control is bound to a DB field, then it's not possible to decide whether or not to link
		xController->enableControl(ExtendedFilePickerElementIds::CHECKBOX_LINK, !bHasField );

        // if the control is bound to a DB field, then linking of the image depends on the type of the field
        sal_Bool bImageIsLinked = sal_True;
        if ( bHasField )
        {
            sal_Int32 nFieldType = DataType::OTHER;
            OSL_VERIFY( xBoundField->getPropertyValue( PROPERTY_FIELDTYPE ) >>= nFieldType );
            bImageIsLinked = ( lcl_getImageStoreType( nFieldType ) == ImageStoreLink );
        }
		xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, makeAny( bImageIsLinked ) );

		if ( ERRCODE_NONE == aDialog.Execute() )
		{
			// reset the url property in case it already has the value we're about to set - in this case
			// our propertyChanged would not get called without this.
			implClearGraphics( sal_False );
			sal_Bool bIsLink = sal_False;
			xController->getValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0) >>= bIsLink;
            // Force bIsLink to be sal_True if we're bound to a field. Though we initialized the file picker with IsLink=TRUE
            // in this case, and disabled the respective control, there might be picker implementations which do not
            // respect this, and return IsLink=FALSE here. In this case, "normalize" the flag.
            // #i112659# / 2010-08-26 / frank.schoenheit@oracle.com
            bIsLink |= bHasField;
			if ( !bIsLink )
			{
				Graphic aGraphic;
				aDialog.GetGraphic( aGraphic );
 				xSet->setPropertyValue( PROPERTY_GRAPHIC, makeAny( aGraphic.GetXGraphic() ) );
			}
			else
				xSet->setPropertyValue( PROPERTY_IMAGE_URL, makeAny( ::rtl::OUString( aDialog.GetPath() ) ) );

            return true;
		}
	}
	catch(Exception&)
	{
		DBG_ERROR("OImageControlControl::implInsertGraphics: caught an exception while attempting to execute the FilePicker!");
	}
    return false;
}

//------------------------------------------------------------------------------
bool OImageControlControl::impl_isEmptyGraphics_nothrow() const
{
    bool bIsEmpty = true;

    try
    {
        Reference< XPropertySet > xModelProps( const_cast< OImageControlControl* >( this )->getModel(), UNO_QUERY_THROW );
        Reference< XGraphic > xGraphic;
        OSL_VERIFY( xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Graphic" ) ) ) >>= xGraphic );
        bIsEmpty = !xGraphic.is();
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }

    return bIsEmpty;
}

// MouseListener
//------------------------------------------------------------------------------
void OImageControlControl::mousePressed(const ::com::sun::star::awt::MouseEvent& e) throw ( ::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );

	if (e.Buttons != MouseButton::LEFT)
		return;

    bool bModified = false;
	// is this a request for a context menu?
	if ( e.PopupTrigger )
	{
		Reference< XPopupMenu > xMenu( m_aContext.createComponent( "com.sun.star.awt.PopupMenu" ), UNO_QUERY );
		DBG_ASSERT( xMenu.is(), "OImageControlControl::mousePressed: could not create a popup menu!" );

		Reference< XWindowPeer > xWindowPeer = getPeer();
		DBG_ASSERT( xWindowPeer.is(), "OImageControlControl::mousePressed: no window!" );

		if ( xMenu.is() && xWindowPeer.is() )
		{
			xMenu->insertItem( ID_OPEN_GRAPHICS, FRM_RES_STRING( RID_STR_OPEN_GRAPHICS ), 0, 0 );
			xMenu->insertItem( ID_CLEAR_GRAPHICS, FRM_RES_STRING( RID_STR_CLEAR_GRAPHICS ), 0, 1 );

			// check if the ImageURL is empty
            if ( impl_isEmptyGraphics_nothrow() )
				xMenu->enableItem( ID_CLEAR_GRAPHICS, sal_False );

			awt::Rectangle aRect( e.X, e.Y, 0, 0 );
			if ( ( e.X < 0 ) || ( e.Y < 0 ) )
			{	// context menu triggered by keyboard
				// position it in the center of the control
				// 102205 - 16.08.2002 - fs@openoffice.org
				Reference< XWindow > xWindow( static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY );
				OSL_ENSURE( xWindow.is(), "OImageControlControl::mousePressed: me not a window? How this?" );
				if ( xWindow.is() )
				{
					awt::Rectangle aPosSize = xWindow->getPosSize();
					aRect.X = aPosSize.Width / 2;
					aRect.Y = aPosSize.Height / 2;
				}
			}

			const sal_Int16 nResult = xMenu->execute( xWindowPeer, aRect, PopupMenuDirection::EXECUTE_DEFAULT );

			switch ( nResult )
			{
			case ID_OPEN_GRAPHICS:
				implInsertGraphics();
                bModified = true;
				break;

			case ID_CLEAR_GRAPHICS:
				implClearGraphics( sal_True );
                bModified = true;
				break;
			}
		}
	}
	else
	{
		//////////////////////////////////////////////////////////////////////
		// Doppelclick
		if (e.ClickCount == 2)
		{

			Reference<XPropertySet>  xSet(getModel(), UNO_QUERY);
			if (!xSet.is())
				return;

			// wenn Control nicht gebunden ist, kein Dialog (da die zu schickende URL hinterher sowieso
			// versanden wuerde)
			// FS - #64946# - 19.04.99
			Reference<XPropertySet> xBoundField;
			if (hasProperty(PROPERTY_BOUNDFIELD, xSet))
				::cppu::extractInterface(xBoundField, xSet->getPropertyValue(PROPERTY_BOUNDFIELD));
			if (!xBoundField.is())
			{
				// but only if our IMAGE_URL property is handled as if it is transient, which is equivalent to
				// an empty control source
				if (!hasProperty(PROPERTY_CONTROLSOURCE, xSet) || (::comphelper::getString(xSet->getPropertyValue(PROPERTY_CONTROLSOURCE)).getLength() != 0))
					return;
			}

			sal_Bool bReadOnly = false;
			xSet->getPropertyValue(PROPERTY_READONLY) >>= bReadOnly;
			if (bReadOnly)
				return;

			if ( implInsertGraphics() )
                bModified = true;
		}
	}

    if ( bModified )
    {
        EventObject aEvent( *this );
        m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvent );
    }
}

//------------------------------------------------------------------------------
void SAL_CALL OImageControlControl::mouseReleased(const awt::MouseEvent& /*e*/) throw ( RuntimeException )
{
}

//------------------------------------------------------------------------------
void SAL_CALL OImageControlControl::mouseEntered(const awt::MouseEvent& /*e*/) throw ( RuntimeException )
{
}

//------------------------------------------------------------------------------
void SAL_CALL OImageControlControl::mouseExited(const awt::MouseEvent& /*e*/) throw ( RuntimeException )
{
}

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

