/**************************************************************
 *
 * 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 "DialogModel.hxx"
#include "RangeSelectionHelper.hxx"
#include "PropertyHelper.hxx"
#include "DataSeriesHelper.hxx"
#include "DataSourceHelper.hxx"
#include "DiagramHelper.hxx"
#include "macros.hxx"
#include "Strings.hrc"
#include "ResId.hxx"
#include "ContainerHelper.hxx"
#include "CommonFunctors.hxx"
#include "ControllerLockGuard.hxx"
#include "ChartTypeHelper.hxx"
#include "ThreeDHelper.hxx"

#include <com/sun/star/util/XCloneable.hpp>
#include <com/sun/star/chart2/AxisType.hpp>
#include <com/sun/star/chart2/XTitled.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
#include <com/sun/star/chart2/data/XDataSink.hpp>

#include <tools/string.hxx>

#include <utility>
#include <algorithm>
#include <iterator>
#include <functional>
#include <numeric>

using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;
using namespace ::chart::ContainerHelper;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::rtl::OUString;

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

namespace
{
const OUString lcl_aLabelRole( RTL_CONSTASCII_USTRINGPARAM( "label" ));

struct lcl_ChartTypeToSeriesCnt : ::std::unary_function<
        Reference< XChartType >, Reference< XDataSeriesContainer > >
{
    Reference< XDataSeriesContainer > operator() (
        const Reference< XChartType > & xChartType )
    {
        return Reference< XDataSeriesContainer >::query( xChartType );
    }
};

OUString lcl_ConvertRole( const OUString & rRoleString, bool bFromInternalToUI )
{
    OUString aResult( rRoleString );

    typedef ::std::map< OUString, OUString > tTranslationMap;
    static tTranslationMap aTranslationMap;

    if( aTranslationMap.size() == 0 )
    {
        aTranslationMap[ C2U( "categories" ) ] =   OUString( String( ::chart::SchResId( STR_DATA_ROLE_CATEGORIES )));
        aTranslationMap[ C2U( "error-bars-x" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR )));
        aTranslationMap[ C2U( "error-bars-x-positive" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR_POSITIVE )));
        aTranslationMap[ C2U( "error-bars-x-negative" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR_NEGATIVE )));
        aTranslationMap[ C2U( "error-bars-y" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR )));
        aTranslationMap[ C2U( "error-bars-y-positive" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_POSITIVE )));
        aTranslationMap[ C2U( "error-bars-y-negative" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_NEGATIVE )));
        aTranslationMap[ C2U( "label" ) ] =        OUString( String( ::chart::SchResId( STR_DATA_ROLE_LABEL )));
        aTranslationMap[ C2U( "values-first" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_FIRST )));
        aTranslationMap[ C2U( "values-last" ) ] =  OUString( String( ::chart::SchResId( STR_DATA_ROLE_LAST )));
        aTranslationMap[ C2U( "values-max" ) ] =   OUString( String( ::chart::SchResId( STR_DATA_ROLE_MAX )));
        aTranslationMap[ C2U( "values-min" ) ] =   OUString( String( ::chart::SchResId( STR_DATA_ROLE_MIN )));
        aTranslationMap[ C2U( "values-x" ) ] =     OUString( String( ::chart::SchResId( STR_DATA_ROLE_X )));
        aTranslationMap[ C2U( "values-y" ) ] =     OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y )));
        aTranslationMap[ C2U( "values-size" ) ] =  OUString( String( ::chart::SchResId( STR_DATA_ROLE_SIZE )));
    }

    if( bFromInternalToUI )
    {
        tTranslationMap::const_iterator aIt( aTranslationMap.find( rRoleString ));
        if( aIt != aTranslationMap.end())
        {
            aResult = (*aIt).second;
        }
    }
    else
    {
        tTranslationMap::const_iterator aIt(
            ::std::find_if( aTranslationMap.begin(), aTranslationMap.end(),
                            ::std::compose1( ::std::bind2nd(
                                                 ::std::equal_to< tTranslationMap::mapped_type >(),
                                                 rRoleString ),
                                             ::std::select2nd< tTranslationMap::value_type >())));

        if( aIt != aTranslationMap.end())
            aResult = (*aIt).first;
    }

    return aResult;
}

typedef ::std::map< ::rtl::OUString, sal_Int32 > lcl_tRoleIndexMap;

void lcl_createRoleIndexMap( lcl_tRoleIndexMap & rOutMap )
{
    rOutMap.clear();
    sal_Int32 nIndex = 0;

    rOutMap[ C2U( "label" ) ] =                 ++nIndex;
    rOutMap[ C2U( "categories" ) ] =            ++nIndex;
    rOutMap[ C2U( "values-x" ) ] =              ++nIndex;
    rOutMap[ C2U( "values-y" ) ] =              ++nIndex;
    rOutMap[ C2U( "error-bars-x" ) ] =          ++nIndex;
    rOutMap[ C2U( "error-bars-x-positive" ) ] = ++nIndex;
    rOutMap[ C2U( "error-bars-x-negative" ) ] = ++nIndex;
    rOutMap[ C2U( "error-bars-y" ) ] =          ++nIndex;
    rOutMap[ C2U( "error-bars-y-positive" ) ] = ++nIndex;
    rOutMap[ C2U( "error-bars-y-negative" ) ] = ++nIndex;
    rOutMap[ C2U( "values-first" ) ] =          ++nIndex;
    rOutMap[ C2U( "values-min" ) ] =            ++nIndex;
    rOutMap[ C2U( "values-max" ) ] =            ++nIndex;
    rOutMap[ C2U( "values-last" ) ] =           ++nIndex;
    rOutMap[ C2U( "values-size" ) ] =           ++nIndex;
}

struct lcl_DataSeriesContainerAppend : public
    ::std::iterator< ::std::output_iterator_tag, Reference< XDataSeriesContainer > >
{
    typedef ::std::vector< ::chart::DialogModel::tSeriesWithChartTypeByName > tContainerType;

    explicit lcl_DataSeriesContainerAppend( tContainerType & rCnt )
            : m_rDestCnt( rCnt )
    {}

    lcl_DataSeriesContainerAppend & operator= ( const value_type & xVal )
    {
        try
        {
            if( xVal.is())
            {
                Sequence< Reference< XDataSeries > > aSeq( xVal->getDataSeries());
                OUString aRole( RTL_CONSTASCII_USTRINGPARAM("values-y"));
                Reference< XChartType > xCT( xVal, uno::UNO_QUERY );
                if( xCT.is())
                    aRole = xCT->getRoleOfSequenceForSeriesLabel();
                for( sal_Int32 nI = 0; nI < aSeq.getLength(); ++ nI )
                {
                    m_rDestCnt.push_back(
                        ::chart::DialogModel::tSeriesWithChartTypeByName(
                            ::chart::DataSeriesHelper::getDataSeriesLabel( aSeq[nI], aRole ),
                            ::std::make_pair( aSeq[nI], xCT )));
                }
            }
        }
        catch( uno::Exception & ex )
        {
            ASSERT_EXCEPTION( ex );
        }
        return *this;
    }

    lcl_DataSeriesContainerAppend & operator* ()     { return *this; }
    lcl_DataSeriesContainerAppend & operator++ ()    { return *this; }
    lcl_DataSeriesContainerAppend & operator++ (int) { return *this; }

private:
    tContainerType & m_rDestCnt;
};

struct lcl_RolesWithRangeAppend : public
    ::std::iterator< ::std::output_iterator_tag, Reference< data::XLabeledDataSequence > >
{
    typedef ::chart::DialogModel::tRolesWithRanges tContainerType;

    explicit lcl_RolesWithRangeAppend( tContainerType & rCnt,
                                       const ::rtl::OUString & aLabelRole )
            : m_rDestCnt( rCnt ),
              m_aRoleForLabelSeq( aLabelRole )
    {}

    lcl_RolesWithRangeAppend & operator= ( const value_type & xVal )
    {
        try
        {
            if( xVal.is())
            {
                // data sequence
                Reference< data::XDataSequence > xSeq( xVal->getValues());
                if( xSeq.is())
                {
                    OUString aRole;
                    Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW );
                    if( xProp->getPropertyValue( C2U("Role")) >>= aRole )
                    {
                        m_rDestCnt.insert(
                            tContainerType::value_type(
                                aRole, xSeq->getSourceRangeRepresentation()));
                        // label
                        if( aRole.equals( m_aRoleForLabelSeq ))
                        {
                            Reference< data::XDataSequence > xLabelSeq( xVal->getLabel());
                            if( xLabelSeq.is())
                            {
                                m_rDestCnt.insert(
                                    tContainerType::value_type(
                                        lcl_aLabelRole, xLabelSeq->getSourceRangeRepresentation()));
                            }
                        }
                    }
                }
            }
        }
        catch( uno::Exception & ex )
        {
            ASSERT_EXCEPTION( ex );
        }
        return *this;
    }

    lcl_RolesWithRangeAppend & operator* ()     { return *this; }
    lcl_RolesWithRangeAppend & operator++ ()    { return *this; }
    lcl_RolesWithRangeAppend & operator++ (int) { return *this; }

private:
    tContainerType & m_rDestCnt;
    OUString m_aRoleForLabelSeq;
};

void lcl_SetSequenceRole(
    const Reference< data::XDataSequence > & xSeq,
    const OUString & rRole )
{
    Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY );
    if( xProp.is())
        xProp->setPropertyValue( C2U("Role"), uno::makeAny( rRole ));
}

Reference< XDataSeries > lcl_CreateNewSeries(
    const Reference< uno::XComponentContext > & xContext,
    const Reference< XChartType > & xChartType,
    sal_Int32 nNewSeriesIndex,
    sal_Int32 nTotalNumberOfSeriesInCTGroup,
    const Reference< XDiagram > & xDiagram,
    const Reference< XChartTypeTemplate > & xTemplate,
    bool bCreateDataCachedSequences )
{
    // create plain series
    Reference< XDataSeries > xResult(
        xContext->getServiceManager()->createInstanceWithContext(
            C2U( "com.sun.star.chart2.DataSeries" ),
            xContext ), uno::UNO_QUERY );
    if( xTemplate.is())
    {
        Reference< beans::XPropertySet > xResultProp( xResult, uno::UNO_QUERY );
        if( xResultProp.is())
        {
            // @deprecated: correct default color should be found by view
            // without setting it as hard attribute
            Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
            if( xColorScheme.is())
                xResultProp->setPropertyValue(
                    C2U("Color"), uno::makeAny( xColorScheme->getColorByIndex( nNewSeriesIndex )));
        }
        sal_Int32 nGroupIndex=0;
        if( xChartType.is())
        {
            Sequence< Reference< XChartType > > aCTs(
                ::chart::DiagramHelper::getChartTypesFromDiagram( xDiagram ));
            for( ; nGroupIndex<aCTs.getLength(); ++nGroupIndex)
                if( aCTs[nGroupIndex] == xChartType )
                    break;
            if( nGroupIndex == aCTs.getLength())
                nGroupIndex = 0;
        }
        xTemplate->applyStyle( xResult, nGroupIndex, nNewSeriesIndex, nTotalNumberOfSeriesInCTGroup );
    }

    if( bCreateDataCachedSequences )
    {
        // set chart type specific roles
        Reference< data::XDataSink > xSink( xResult, uno::UNO_QUERY );
        if( xChartType.is() && xSink.is())
        {
            ::std::vector< Reference< data::XLabeledDataSequence > > aNewSequences;
            const OUString aRoleOfSeqForSeriesLabel = xChartType->getRoleOfSequenceForSeriesLabel();
            const OUString aLabel( String( ::chart::SchResId( STR_DATA_UNNAMED_SERIES )));
            const Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
            const Sequence< OUString > aOptRoles( xChartType->getSupportedOptionalRoles());
            sal_Int32 nI = 0;

            for(nI=0; nI<aRoles.getLength(); ++nI)
            {
                if( aRoles[nI].equals( lcl_aLabelRole ))
                    continue;
                Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence() );
                lcl_SetSequenceRole( xSeq, aRoles[nI] );
                // assert that aRoleOfSeqForSeriesLabel is part of the mandatory roles
                if( aRoles[nI].equals( aRoleOfSeqForSeriesLabel ))
                {
                    Reference< data::XDataSequence > xLabel( ::chart::DataSourceHelper::createCachedDataSequence( aLabel ));
                    lcl_SetSequenceRole( xLabel, lcl_aLabelRole );
                    aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq, xLabel ));
                }
                else
                    aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
            }

            for(nI=0; nI<aOptRoles.getLength(); ++nI)
            {
                if( aOptRoles[nI].equals( lcl_aLabelRole ))
                    continue;
                Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence());
                lcl_SetSequenceRole( xSeq, aOptRoles[nI] );
                aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
            }

            xSink->setData( ContainerToSequence( aNewSequences ));
        }
    }

    return xResult;
}

struct lcl_addSeriesNumber : public ::std::binary_function<
        sal_Int32, Reference< XDataSeriesContainer >, sal_Int32 >
{
    sal_Int32 operator() ( sal_Int32 nCurrentNumber, const Reference< XDataSeriesContainer > & xCnt ) const
    {
        if( xCnt.is())
            return nCurrentNumber + (xCnt->getDataSeries().getLength());
        return nCurrentNumber;
    }
};

} // anonymous namespace

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


namespace chart
{

DialogModel::DialogModel(
    const Reference< XChartDocument > & xChartDocument,
    const Reference< uno::XComponentContext > & xContext ) :
        m_xChartDocument( xChartDocument ),
        m_xContext( xContext ),
        m_aTimerTriggeredControllerLock( uno::Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) )
{
}

DialogModel::~DialogModel()
{}

void DialogModel::setTemplate(
    const Reference< XChartTypeTemplate > & xTemplate )
{
    m_xTemplate = xTemplate;
}

::boost::shared_ptr< RangeSelectionHelper >
    DialogModel::getRangeSelectionHelper() const
{
    if( ! m_spRangeSelectionHelper.get())
        m_spRangeSelectionHelper.reset(
            new RangeSelectionHelper( m_xChartDocument ));

    return m_spRangeSelectionHelper;
}

Reference< frame::XModel > DialogModel::getChartModel() const
{
    Reference< frame::XModel > xResult( m_xChartDocument, uno::UNO_QUERY );
    return xResult;
}

Reference< data::XDataProvider > DialogModel::getDataProvider() const
{
    Reference< data::XDataProvider > xResult;
    if( m_xChartDocument.is())
        xResult.set( m_xChartDocument->getDataProvider());
    return xResult;
}

::std::vector< Reference< XDataSeriesContainer > >
    DialogModel::getAllDataSeriesContainers() const
{
    ::std::vector< Reference< XDataSeriesContainer > > aResult;

    try
    {
        Reference< XDiagram > xDiagram;
        if( m_xChartDocument.is())
            xDiagram.set( m_xChartDocument->getFirstDiagram());
        if( xDiagram.is())
        {
            Reference< XCoordinateSystemContainer > xCooSysCnt(
                xDiagram, uno::UNO_QUERY_THROW );
            Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
                xCooSysCnt->getCoordinateSystems());
            for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
            {
                Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
                Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
                ::std::transform(
                    aChartTypeSeq.getConstArray(), aChartTypeSeq.getConstArray() + aChartTypeSeq.getLength(),
                    ::std::back_inserter( aResult ),
                    lcl_ChartTypeToSeriesCnt() );
            }
        }
    }
    catch( uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }

    return aResult;
}

::std::vector< DialogModel::tSeriesWithChartTypeByName >
    DialogModel::getAllDataSeriesWithLabel() const
{
    ::std::vector< tSeriesWithChartTypeByName > aResult;
    ::std::vector< Reference< XDataSeriesContainer > > aContainers(
        getAllDataSeriesContainers());

    ::std::copy( aContainers.begin(), aContainers.end(),
                 lcl_DataSeriesContainerAppend( aResult ));
    return aResult;
}

DialogModel::tRolesWithRanges DialogModel::getRolesWithRanges(
    const Reference< XDataSeries > & xSeries,
    const ::rtl::OUString & aRoleOfSequenceForLabel,
    const Reference< chart2::XChartType > & xChartType ) const
{
    DialogModel::tRolesWithRanges aResult;
    try
    {
        Reference< data::XDataSource > xSource( xSeries, uno::UNO_QUERY_THROW );
        const Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
        ::std::copy( aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength(),
                     lcl_RolesWithRangeAppend( aResult, aRoleOfSequenceForLabel ));
        if( xChartType.is())
        {
            // add missing mandatory roles
            Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
            OUString aEmptyString;
            sal_Int32 nI = 0;
            for( nI=0; nI < aRoles.getLength(); ++nI )
            {
                if( aResult.find( aRoles[nI] ) == aResult.end() )
                    aResult.insert( DialogModel::tRolesWithRanges::value_type( aRoles[nI], aEmptyString ));
            }

            // add missing optional roles
            aRoles = xChartType->getSupportedOptionalRoles();
            for( nI=0; nI < aRoles.getLength(); ++nI )
            {
                if( aResult.find( aRoles[nI] ) == aResult.end() )
                    aResult.insert( DialogModel::tRolesWithRanges::value_type( aRoles[nI], aEmptyString ));
            }
        }
    }
    catch( uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }
    return aResult;
}

void DialogModel::moveSeries(
    const Reference< XDataSeries > & xSeries,
    eMoveDirection eDirection )
{
    m_aTimerTriggeredControllerLock.startTimer();
    ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );

    Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
    DiagramHelper::moveSeries( xDiagram, xSeries, eDirection==MOVE_UP );
}

Reference< chart2::XDataSeries > DialogModel::insertSeriesAfter(
    const Reference< XDataSeries > & xSeries,
    const Reference< XChartType > & xChartType,
    bool bCreateDataCachedSequences /* = false */ )
{
    m_aTimerTriggeredControllerLock.startTimer();
    ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
    Reference< XDataSeries > xNewSeries;

    try
    {
        Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram() );
        ThreeDLookScheme e3DScheme = ThreeDHelper::detectScheme( xDiagram );

        sal_Int32 nSeriesInChartType = 0;
        const sal_Int32 nTotalSeries = countSeries();
        if( xChartType.is())
        {
            Reference< XDataSeriesContainer > xCnt( xChartType, uno::UNO_QUERY_THROW );
            nSeriesInChartType = xCnt->getDataSeries().getLength();
        }

        // create new series
        xNewSeries.set(
            lcl_CreateNewSeries(
                m_xContext,
                xChartType,
                nTotalSeries, // new series' index
                nSeriesInChartType,
                xDiagram,
                m_xTemplate,
                bCreateDataCachedSequences ));

        // add new series to container
        if( xNewSeries.is())
        {
            Reference< XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY_THROW );
            ::std::vector< Reference< XDataSeries > > aSeries(
                SequenceToVector( xSeriesCnt->getDataSeries()));
            ::std::vector< Reference< XDataSeries > >::iterator aIt =
                  ::std::find( aSeries.begin(), aSeries.end(), xSeries );
            if( aIt == aSeries.end())
                // if we have no series we insert at the first position.
                aIt = aSeries.begin();
            else
                // vector::insert inserts before, so we have to advance
                ++aIt;
            aSeries.insert( aIt, xNewSeries );
            xSeriesCnt->setDataSeries( ContainerToSequence( aSeries ));
        }

        ThreeDHelper::setScheme( xDiagram, e3DScheme );
    }
    catch( uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }
    return xNewSeries;
}

