/**************************************************************
 * 
 * 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_chart2.hxx"
#include "ChartDataWrapper.hxx"
#include "macros.hxx"
#include "DiagramHelper.hxx"
#include "DataSourceHelper.hxx"
#include "servicenames_charttypes.hxx"
#include "ContainerHelper.hxx"
#include "CommonFunctors.hxx"
#include "ChartModelHelper.hxx"
#include "DataSeriesHelper.hxx"
#include "ControllerLockGuard.hxx"
#include "Chart2ModelContact.hxx"
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/chart2/XTitled.hpp>
#include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
#include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
#include <com/sun/star/chart2/data/XDataSource.hpp>
#include <com/sun/star/chart2/XDataSeries.hpp>
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#include <com/sun/star/chart/XChartDocument.hpp>

#include "CharacterProperties.hxx"
#include "LineProperties.hxx"
#include "FillProperties.hxx"

#include <map>
#include <algorithm>
#include <rtl/math.hxx>

using namespace ::com::sun::star;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::rtl::OUString;
using ::osl::MutexGuard;
using ::com::sun::star::chart2::XAnyDescriptionAccess;
using ::com::sun::star::chart::XComplexDescriptionAccess;
using ::com::sun::star::chart::XChartData;
using ::com::sun::star::chart::XChartDataArray;
using ::com::sun::star::chart::XDateCategories;

namespace
{
static const ::rtl::OUString lcl_aServiceName(
    RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.ChartData" ));

uno::Sequence< uno::Sequence< double > > lcl_getNANInsteadDBL_MIN( const uno::Sequence< uno::Sequence< double > >& rData )
{
    uno::Sequence< uno::Sequence< double > > aRet;
    const sal_Int32 nOuterSize = rData.getLength();
    aRet.realloc( nOuterSize );
    for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter )
    {
        sal_Int32 nInnerSize = rData[nOuter].getLength();
        aRet[nOuter].realloc( nInnerSize );
        for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner )
        {
            aRet[nOuter][nInner] = rData[nOuter][nInner];
            double& rValue = aRet[nOuter][nInner];
            if( rValue == DBL_MIN )
                ::rtl::math::setNan( &rValue );
        }
    }
    return aRet;
}

uno::Sequence< uno::Sequence< double > > lcl_getDBL_MINInsteadNAN( const uno::Sequence< uno::Sequence< double > >& rData )
{
    uno::Sequence< uno::Sequence< double > > aRet;
    const sal_Int32 nOuterSize = rData.getLength();
    aRet.realloc( nOuterSize );
    for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter )
    {
        sal_Int32 nInnerSize = rData[nOuter].getLength();
        aRet[nOuter].realloc( nInnerSize );
        for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner )
        {
            aRet[nOuter][nInner] = rData[nOuter][nInner];
            double& rValue = aRet[nOuter][nInner];
            if( ::rtl::math::isNan( rValue ) )
                rValue = DBL_MIN;
        }
    }
    return aRet;
}

} // anonymous namespace

// --------------------------------------------------------------------------------

namespace chart
{
namespace wrapper
{

//--------------------------------------------------------------------------------------

struct lcl_Operator
{
    lcl_Operator()
    {
    }
    virtual ~lcl_Operator()
    {
    }
    virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) = 0;

    virtual bool setsCategories( bool /*bDataInColumns*/ )
    {
        return false;
    }
};

//--------------------------------------------------------------------------

struct lcl_AllOperator : public lcl_Operator
{
    lcl_AllOperator( const Reference< XChartData >& xDataToApply )
        : lcl_Operator()
        , m_xDataToApply( xDataToApply )
    {
    }

    virtual bool setsCategories( bool /*bDataInColumns*/ )
    {
        return true;
    }

    virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
    {
        if( !xDataAccess.is() )
            return;

        Reference< XAnyDescriptionAccess > xNewAny( m_xDataToApply, uno::UNO_QUERY );
        Reference< XComplexDescriptionAccess > xNewComplex( m_xDataToApply, uno::UNO_QUERY );
        if( xNewAny.is() )
        {
            xDataAccess->setData( xNewAny->getData() );
            xDataAccess->setComplexRowDescriptions( xNewAny->getComplexRowDescriptions() );
            xDataAccess->setComplexColumnDescriptions( xNewAny->getComplexColumnDescriptions() );
        }
        else if( xNewComplex.is() )
        {
            xDataAccess->setData( xNewComplex->getData() );
            xDataAccess->setComplexRowDescriptions( xNewComplex->getComplexRowDescriptions() );
            xDataAccess->setComplexColumnDescriptions( xNewComplex->getComplexColumnDescriptions() );
        }
        else
        {
            Reference< XChartDataArray > xNew( m_xDataToApply, uno::UNO_QUERY );
            if( xNew.is() )
            {
                xDataAccess->setData( xNew->getData() );
                xDataAccess->setRowDescriptions( xNew->getRowDescriptions() );
                xDataAccess->setColumnDescriptions( xNew->getColumnDescriptions() );
            }
        }
    }

