/**************************************************************
 * 
 * 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_xmloff.hxx"
#include "formcellbinding.hxx"
#include <com/sun/star/form/binding/XBindableValue.hpp>
#include <com/sun/star/form/binding/XListEntrySink.hpp>
#include <com/sun/star/form/XGridColumnFactory.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
#include <com/sun/star/table/XCellRange.hpp>
#include <com/sun/star/form/XFormsSupplier.hpp>
#include <com/sun/star/form/XForm.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include "strings.hxx"
#include <osl/diagnose.h>
#include <rtl/logfile.hxx>

#include <functional>
#include <algorithm>

//............................................................................
namespace xmloff
{
//............................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::frame;
    using namespace ::com::sun::star::sheet;
    using namespace ::com::sun::star::container;
    using namespace ::com::sun::star::drawing;
    using namespace ::com::sun::star::table;
    using namespace ::com::sun::star::form;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::form::binding;

namespace
{
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::uno::XInterface;
    using ::com::sun::star::container::XChild;
    using ::com::sun::star::frame::XModel;
    using ::com::sun::star::uno::UNO_QUERY;

	//....................................................................
    template< class TYPE >
    Reference< TYPE > getTypedModelNode( const Reference< XInterface >& _rxModelNode )
    {
        Reference< TYPE > xTypedNode( _rxModelNode, UNO_QUERY );
        if ( xTypedNode.is() )
	        return xTypedNode;
        else
        {
	        Reference< XChild > xChild( _rxModelNode, UNO_QUERY );
	        if ( xChild.is() )
		        return getTypedModelNode< TYPE >( xChild->getParent() );
	        else
		        return NULL;
        }
    }

	//....................................................................
    Reference< XModel > getDocument( const Reference< XInterface >& _rxModelNode )
    {
        return getTypedModelNode< XModel >( _rxModelNode );
    }

    //....................................................................
    struct StringCompare : public ::std::unary_function< ::rtl::OUString, bool >
    {
    private:
        const ::rtl::OUString m_sReference;

    public:
        StringCompare( const ::rtl::OUString& _rReference ) : m_sReference( _rReference ) { }

        inline bool operator()( const ::rtl::OUString& _rCompare )
        {
            return ( _rCompare == m_sReference );
        }
    };
}

//========================================================================
//= FormCellBindingHelper
//========================================================================
//------------------------------------------------------------------------
FormCellBindingHelper::FormCellBindingHelper( const Reference< XPropertySet >& _rxControlModel, const Reference< XModel >& _rxDocument )
    :m_xControlModel( _rxControlModel )
    ,m_xDocument( _rxDocument, UNO_QUERY )
{
    OSL_ENSURE( m_xControlModel.is(), "FormCellBindingHelper::FormCellBindingHelper: invalid control model!" );

    if ( !m_xDocument.is() )
        m_xDocument = m_xDocument.query( getDocument( m_xControlModel ) );
    OSL_ENSURE( m_xDocument.is(), "FormCellBindingHelper::FormCellBindingHelper: Did not find the spreadsheet document!" );
}

//------------------------------------------------------------------------
sal_Bool FormCellBindingHelper::livesInSpreadsheetDocument( const Reference< XPropertySet >& _rxControlModel )
{
    Reference< XSpreadsheetDocument > xDocument( getDocument( _rxControlModel ), UNO_QUERY );
    return xDocument.is();
}

//------------------------------------------------------------------------
bool FormCellBindingHelper::convertStringAddress( const ::rtl::OUString& _rAddressDescription, CellAddress& /* [out] */ _rAddress, sal_Int16 /*_nAssumeSheet*/ ) const
{
    Any aAddress;
    return doConvertAddressRepresentations(
                PROPERTY_FILE_REPRESENTATION,
                makeAny( _rAddressDescription ),
                PROPERTY_ADDRESS,
                aAddress,
                false
           )
       &&  ( aAddress >>= _rAddress );
}

//------------------------------------------------------------------------
bool FormCellBindingHelper::convertStringAddress( const ::rtl::OUString& _rAddressDescription,
                        CellRangeAddress& /* [out] */ _rAddress ) const
{
    Any aAddress;
    return doConvertAddressRepresentations(
                PROPERTY_FILE_REPRESENTATION,
                makeAny( _rAddressDescription ),
                PROPERTY_ADDRESS,
                aAddress,
                true
           )
       &&  ( aAddress >>= _rAddress );
}