void DialogModel::deleteSeries(
    const Reference< XDataSeries > & xSeries,
    const Reference< XChartType > & xChartType )
{
    m_aTimerTriggeredControllerLock.startTimer();
    ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );

    DataSeriesHelper::deleteSeries( xSeries, xChartType );
}

Reference< data::XLabeledDataSequence > DialogModel::getCategories() const
{
    Reference< data::XLabeledDataSequence > xResult;
    try
    {
        if( m_xChartDocument.is())
        {
            Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
            xResult.set( DiagramHelper::getCategoriesFromDiagram( xDiagram ));
        }
    }
    catch( uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }
    return xResult;
}

void DialogModel::setCategories( const Reference< chart2::data::XLabeledDataSequence > & xCategories )
{
    if( m_xChartDocument.is())
    {
        Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
        if( xDiagram.is())
        {
            // categories
            bool bSupportsCategories = true;

            Reference< XChartType > xFirstChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
            if( xFirstChartType.is() )
            {
                sal_Int32 nAxisType = ChartTypeHelper::getAxisType( xFirstChartType, 0 ); // x-axis
                bSupportsCategories = (nAxisType == AxisType::CATEGORY);
            }
            DiagramHelper::setCategoriesToDiagram( xCategories, xDiagram, true, bSupportsCategories );
        }
    }
}