    Reference< XChartData > m_xDataToApply;
};

//--------------------------------------------------------------------------

struct lcl_DataOperator : public lcl_Operator
{
    lcl_DataOperator( const Sequence< Sequence< double > >& rData )
        : lcl_Operator()
        , m_rData( rData )
    {
    }

    virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
    {
        if( xDataAccess.is() )
            xDataAccess->setData( lcl_getNANInsteadDBL_MIN( m_rData ) );
    }

    const Sequence< Sequence< double > >& m_rData;
};

//--------------------------------------------------------------------------

struct lcl_RowDescriptionsOperator : public lcl_Operator
{
    lcl_RowDescriptionsOperator( const Sequence< OUString >& rRowDescriptions
        , const Reference< chart2::XChartDocument >& xChartDoc )
        : lcl_Operator()
        , m_rRowDescriptions( rRowDescriptions )
        , m_xChartDoc(xChartDoc)
        , m_bDataInColumns(true)
    {
    }

    virtual bool setsCategories( bool bDataInColumns )
    {
        m_bDataInColumns = bDataInColumns;
        return bDataInColumns;
    }

    virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
    {
        if( xDataAccess.is() )
        {
            xDataAccess->setRowDescriptions( m_rRowDescriptions );
            if( m_bDataInColumns )
                DiagramHelper::switchToTextCategories( m_xChartDoc );
        }
    }

    const Sequence< OUString >& m_rRowDescriptions;
    Reference< chart2::XChartDocument > m_xChartDoc;
    bool m_bDataInColumns;
};

//--------------------------------------------------------------------------

struct lcl_ComplexRowDescriptionsOperator : public lcl_Operator
{
    lcl_ComplexRowDescriptionsOperator( const Sequence< Sequence< OUString > >& rComplexRowDescriptions
        , const Reference< chart2::XChartDocument >& xChartDoc )
        : lcl_Operator()
        , m_rComplexRowDescriptions( rComplexRowDescriptions )
        , m_xChartDoc(xChartDoc)
        , m_bDataInColumns(true)
    {
    }

    virtual bool setsCategories( bool bDataInColumns )
    {
        m_bDataInColumns = bDataInColumns;
        return bDataInColumns;
    }

    virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
    {
        if( xDataAccess.is() )
        {
            xDataAccess->setComplexRowDescriptions( m_rComplexRowDescriptions );
            if( m_bDataInColumns )
                DiagramHelper::switchToTextCategories( m_xChartDoc );
        }
    }

    const Sequence< Sequence< OUString > >& m_rComplexRowDescriptions;
    Reference< chart2::XChartDocument > m_xChartDoc;
    bool m_bDataInColumns;
};
//--------------------------------------------------------------------------

struct lcl_AnyRowDescriptionsOperator : public lcl_Operator
{
    lcl_AnyRowDescriptionsOperator( const Sequence< Sequence< uno::Any > >& rAnyRowDescriptions )
        : lcl_Operator()
        , m_rAnyRowDescriptions( rAnyRowDescriptions )
    {
    }

    virtual bool setsCategories( bool bDataInColumns )
    {
        return bDataInColumns;
    }

    virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
    {
        if( xDataAccess.is() )
            xDataAccess->setAnyRowDescriptions( m_rAnyRowDescriptions );
    }

    const Sequence< Sequence< uno::Any > >& m_rAnyRowDescriptions;
};

//--------------------------------------------------------------------------

struct lcl_ColumnDescriptionsOperator : public lcl_Operator
{
    lcl_ColumnDescriptionsOperator( const Sequence< OUString >& rColumnDescriptions
        , const Reference< chart2::XChartDocument >& xChartDoc )
        : lcl_Operator()
        , m_rColumnDescriptions( rColumnDescriptions )
        , m_xChartDoc(xChartDoc)
        , m_bDataInColumns(true)
    {
    }

