/**************************************************************
 *
 * 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)
{
    // order matters: we want to "override" the XImageProducer interface of the aggregate 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
//.........................................................................