OUString DialogModel::getCategoriesRange() const
{
    Reference< data::XLabeledDataSequence > xLSeq( getCategories());
    OUString aRange;
    if( xLSeq.is())
    {
        Reference< data::XDataSequence > xSeq( xLSeq->getValues());
        if( xSeq.is())
            aRange = xSeq->getSourceRangeRepresentation();
    }
    return aRange;
}

bool DialogModel::isCategoryDiagram() const
{
    bool bRet = false;
    if( m_xChartDocument.is())
        bRet = DiagramHelper::isCategoryDiagram( m_xChartDocument->getFirstDiagram() );
    return bRet;
}

void DialogModel::detectArguments(
    OUString & rOutRangeString,
    bool & rOutUseColumns,
    bool & rOutFirstCellAsLabel,
    bool & rOutHasCategories ) const
{
    try
    {
        uno::Sequence< sal_Int32 > aSequenceMapping;//todo YYYX

        // Note: unused data is currently not supported in being passed to detectRangeSegmentation
        if( m_xChartDocument.is())
            DataSourceHelper::detectRangeSegmentation(
                Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY_THROW ),
                rOutRangeString, aSequenceMapping, rOutUseColumns, rOutFirstCellAsLabel, rOutHasCategories );
    }
    catch( uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }
}