    virtual bool setsCategories( bool bDataInColumns )
    {
        m_bDataInColumns = bDataInColumns;
        return !bDataInColumns;
    }

    virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
    {
        if( xDataAccess.is() )
        {
            xDataAccess->setColumnDescriptions( m_rColumnDescriptions );
            if( !m_bDataInColumns )
                DiagramHelper::switchToTextCategories( m_xChartDoc );
        }
    }

    const Sequence< OUString >& m_rColumnDescriptions;
    Reference< chart2::XChartDocument > m_xChartDoc;
    bool m_bDataInColumns;
};

//--------------------------------------------------------------------------

struct lcl_ComplexColumnDescriptionsOperator : public lcl_Operator
{
    lcl_ComplexColumnDescriptionsOperator( const Sequence< Sequence< OUString > >& rComplexColumnDescriptions
        , const Reference< chart2::XChartDocument >& xChartDoc )
        : lcl_Operator()
        , m_rComplexColumnDescriptions( rComplexColumnDescriptions )
        , m_xChartDoc(xChartDoc)
        , m_bDataInColumns(true)
    {
    }

    virtual bool setsCategories( bool bDataInColumns )
    {
        m_bDataInColumns = bDataInColumns;
        return !bDataInColumns;
    }

    virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
    {
        if( xDataAccess.is() )
        {
            xDataAccess->setComplexColumnDescriptions( m_rComplexColumnDescriptions );
            if( !m_bDataInColumns )
                DiagramHelper::switchToTextCategories( m_xChartDoc );
        }
    }

    const Sequence< Sequence< OUString > >& m_rComplexColumnDescriptions;
    Reference< chart2::XChartDocument > m_xChartDoc;
    bool m_bDataInColumns;
};

//--------------------------------------------------------------------------

struct lcl_AnyColumnDescriptionsOperator : public lcl_Operator
{
    lcl_AnyColumnDescriptionsOperator( const Sequence< Sequence< uno::Any > >& rAnyColumnDescriptions )
        : lcl_Operator()
        , m_rAnyColumnDescriptions( rAnyColumnDescriptions )
    {
    }

    virtual bool setsCategories( bool bDataInColumns )
    {
        return bDataInColumns;
    }

    virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
    {
        if( xDataAccess.is() )
            xDataAccess->setAnyColumnDescriptions( m_rAnyColumnDescriptions );
    }

    const Sequence< Sequence< uno::Any > >& m_rAnyColumnDescriptions;
};

//--------------------------------------------------------------------------

struct lcl_DateCategoriesOperator : public lcl_Operator
{
    lcl_DateCategoriesOperator( const Sequence< double >& rDates )
        : lcl_Operator()
        , m_rDates( rDates )
    {
    }

    virtual bool setsCategories( bool /*bDataInColumns*/ )
    {
        return true;
    }

    virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
    {
        Reference< XDateCategories > xDateCategories( xDataAccess, uno::UNO_QUERY );
        if( xDateCategories.is() )
            xDateCategories->setDateCategories( m_rDates );
    }

    const Sequence< double >& m_rDates;
};

//--------------------------------------------------------------------------

ChartDataWrapper::ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact ) :
        m_spChart2ModelContact( spChart2ModelContact ),
        m_aEventListenerContainer( m_aMutex )
{
    osl_incrementInterlockedCount( &m_refCount );
    initDataAccess();
    osl_decrementInterlockedCount( &m_refCount );
}

ChartDataWrapper::ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
                                    const Reference< XChartData >& xNewData ) :
        m_spChart2ModelContact( spChart2ModelContact ),
        m_aEventListenerContainer( m_aMutex )
{
    osl_incrementInterlockedCount( &m_refCount );
    lcl_AllOperator aOperator( xNewData );
    applyData( aOperator );
    osl_decrementInterlockedCount( &m_refCount );
}

ChartDataWrapper::~ChartDataWrapper()
{
    // @todo: implement XComponent and call this in dispose().  In the DTOR the
    // ref-count is 0, thus creating a stack reference to this calls the DTOR at
    // the end of the block recursively
//     uno::Reference< uno::XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
//     m_aEventListenerContainer.disposeAndClear( lang::EventObject( xSource ) );
}