//------------------------------------------------------------------------
Reference< XValueBinding > FormCellBindingHelper::createCellBindingFromStringAddress( const ::rtl::OUString& _rAddress, bool _bUseIntegerBinding ) const
{
    Reference< XValueBinding > xBinding;
    if ( !m_xDocument.is() )
        // very bad ...
        return xBinding;

    // get the UNO representation of the address
    CellAddress aAddress;
    if ( !_rAddress.getLength() || !convertStringAddress( _rAddress, aAddress ) )
        return xBinding;

    xBinding = xBinding.query( createDocumentDependentInstance(
        _bUseIntegerBinding ? SERVICE_LISTINDEXCELLBINDING : SERVICE_CELLVALUEBINDING,
        PROPERTY_BOUND_CELL,
        makeAny( aAddress )
    ) );

    return xBinding;
}

//------------------------------------------------------------------------
Reference< XListEntrySource > FormCellBindingHelper::createCellListSourceFromStringAddress( const ::rtl::OUString& _rAddress ) const
{
    Reference< XListEntrySource > xSource;

    CellRangeAddress aRangeAddress;
    if ( !convertStringAddress( _rAddress, aRangeAddress ) )
        return xSource;

    // create a range object for this address
    xSource = xSource.query( createDocumentDependentInstance(
        SERVICE_CELLRANGELISTSOURCE,
        PROPERTY_LIST_CELL_RANGE,
        makeAny( aRangeAddress )
    ) );

    return xSource;
}

//------------------------------------------------------------------------
::rtl::OUString FormCellBindingHelper::getStringAddressFromCellBinding( const Reference< XValueBinding >& _rxBinding ) const
{
    OSL_PRECOND( !_rxBinding.is() || isCellBinding( _rxBinding ), "FormCellBindingHelper::getStringAddressFromCellBinding: this is no cell binding!" );

    ::rtl::OUString sAddress;
    try
    {
        Reference< XPropertySet > xBindingProps( _rxBinding, UNO_QUERY );
        OSL_ENSURE( xBindingProps.is() || !_rxBinding.is(), "FormCellBindingHelper::getStringAddressFromCellBinding: no property set for the binding!" );
        if ( xBindingProps.is() )
        {
            CellAddress aAddress;
            xBindingProps->getPropertyValue( PROPERTY_BOUND_CELL ) >>= aAddress;

            Any aStringAddress;
            doConvertAddressRepresentations( PROPERTY_ADDRESS, makeAny( aAddress ),
                PROPERTY_FILE_REPRESENTATION, aStringAddress, false );

            aStringAddress >>= sAddress;
        }
    }
    catch( const Exception& )
    {
        OSL_ENSURE( sal_False, "FormCellBindingHelper::getStringAddressFromCellBinding: caught an exception!" );
    }

    return sAddress;
}

//------------------------------------------------------------------------
::rtl::OUString FormCellBindingHelper::getStringAddressFromCellListSource( const Reference< XListEntrySource >& _rxSource ) const
{
    OSL_PRECOND( !_rxSource.is() || isCellRangeListSource( _rxSource ), "FormCellBindingHelper::getStringAddressFromCellListSource: this is no cell list source!" );

    ::rtl::OUString sAddress;
    try
    {
        Reference< XPropertySet > xSourceProps( _rxSource, UNO_QUERY );
        OSL_ENSURE( xSourceProps.is() || !_rxSource.is(), "FormCellBindingHelper::getStringAddressFromCellListSource: no property set for the list source!" );
        if ( xSourceProps.is() )
        {
            CellRangeAddress aRangeAddress;
            xSourceProps->getPropertyValue( PROPERTY_LIST_CELL_RANGE ) >>= aRangeAddress;

            Any aStringAddress;
            doConvertAddressRepresentations( PROPERTY_ADDRESS, makeAny( aRangeAddress ),
                PROPERTY_FILE_REPRESENTATION, aStringAddress, true );
            aStringAddress >>= sAddress;
        }
    }
    catch( const Exception& )
    {
        OSL_ENSURE( sal_False, "FormCellBindingHelper::getStringAddressFromCellListSource: caught an exception!" );
    }

    return sAddress;
}