bool DialogModel::allArgumentsForRectRangeDetected() const
{
    return DataSourceHelper::allArgumentsForRectRangeDetected( m_xChartDocument );
}

void DialogModel::startControllerLockTimer()
{
    m_aTimerTriggeredControllerLock.startTimer();
}

bool DialogModel::setData(
    const Sequence< beans::PropertyValue > & rArguments )
{
    m_aTimerTriggeredControllerLock.startTimer();
    ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );

    Reference< data::XDataProvider > xDataProvider( getDataProvider());
    if( ! xDataProvider.is() ||
        ! m_xTemplate.is() )
    {
        OSL_ENSURE( false, "Model objects missing" );
        return false;
    }

    try
    {
        Reference< chart2::data::XDataSource > xDataSource(
            xDataProvider->createDataSource( rArguments ) );

        Reference< chart2::XDataInterpreter > xInterpreter(
            m_xTemplate->getDataInterpreter());
        if( xInterpreter.is())
        {
            Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram() );
            ThreeDLookScheme e3DScheme = ThreeDHelper::detectScheme( xDiagram );

            ::std::vector< Reference< XDataSeries > > aSeriesToReUse(
                DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
            applyInterpretedData(
                xInterpreter->interpretDataSource(
                    xDataSource, rArguments,
                    ContainerToSequence( aSeriesToReUse )),
                aSeriesToReUse,
                true /* bSetStyles */);

            ThreeDHelper::setScheme( xDiagram, e3DScheme );
        }
    }
    catch( uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
        return false;
    }

    return true;
}