// ____ XChartDataArray (read)____
Sequence< Sequence< double > > SAL_CALL ChartDataWrapper::getData()
    throw (uno::RuntimeException)
{
    initDataAccess();
    if( m_xDataAccess.is() )
        return lcl_getDBL_MINInsteadNAN( m_xDataAccess->getData() );
    return Sequence< Sequence< double > >();
}
Sequence< OUString > SAL_CALL ChartDataWrapper::getRowDescriptions()
    throw (uno::RuntimeException)
{
    initDataAccess();
    if( m_xDataAccess.is() )
        return m_xDataAccess->getRowDescriptions();
    return Sequence< OUString >();
}
Sequence< OUString > SAL_CALL ChartDataWrapper::getColumnDescriptions()
    throw (uno::RuntimeException)
{
    initDataAccess();
    if( m_xDataAccess.is() )
        return m_xDataAccess->getColumnDescriptions();
    return Sequence< OUString > ();
}

// ____ XComplexDescriptionAccess (read) ____
Sequence< Sequence< OUString > > SAL_CALL ChartDataWrapper::getComplexRowDescriptions() throw (uno::RuntimeException)
{
    initDataAccess();
    if( m_xDataAccess.is() )
        return m_xDataAccess->getComplexRowDescriptions();
    return Sequence< Sequence< OUString > >();
}
Sequence< Sequence< OUString > > SAL_CALL ChartDataWrapper::getComplexColumnDescriptions() throw (uno::RuntimeException)
{
    initDataAccess();
    if( m_xDataAccess.is() )
        return m_xDataAccess->getComplexColumnDescriptions();
    return Sequence< Sequence< OUString > >();
}

// ____ XAnyDescriptionAccess (read) ____
Sequence< Sequence< uno::Any > > SAL_CALL ChartDataWrapper::getAnyRowDescriptions() throw (uno::RuntimeException)
{
    initDataAccess();
    if( m_xDataAccess.is() )
        return m_xDataAccess->getAnyRowDescriptions();
    return Sequence< Sequence< uno::Any > >();
}
Sequence< Sequence< uno::Any > > SAL_CALL ChartDataWrapper::getAnyColumnDescriptions() throw (uno::RuntimeException)
{
    initDataAccess();
    if( m_xDataAccess.is() )
        return m_xDataAccess->getAnyColumnDescriptions();
    return Sequence< Sequence< uno::Any > >();
}

// ____ XDateCategories (read) ____
Sequence< double > SAL_CALL ChartDataWrapper::getDateCategories() throw (uno::RuntimeException)
{
    initDataAccess();
    Reference< XDateCategories > xDateCategories( m_xDataAccess, uno::UNO_QUERY );
    if( xDateCategories.is() )
        return xDateCategories->getDateCategories();
    return Sequence< double >();
}

// ____ XChartDataArray (write)____
void SAL_CALL ChartDataWrapper::setData( const Sequence< Sequence< double > >& rData )
    throw (uno::RuntimeException)
{
    lcl_DataOperator aOperator( rData );
    applyData( aOperator );
}
void SAL_CALL ChartDataWrapper::setRowDescriptions( const Sequence< OUString >& rRowDescriptions )
    throw (uno::RuntimeException)
{
    lcl_RowDescriptionsOperator aOperator( rRowDescriptions, m_spChart2ModelContact->getChart2Document() );
    applyData( aOperator );
}
void SAL_CALL ChartDataWrapper::setColumnDescriptions( const Sequence< OUString >& rColumnDescriptions )
    throw (uno::RuntimeException)
{
    lcl_ColumnDescriptionsOperator aOperator( rColumnDescriptions, m_spChart2ModelContact->getChart2Document() );
    applyData( aOperator );
}

// ____ XComplexDescriptionAccess (write) ____
void SAL_CALL ChartDataWrapper::setComplexRowDescriptions( const Sequence< Sequence< ::rtl::OUString > >& rRowDescriptions ) throw (uno::RuntimeException)
{
    lcl_ComplexRowDescriptionsOperator aOperator( rRowDescriptions, m_spChart2ModelContact->getChart2Document() );
    applyData( aOperator );
}
void SAL_CALL ChartDataWrapper::setComplexColumnDescriptions( const Sequence< Sequence< ::rtl::OUString > >& rColumnDescriptions ) throw (uno::RuntimeException)
{
    lcl_ComplexColumnDescriptionsOperator aOperator( rColumnDescriptions, m_spChart2ModelContact->getChart2Document() );
    applyData( aOperator );
}