//------------------------------------------------------------------------
bool FormCellBindingHelper::isSpreadsheetDocumentWhichSupplies( const Reference< XSpreadsheetDocument >& _rxDocument, const ::rtl::OUString& _rService ) SAL_THROW(())
{
    bool bYesItIs = false;

    try
    {
        Reference< XServiceInfo > xSI( _rxDocument, UNO_QUERY );
        if ( xSI.is() && xSI->supportsService( SERVICE_SPREADSHEET_DOCUMENT ) )
        {
            Reference< XMultiServiceFactory > xDocumentFactory( _rxDocument, UNO_QUERY );
            OSL_ENSURE( xDocumentFactory.is(), "FormCellBindingHelper::isSpreadsheetDocumentWhichSupplies: spreadsheet document, but no factory?" );

            Sequence< ::rtl::OUString > aAvailableServices;
            if ( xDocumentFactory.is() )
                aAvailableServices = xDocumentFactory->getAvailableServiceNames( );

            const ::rtl::OUString* pFound = ::std::find_if(
                aAvailableServices.getConstArray(),
                aAvailableServices.getConstArray() + aAvailableServices.getLength(),
                StringCompare( _rService )
            );
            if ( pFound - aAvailableServices.getConstArray() < aAvailableServices.getLength() )
            {
                bYesItIs = true;
            }
        }
    }
    catch( const Exception& )
    {
        OSL_ENSURE( sal_False, "FormCellBindingHelper::isSpreadsheetDocumentWhichSupplies: caught an exception!" );
    }

    return bYesItIs;
}

//------------------------------------------------------------------------
bool FormCellBindingHelper::isSpreadsheetDocumentWhichSupplies( const ::rtl::OUString& _rService ) const SAL_THROW(())
{
    return isSpreadsheetDocumentWhichSupplies( m_xDocument, _rService );
}

//------------------------------------------------------------------------
bool FormCellBindingHelper::isListCellRangeAllowed( const Reference< XModel >& _rxDocument )
{
    return isSpreadsheetDocumentWhichSupplies(
        Reference< XSpreadsheetDocument >( _rxDocument, UNO_QUERY ),
        SERVICE_CELLRANGELISTSOURCE
    );
}

//------------------------------------------------------------------------
bool FormCellBindingHelper::isListCellRangeAllowed( ) const
{
    bool bAllow( false );

    Reference< XListEntrySink > xSink( m_xControlModel, UNO_QUERY );
    if ( xSink.is() )
    {
        bAllow = isSpreadsheetDocumentWhichSupplies( SERVICE_CELLRANGELISTSOURCE );
    }

    return bAllow;
}

//------------------------------------------------------------------------
bool FormCellBindingHelper::isCellBindingAllowed( ) const
{
    bool bAllow( false );

    Reference< XBindableValue > xBindable( m_xControlModel, UNO_QUERY );
    if ( xBindable.is() )
    {
        // the control can potentially be bound to an external value
        // Does it live within a Calc document, and is able to supply CellBindings?
        bAllow = isSpreadsheetDocumentWhichSupplies( SERVICE_CELLVALUEBINDING );
    }

    return bAllow;
}

//------------------------------------------------------------------------
bool FormCellBindingHelper::isCellBindingAllowed( const Reference< XModel >& _rxDocument )
{
    return isSpreadsheetDocumentWhichSupplies(
        Reference< XSpreadsheetDocument >( _rxDocument, UNO_QUERY ),
        SERVICE_CELLVALUEBINDING
    );
}

//------------------------------------------------------------------------
bool FormCellBindingHelper::isCellBinding( const Reference< XValueBinding >& _rxBinding ) const
{
    return doesComponentSupport( _rxBinding.get(), SERVICE_CELLVALUEBINDING );
}

//------------------------------------------------------------------------
bool FormCellBindingHelper::isCellIntegerBinding( const Reference< XValueBinding >& _rxBinding ) const
{
    return doesComponentSupport( _rxBinding.get(), SERVICE_LISTINDEXCELLBINDING );
}

//------------------------------------------------------------------------
bool FormCellBindingHelper::isCellRangeListSource( const Reference< XListEntrySource >& _rxSource ) const
{
    return doesComponentSupport( _rxSource.get(), SERVICE_CELLRANGELISTSOURCE );
}