OUString DialogModel::ConvertRoleFromInternalToUI( const OUString & rRoleString )
{
    return lcl_ConvertRole( rRoleString, true );
}

OUString DialogModel::GetRoleDataLabel()
{
    return OUString( String( ::chart::SchResId( STR_OBJECT_DATALABELS )));
}

sal_Int32 DialogModel::GetRoleIndexForSorting( const ::rtl::OUString & rInternalRoleString )
{
    static lcl_tRoleIndexMap aRoleIndexMap;

    if( aRoleIndexMap.empty())
        lcl_createRoleIndexMap( aRoleIndexMap );

    lcl_tRoleIndexMap::const_iterator aIt( aRoleIndexMap.find( rInternalRoleString ));
    if( aIt != aRoleIndexMap.end())
        return aIt->second;

    return 0;
}

// private methods

void DialogModel::applyInterpretedData(
    const InterpretedData & rNewData,
    const ::std::vector< Reference< XDataSeries > > & rSeriesToReUse,
    bool bSetStyles )
{
    if( ! m_xChartDocument.is())
        return;

    m_aTimerTriggeredControllerLock.startTimer();
    Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
    if( xDiagram.is())
    {
        // styles
        if( bSetStyles && m_xTemplate.is() )
        {
            sal_Int32 nGroup = 0;
            sal_Int32 nSeriesCounter = 0;
            sal_Int32 nNewSeriesIndex = static_cast< sal_Int32 >( rSeriesToReUse.size());
            const sal_Int32 nOuterSize=rNewData.Series.getLength();

            for(; nGroup < nOuterSize; ++nGroup)
            {
                Sequence< Reference< XDataSeries > > aSeries( rNewData.Series[ nGroup ] );
                const sal_Int32 nSeriesInGroup = aSeries.getLength();
                for( sal_Int32 nSeries=0; nSeries<nSeriesInGroup; ++nSeries, ++nSeriesCounter )
                {
                    if( ::std::find( rSeriesToReUse.begin(), rSeriesToReUse.end(), aSeries[nSeries] )
                        == rSeriesToReUse.end())
                    {
                        Reference< beans::XPropertySet > xSeriesProp( aSeries[nSeries], uno::UNO_QUERY );
                        if( xSeriesProp.is())
                        {
                            // @deprecated: correct default color should be found by view
                            // without setting it as hard attribute
                            Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
                            if( xColorScheme.is())
                                xSeriesProp->setPropertyValue(
                                    C2U("Color"), uno::makeAny( xColorScheme->getColorByIndex( nSeriesCounter )));
                        }
                        m_xTemplate->applyStyle( aSeries[nSeries], nGroup, nNewSeriesIndex++, nSeriesInGroup );
                    }
                }
            }
        }

        // data series
        ::std::vector< Reference< XDataSeriesContainer > > aSeriesCnt( getAllDataSeriesContainers());
        ::std::vector< Sequence< Reference< XDataSeries > > > aNewSeries(
            SequenceToVector( rNewData.Series ));

        OSL_ASSERT( aSeriesCnt.size() == aNewSeries.size());

        ::std::vector< Sequence< Reference< XDataSeries > > >::const_iterator aSrcIt( aNewSeries.begin());
        ::std::vector< Reference< XDataSeriesContainer > >::iterator aDestIt( aSeriesCnt.begin());
        for(; aSrcIt != aNewSeries.end() && aDestIt != aSeriesCnt.end();
            ++aSrcIt, ++aDestIt )
        {
            try
            {
                OSL_ASSERT( (*aDestIt).is());
                (*aDestIt)->setDataSeries( *aSrcIt );
            }
            catch( uno::Exception & ex )
            {
                ASSERT_EXCEPTION( ex );
            }
        }

        DialogModel::setCategories(rNewData.Categories);
    }
}

sal_Int32 DialogModel::countSeries() const
{
    ::std::vector< Reference< XDataSeriesContainer > > aCnt( getAllDataSeriesContainers());
    return ::std::accumulate( aCnt.begin(), aCnt.end(), 0, lcl_addSeriesNumber());
}

} //  namespace chart