// ____ XAnyDescriptionAccess (write) ____
void SAL_CALL ChartDataWrapper::setAnyRowDescriptions( const Sequence< Sequence< uno::Any > >& rRowDescriptions ) throw (uno::RuntimeException)
{
    lcl_AnyRowDescriptionsOperator aOperator( rRowDescriptions );
    applyData( aOperator );
}
void SAL_CALL ChartDataWrapper::setAnyColumnDescriptions( const Sequence< Sequence< uno::Any > >& rColumnDescriptions ) throw (uno::RuntimeException)
{
    lcl_AnyColumnDescriptionsOperator aOperator( rColumnDescriptions );
    applyData( aOperator );
}

// ____ XDateCategories (write) ____
void SAL_CALL ChartDataWrapper::setDateCategories( const Sequence< double >& rDates ) throw (uno::RuntimeException)
{
    Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
    ControllerLockGuard aCtrlLockGuard( uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ));
    lcl_DateCategoriesOperator aOperator( rDates );
    applyData( aOperator );
    DiagramHelper::switchToDateCategories( xChartDoc );
}

//--------------------------------------------------------------------------------------

// ____ XChartData (base of XChartDataArray) ____
void SAL_CALL ChartDataWrapper::addChartDataChangeEventListener(
    const uno::Reference<
        ::com::sun::star::chart::XChartDataChangeEventListener >& aListener )
    throw (uno::RuntimeException)
{
    m_aEventListenerContainer.addInterface( aListener );
}

void SAL_CALL ChartDataWrapper::removeChartDataChangeEventListener(
    const uno::Reference<
        ::com::sun::star::chart::XChartDataChangeEventListener >& aListener )
    throw (uno::RuntimeException)
{
    m_aEventListenerContainer.removeInterface( aListener );
}

double SAL_CALL ChartDataWrapper::getNotANumber()
    throw (uno::RuntimeException)
{
    return DBL_MIN;
}

sal_Bool SAL_CALL ChartDataWrapper::isNotANumber( double nNumber )
    throw (uno::RuntimeException)
{
    return DBL_MIN == nNumber
        || ::rtl::math::isNan( nNumber )
        || ::rtl::math::isInf( nNumber );
}

// ____ XComponent ____
void SAL_CALL ChartDataWrapper::dispose()
    throw (uno::RuntimeException)
{
    m_aEventListenerContainer.disposeAndClear( lang::EventObject( static_cast< ::cppu::OWeakObject* >( this )));
    m_xDataAccess=0;
}

void SAL_CALL ChartDataWrapper::addEventListener(
    const uno::Reference< lang::XEventListener > & xListener )
    throw (uno::RuntimeException)
{
	m_aEventListenerContainer.addInterface( xListener );
}

void SAL_CALL ChartDataWrapper::removeEventListener(
    const uno::Reference< lang::XEventListener >& aListener )
    throw (uno::RuntimeException)
{
	m_aEventListenerContainer.removeInterface( aListener );
}

// ____ XEventListener ____
void SAL_CALL ChartDataWrapper::disposing( const lang::EventObject& /* Source */ )
    throw (uno::RuntimeException)
{
}

//  ::com::sun::star::chart::ChartDataChangeEvent aEvent;
//  aEvent.Type = chart::ChartDataChangeType_ALL;
//  aEvent.StartColumn = 0;
//  aEvent.EndColumn = 0;
//  aEvent.StartRow = 0;
//  aEvent.EndRow = 0;
void ChartDataWrapper::fireChartDataChangeEvent(
    ::com::sun::star::chart::ChartDataChangeEvent& aEvent )
{
    if( ! m_aEventListenerContainer.getLength() )
        return;

    uno::Reference< uno::XInterface > xSrc( static_cast< cppu::OWeakObject* >( this ));
    OSL_ASSERT( xSrc.is());
    if( xSrc.is() )
        aEvent.Source = xSrc;

    ::cppu::OInterfaceIteratorHelper aIter( m_aEventListenerContainer );

    while( aIter.hasMoreElements() )
    {
        uno::Reference<
            ::com::sun::star::chart::XChartDataChangeEventListener > xListener(
                aIter.next(), uno::UNO_QUERY );
        if( xListener.is() )
            xListener->chartDataChanged( aEvent );
    }
}

// --------------------------------------------------------------------------------

