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



#ifndef XMLOFF_FORMS_FORMCELLBINDING
#define XMLOFF_FORMS_FORMCELLBINDING

#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include <com/sun/star/table/CellAddress.hpp>
#include <com/sun/star/table/CellRangeAddress.hpp>
#include <com/sun/star/form/binding/XValueBinding.hpp>
#include <com/sun/star/form/binding/XListEntrySource.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/frame/XModel.hpp>

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

    //========================================================================
    //= FormCellBindingHelper
    //========================================================================
    /** encapsulates functionality related to binding a form control to a spreadsheet cell
    */
    class FormCellBindingHelper
    {
    protected:
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
                    m_xControlModel;    // the model we work for
        ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >
                    m_xDocument;        // the document where the model lives

    public:
        /** determines whether the given control model lives in a spreadsheet document
            <p>If this method returns <FALSE/>, you cannot instantiate a CellBindingHelper with
            this model, since then no of it's functionality will be available.</p>
        */
        static  sal_Bool    livesInSpreadsheetDocument(
                                const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxControlModel
                            );

        /** ctor
            @param _rxControlModel
                the control model which is or will be bound
            @param _rxDocument
                the document. If this is <NULL/>, the document will be obtained from the model
                itself by walkong up the chain of its ancestors.<br/>
                This parameter can be used if the control model is not (yet) part of a document
                model.
        */
        FormCellBindingHelper(
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxControlModel,
            const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _rxDocument
        );

    public:
        /** gets a cell binding for the given address
            @precond
                isCellBindingAllowed returns <TRUE/>
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >
                        createCellBindingFromStringAddress(
                            const ::rtl::OUString& _rAddress,
                            bool _bUseIntegerBinding
                        ) const;

        /** gets a cell range list source binding for the given address
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntrySource >
                        createCellListSourceFromStringAddress( const ::rtl::OUString& _rAddress ) const;

        /** creates a string representation for the given value binding's address

            <p>If the sheet of the bound cell is the same as the sheet which our control belongs
            to, then the sheet name is omitted in the resulting string representation.</p>

            @precond
                The binding is a valid cell binding, or <NULL/>
            @see isCellBinding
        */
        ::rtl::OUString getStringAddressFromCellBinding(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding
                        ) const;

        /** creates a string representation for the given list source's range address

            <p>If the sheet of the cell range which acts as list source is the same as the
            sheet which our control belongs to, then the sheet name is omitted in the
            resulting string representation.</p>

            @precond
                The object is a valid cell range list source, or <NULL/>
            @see isCellRangeListSource
        */
        ::rtl::OUString getStringAddressFromCellListSource(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntrySource >& _rxSource
                        ) const;

        /** returns the current binding of our control model, if any.
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >
                        getCurrentBinding( ) const;

        /** returns the current external list source of the control model, if any
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntrySource >
                        getCurrentListSource( ) const;

        /** sets a new binding for our control model
            @precond
                the control model is bindable (which is implied by <member>isCellBindingAllowed</member>
                returning <TRUE/>)
        */
        void            setBinding(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding
                        );

        /** sets a list source for our control model
            @precond
                the control model is a list sink (which is implied by <member>isListCellRangeAllowed</member>
                returning <TRUE/>)
        */
        void            setListSource(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntrySource >& _rxSource
                        );

        /** checks whether it's possible to bind the control model to a spreadsheet cell
        */
        bool            isCellBindingAllowed( ) const;

        /** checks whether within the given document, it's possible to bind control models to spreadsheet cells
        */
        static bool     isCellBindingAllowed(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _rxDocument
                        );

        /** checks whether it's possible to bind the control model to a range of spreadsheet cells
            supplying the list entries
        */
        bool            isListCellRangeAllowed( ) const;

        /** checks whether within the given document, it's possible to bind the control model to a range of
            spreadsheet cells supplying the list entries
        */
        static bool     isListCellRangeAllowed(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _rxDocument
                        );

        /** checks whether a given binding is a spreadsheet cell binding
        */
        bool            isCellBinding(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding
                        ) const;

        /** checks whether a given binding is a spreadsheet cell binding, exchanging
            integer values
        */
        bool            isCellIntegerBinding(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding
                        ) const;

        /** checks whether a given list source is a spreadsheet cell list source
        */
        bool            isCellRangeListSource(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntrySource >& _rxSource
                        ) const;

    protected:
        /** creates an address object from a string representation of a cell address
        */
        bool            convertStringAddress(
                            const ::rtl::OUString& _rAddressDescription,
                            ::com::sun::star::table::CellAddress& /* [out] */ _rAddress,
                            sal_Int16 _nAssumeSheet = -1
                        ) const;

        /** creates an address range object from a string representation of a cell range address
        */
        bool            convertStringAddress(
                            const ::rtl::OUString& _rAddressDescription,
                            ::com::sun::star::table::CellRangeAddress& /* [out] */ _rAddress
                        ) const;

        /** determines if our document is a spreadsheet document, *and* can supply
            the given service
        */
        bool            isSpreadsheetDocumentWhichSupplies( const ::rtl::OUString& _rService ) const  SAL_THROW(());

        /** determines if our document is a spreadsheet document, *and* can supply
            the given service
        */
        static bool     isSpreadsheetDocumentWhichSupplies(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >& _rxDocument,
                            const ::rtl::OUString& _rService
                        ) SAL_THROW(());

        /** checkes whether a given component supports a given servive
        */
        bool            doesComponentSupport(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxComponent,
                            const ::rtl::OUString& _rService
                        ) const;

        /** uses the document (it's factory interface, respectively) to create a component instance
            @param _rService
                the service name
            @param _rArgumentName
                the name of the single argument to pass during creation. May be empty, in this case
                no arguments are passed
            @param _rArgumentValue
                the value of the instantiation argument. Not evaluated if <arg>_rArgumentName</arg>
                is empty.
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
                        createDocumentDependentInstance(
                            const ::rtl::OUString& _rService,
                            const ::rtl::OUString& _rArgumentName,
                            const ::com::sun::star::uno::Any& _rArgumentValue
                        ) const;

        /** converts an address representation into another one

            @param _rInputProperty
                the input property name for the conversion service
            @param _rInputValue
                the input property value for the conversion service
            @param _rOutputProperty
                the output property name for the conversion service
            @param _rOutputValue
                the output property value for the conversion service
            @param _bIsRange
                if <TRUE/>, the RangeAddressConversion service will be used, else
                the AddressConversion service

            @return
                <TRUE/> if any only if the conversion was successful

            @see com::sun::star::table::CellAddressConversion
            @see com::sun::star::table::CellRangeAddressConversion
        */
        bool            doConvertAddressRepresentations(
                            const ::rtl::OUString& _rInputProperty,
                            const ::com::sun::star::uno::Any& _rInputValue,
                            const ::rtl::OUString& _rOutputProperty,
                                  ::com::sun::star::uno::Any& _rOutputValue,
                            bool _bIsRange
                        ) const SAL_THROW(());
    };

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

#endif // XMLOFF_FORMS_FORMCELLBINDING