//------------------------------------------------------------------------
bool FormCellBindingHelper::doesComponentSupport( const Reference< XInterface >& _rxComponent, const ::rtl::OUString& _rService ) const
{
    bool bDoes = false;
    Reference< XServiceInfo > xSI( _rxComponent, UNO_QUERY );
    bDoes = xSI.is() && xSI->supportsService( _rService );
    return bDoes;
}

//------------------------------------------------------------------------
Reference< XValueBinding > FormCellBindingHelper::getCurrentBinding( ) const
{
    Reference< XValueBinding > xBinding;
    Reference< XBindableValue > xBindable( m_xControlModel, UNO_QUERY );
    if ( xBindable.is() )
        xBinding = xBindable->getValueBinding();
    return xBinding;
}

//------------------------------------------------------------------------
Reference< XListEntrySource > FormCellBindingHelper::getCurrentListSource( ) const
{
    Reference< XListEntrySource > xSource;
    Reference< XListEntrySink > xSink( m_xControlModel, UNO_QUERY );
    if ( xSink.is() )
        xSource = xSink->getListEntrySource();
    return xSource;
}

//------------------------------------------------------------------------
void FormCellBindingHelper::setBinding( const Reference< XValueBinding >& _rxBinding )
{
    Reference< XBindableValue > xBindable( m_xControlModel, UNO_QUERY );
    OSL_PRECOND( xBindable.is(), "FormCellBindingHelper::setBinding: the object is not bindable!" );
    if ( xBindable.is() )
        xBindable->setValueBinding( _rxBinding );
}

//------------------------------------------------------------------------
void FormCellBindingHelper::setListSource( const Reference< XListEntrySource >& _rxSource )
{
    Reference< XListEntrySink > xSink( m_xControlModel, UNO_QUERY );
    OSL_PRECOND( xSink.is(), "FormCellBindingHelper::setListSource: the object is no list entry sink!" );
    if ( xSink.is() )
        xSink->setListEntrySource( _rxSource );
}

//------------------------------------------------------------------------
Reference< XInterface > FormCellBindingHelper::createDocumentDependentInstance( const ::rtl::OUString& _rService, const ::rtl::OUString& _rArgumentName,
    const Any& _rArgumentValue ) const
{
    Reference< XInterface > xReturn;

    Reference< XMultiServiceFactory > xDocumentFactory( m_xDocument, UNO_QUERY );
    OSL_ENSURE( xDocumentFactory.is(), "FormCellBindingHelper::createDocumentDependentInstance: no document service factory!" );
    if ( xDocumentFactory.is() )
    {
        try
        {
            if ( _rArgumentName.getLength() )
            {
                NamedValue aArg;
                aArg.Name = _rArgumentName;
                aArg.Value = _rArgumentValue;

                Sequence< Any > aArgs( 1 );
                aArgs[ 0 ] <<= aArg;

                xReturn = xDocumentFactory->createInstanceWithArguments( _rService, aArgs );
            }
            else
            {
                xReturn = xDocumentFactory->createInstance( _rService );
            }
        }
        catch ( const Exception& )
        {
            OSL_ENSURE( sal_False, "FormCellBindingHelper::createDocumentDependentInstance: could not create the binding at the document!" );
        }
    }
    return xReturn;
}

//------------------------------------------------------------------------
bool FormCellBindingHelper::doConvertAddressRepresentations( const ::rtl::OUString& _rInputProperty, const Any& _rInputValue,
    const ::rtl::OUString& _rOutputProperty, Any& _rOutputValue, bool _bIsRange ) const SAL_THROW(())
{
    bool bSuccess = false;

    Reference< XPropertySet > xConverter(
        createDocumentDependentInstance(
            _bIsRange ? SERVICE_RANGEADDRESS_CONVERSION : SERVICE_ADDRESS_CONVERSION,
            ::rtl::OUString(),
            Any()
        ),
        UNO_QUERY
    );
    OSL_ENSURE( xConverter.is(), "FormCellBindingHelper::doConvertAddressRepresentations: could not get a converter service!" );
    if ( xConverter.is() )
    {
        try
        {
            xConverter->setPropertyValue( _rInputProperty, _rInputValue );
            _rOutputValue = xConverter->getPropertyValue( _rOutputProperty );
            bSuccess = true;
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "FormCellBindingHelper::doConvertAddressRepresentations: caught an exception!" );
        }
    }

    return bSuccess;
}

//............................................................................
}   // namespace xmloff
//............................................................................