void ChartDataWrapper::switchToInternalDataProvider()
{
    //create an internal data provider that is connected to the model
    Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
    if( xChartDoc.is() )
        xChartDoc->createInternalDataProvider( true /*bCloneExistingData*/ );
    initDataAccess();
}

void ChartDataWrapper::initDataAccess()
{
    Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
    if( !xChartDoc.is() )
        return;
    if( xChartDoc->hasInternalDataProvider() )
        m_xDataAccess = Reference< XAnyDescriptionAccess >( xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW );
    else
    {
        //create a separate "internal data provider" that is not connected to the model
        m_xDataAccess = Reference< XAnyDescriptionAccess >( ChartModelHelper::createInternalDataProvider(
            xChartDoc, false /*bConnectToModel*/ ), uno::UNO_QUERY_THROW );
    }
}

void ChartDataWrapper::applyData( lcl_Operator& rDataOperator )
{
    //bool bSetValues, bool bSetRowDescriptions, bool bSetColumnDescriptions
    Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
    if( !xChartDoc.is() )
        return;
    
    // remember some diagram properties to reset later
    sal_Bool bStacked = sal_False;
    sal_Bool bPercent = sal_False;
    sal_Bool bDeep = sal_False;
    uno::Reference< ::com::sun::star::chart::XChartDocument > xOldDoc( xChartDoc, uno::UNO_QUERY );
    OSL_ASSERT( xOldDoc.is());
    uno::Reference< beans::XPropertySet > xDiaProp( xOldDoc->getDiagram(), uno::UNO_QUERY );
    if( xDiaProp.is())
    {
        xDiaProp->getPropertyValue( C2U("Stacked")) >>= bStacked;
        xDiaProp->getPropertyValue( C2U("Percent")) >>= bPercent;
        xDiaProp->getPropertyValue( C2U("Deep")) >>= bDeep;
    }

    //detect arguments for the new data source
    ::rtl::OUString aRangeString;
    bool bUseColumns = true;
    bool bFirstCellAsLabel = true;
    bool bHasCategories = true;
    uno::Sequence< sal_Int32 > aSequenceMapping;

    DataSourceHelper::detectRangeSegmentation(
        uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ),
        aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories );
    
    if( !bHasCategories && rDataOperator.setsCategories( bUseColumns ) )
        bHasCategories = true;
    
    aRangeString = C2U("all");
    uno::Sequence< beans::PropertyValue > aArguments( DataSourceHelper::createArguments(
            aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories ) );


    // /-- locked controllers
    ControllerLockGuard aCtrlLockGuard( uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ));

    // create and attach new data source
    switchToInternalDataProvider();
    rDataOperator.apply(m_xDataAccess);
    uno::Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
    OSL_ASSERT( xDataProvider.is() );
    if( !xDataProvider.is() )
        return;
    uno::Reference< chart2::data::XDataSource > xSource( xDataProvider->createDataSource( aArguments ) );

    uno::Reference< chart2::XDiagram > xDia( xChartDoc->getFirstDiagram() );
    if( xDia.is() )
        xDia->setDiagramData( xSource, aArguments );

    //correct stacking mode
    if( bStacked || bPercent || bDeep )
    {
        StackMode eStackMode = StackMode_Y_STACKED;
        if( bDeep )
            eStackMode = StackMode_Z_STACKED;
        else if( bPercent )
            eStackMode = StackMode_Y_STACKED_PERCENT;
        DiagramHelper::setStackMode( xDia, eStackMode );
    }

    // notify listeners
    ::com::sun::star::chart::ChartDataChangeEvent aEvent(
        static_cast< ::cppu::OWeakObject* >( this ),
        ::com::sun::star::chart::ChartDataChangeType_ALL, 0, 0, 0, 0 );
    fireChartDataChangeEvent( aEvent );
    // \-- locked controllers
}

// --------------------------------------------------------------------------------

uno::Sequence< ::rtl::OUString > ChartDataWrapper::getSupportedServiceNames_Static()
{
    uno::Sequence< ::rtl::OUString > aServices( 2 );
    aServices[ 0 ] = C2U( "com.sun.star.chart.ChartDataArray" );
    aServices[ 1 ] = C2U( "com.sun.star.chart.ChartData" );

    return aServices;
}

// ================================================================================

// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
APPHELPER_XSERVICEINFO_IMPL( ChartDataWrapper, lcl_aServiceName );

} //  namespace wrapper
} //  namespace chart
