/**************************************************************
 * 
 * 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 "WrappedStatisticProperties.hxx"
#include "WrappedSeriesOrDiagramProperty.hxx"
#include "macros.hxx"
#include "FastPropertyIdRanges.hxx"
#include "RegressionCurveHelper.hxx"
#include "DiagramHelper.hxx"
#include "ErrorBar.hxx"
#include "StatisticsHelper.hxx"

#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/chart/ChartErrorCategory.hpp>
#include <com/sun/star/chart/ErrorBarStyle.hpp>
#include <com/sun/star/chart/ChartErrorIndicatorType.hpp>
#include <com/sun/star/chart/ChartRegressionCurveType.hpp>
#include <com/sun/star/chart2/data/XDataProvider.hpp>
#include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>

using namespace ::com::sun::star;
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::beans::Property;
using ::rtl::OUString;

//.............................................................................
namespace chart
{
namespace wrapper
{

namespace
{

Any lcl_getRegressionDefault()
{
    Any aRet;
    aRet <<= ::com::sun::star::chart::ChartRegressionCurveType_NONE;
    return aRet;
}

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

::com::sun::star::chart::ChartRegressionCurveType lcl_getRegressionCurveType( RegressionCurveHelper::tRegressionType eRegressionType )
{
    ::com::sun::star::chart::ChartRegressionCurveType eRet = ::com::sun::star::chart::ChartRegressionCurveType_NONE;
    switch(eRegressionType)
    {
        case RegressionCurveHelper::REGRESSION_TYPE_LINEAR:
            eRet = ::com::sun::star::chart::ChartRegressionCurveType_LINEAR;
            break;
        case RegressionCurveHelper::REGRESSION_TYPE_LOG:
            eRet = ::com::sun::star::chart::ChartRegressionCurveType_LOGARITHM;
            break;
        case RegressionCurveHelper::REGRESSION_TYPE_EXP:
            eRet = ::com::sun::star::chart::ChartRegressionCurveType_EXPONENTIAL;
            break;
        case RegressionCurveHelper::REGRESSION_TYPE_POWER:
            eRet = ::com::sun::star::chart::ChartRegressionCurveType_POWER;
            break;
        default:
            eRet = ::com::sun::star::chart::ChartRegressionCurveType_NONE;
            break;
    }
    return eRet;
}

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

RegressionCurveHelper::tRegressionType lcl_getRegressionType( ::com::sun::star::chart::ChartRegressionCurveType eRegressionCurveType )
{
    RegressionCurveHelper::tRegressionType eRet;
    switch(eRegressionCurveType)
    {
        case ::com::sun::star::chart::ChartRegressionCurveType_LINEAR:
            eRet = RegressionCurveHelper::REGRESSION_TYPE_LINEAR;
            break;
        case ::com::sun::star::chart::ChartRegressionCurveType_LOGARITHM:
            eRet = RegressionCurveHelper::REGRESSION_TYPE_LOG;
            break;
        case ::com::sun::star::chart::ChartRegressionCurveType_EXPONENTIAL:
            eRet = RegressionCurveHelper::REGRESSION_TYPE_EXP;
            break;
        case ::com::sun::star::chart::ChartRegressionCurveType_POLYNOMIAL:
        case ::com::sun::star::chart::ChartRegressionCurveType_POWER:
            eRet = RegressionCurveHelper::REGRESSION_TYPE_POWER;
            break;
        default:
            eRet = RegressionCurveHelper::REGRESSION_TYPE_NONE;
            break;
    }
    return eRet;
}

sal_Int32 lcl_getErrorBarStyle( const uno::Reference< beans::XPropertySet >& xErrorBarProperties )
{
    sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
    if(xErrorBarProperties.is())
        xErrorBarProperties->getPropertyValue( C2U( "ErrorBarStyle" )) >>= nStyle;
    return nStyle;
}

uno::Reference< chart2::data::XDataProvider > lcl_getDataProviderFromContact(
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact )
{
    uno::Reference< chart2::data::XDataProvider > xResult;
    if( spChart2ModelContact.get())
    {
        uno::Reference< chart2::XChartDocument > xChartDoc(
            spChart2ModelContact->getChart2Document());
        if( xChartDoc.is())
            xResult.set( xChartDoc->getDataProvider());
    }
    return xResult;
}

void lcl_ConvertRangeFromXML(
    ::rtl::OUString & rInOutRange,
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact )
{
    if( !rInOutRange.isEmpty() )
    {
        uno::Reference< chart2::data::XRangeXMLConversion > xConverter(
            lcl_getDataProviderFromContact( spChart2ModelContact ), uno::UNO_QUERY );
        if( xConverter.is())
        {
            ::rtl::OUString aResult = xConverter->convertRangeFromXML( rInOutRange );
            rInOutRange = aResult;
        }
    }
}

void lcl_ConvertRangeToXML(
    ::rtl::OUString & rInOutRange,
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact )
{
    if( !rInOutRange.isEmpty() )
    {
        uno::Reference< chart2::data::XRangeXMLConversion > xConverter(
            lcl_getDataProviderFromContact( spChart2ModelContact ), uno::UNO_QUERY );
        if( xConverter.is())
        {
            ::rtl::OUString aResult = xConverter->convertRangeToXML( rInOutRange );
            rInOutRange = aResult;
        }
    }
}

}//anonymous namespace

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

template< typename PROPERTYTYPE >
class WrappedStatisticProperty : public WrappedSeriesOrDiagramProperty< PROPERTYTYPE >
{
public:
    explicit WrappedStatisticProperty( const OUString& rName, const Any& rDefaulValue
                              , ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact
                              , tSeriesOrDiagramPropertyType ePropertyType )
            : WrappedSeriesOrDiagramProperty< PROPERTYTYPE >(rName,rDefaulValue,spChart2ModelContact,ePropertyType)
    {}
    virtual ~WrappedStatisticProperty() {};


protected:
    uno::Reference< beans::XPropertySet > getOrCreateErrorBarProperties( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const
    {
        if(!xSeriesPropertySet.is())
            return 0;
        uno::Reference< beans::XPropertySet > xErrorBarProperties;
        xSeriesPropertySet->getPropertyValue( C2U( "ErrorBarY" )) >>= xErrorBarProperties;
        if( !xErrorBarProperties.is() )
        {
            // todo: use a valid context
            xErrorBarProperties = ::chart::createErrorBar( uno::Reference< uno::XComponentContext >() );
            //default in new and old api are different
            xErrorBarProperties->setPropertyValue( C2U( "ShowPositiveError" ), uno::makeAny(sal_Bool(sal_False)) );
            xErrorBarProperties->setPropertyValue( C2U( "ShowNegativeError" ), uno::makeAny(sal_Bool(sal_False)) );
            xErrorBarProperties->setPropertyValue( C2U( "ErrorBarStyle" ), uno::makeAny(::com::sun::star::chart::ErrorBarStyle::NONE) );
            xSeriesPropertySet->setPropertyValue( C2U( "ErrorBarY" ), uno::makeAny( xErrorBarProperties ) );
        }
        return xErrorBarProperties;
    }

};

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//PROP_CHART_STATISTIC_CONST_ERROR_LOW
class WrappedConstantErrorLowProperty : public WrappedStatisticProperty< double >
{
public:
    virtual double getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const;
    virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, double aNewValue ) const;

    explicit WrappedConstantErrorLowProperty( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
                                              tSeriesOrDiagramPropertyType ePropertyType );
    virtual ~WrappedConstantErrorLowProperty();

private:
    mutable Any m_aOuterValue;
};

WrappedConstantErrorLowProperty::WrappedConstantErrorLowProperty(
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
    tSeriesOrDiagramPropertyType ePropertyType )
        : WrappedStatisticProperty< double >( C2U("ConstantErrorLow")
            , uno::makeAny( double(0.0) ), spChart2ModelContact, ePropertyType  )
{
}
WrappedConstantErrorLowProperty::~WrappedConstantErrorLowProperty()
{
}

double WrappedConstantErrorLowProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const
{
    double aRet = 0.0;
    m_aDefaultValue >>= aRet;
    uno::Reference< beans::XPropertySet > xErrorBarProperties;
    if( xSeriesPropertySet.is() && ( xSeriesPropertySet->getPropertyValue( C2U( "ErrorBarY" )) >>= xErrorBarProperties ) && xErrorBarProperties.is())
    {
        if( ::com::sun::star::chart::ErrorBarStyle::ABSOLUTE == lcl_getErrorBarStyle( xErrorBarProperties ) )
            xErrorBarProperties->getPropertyValue( C2U( "NegativeError" )) >>= aRet;
        else
            m_aOuterValue >>= aRet;
    }
    return aRet;
}
void WrappedConstantErrorLowProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, double aNewValue ) const
{
    uno::Reference< beans::XPropertySet > xErrorBarProperties( getOrCreateErrorBarProperties(xSeriesPropertySet) );
    if( xErrorBarProperties.is() )
    {
        m_aOuterValue = uno::makeAny( aNewValue );
        if( ::com::sun::star::chart::ErrorBarStyle::ABSOLUTE == lcl_getErrorBarStyle( xErrorBarProperties ) )
        {
            xErrorBarProperties->setPropertyValue( C2U( "NegativeError" ), m_aOuterValue );
        }
    }
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//PROP_CHART_STATISTIC_CONST_ERROR_HIGH
class WrappedConstantErrorHighProperty : public WrappedStatisticProperty< double >
{
public:
    virtual double getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const;
    virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, double aNewValue ) const;

    explicit WrappedConstantErrorHighProperty( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
                                               tSeriesOrDiagramPropertyType ePropertyType );
    virtual ~WrappedConstantErrorHighProperty();

private:
    mutable Any m_aOuterValue;
};

WrappedConstantErrorHighProperty::WrappedConstantErrorHighProperty(
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
    tSeriesOrDiagramPropertyType ePropertyType )
        : WrappedStatisticProperty< double >( C2U("ConstantErrorHigh")
            , uno::makeAny( double(0.0) ), spChart2ModelContact, ePropertyType  )
{
}
WrappedConstantErrorHighProperty::~WrappedConstantErrorHighProperty()
{
}

double WrappedConstantErrorHighProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const
{
    double aRet = 0.0;
    m_aDefaultValue >>= aRet;
    uno::Reference< beans::XPropertySet > xErrorBarProperties;
    if( xSeriesPropertySet.is() && ( xSeriesPropertySet->getPropertyValue( C2U( "ErrorBarY" )) >>= xErrorBarProperties ) && xErrorBarProperties.is())
    {
        if( ::com::sun::star::chart::ErrorBarStyle::ABSOLUTE == lcl_getErrorBarStyle( xErrorBarProperties ) )
            xErrorBarProperties->getPropertyValue( C2U( "PositiveError" )) >>= aRet;
        else
            m_aOuterValue >>= aRet;
    }
    return aRet;
}
void WrappedConstantErrorHighProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, double aNewValue ) const
{
    uno::Reference< beans::XPropertySet > xErrorBarProperties( getOrCreateErrorBarProperties(xSeriesPropertySet) );
    if( xErrorBarProperties.is() )
    {
        m_aOuterValue = uno::makeAny( aNewValue );
        if( ::com::sun::star::chart::ErrorBarStyle::ABSOLUTE == lcl_getErrorBarStyle( xErrorBarProperties ) )
        {
            xErrorBarProperties->setPropertyValue( C2U( "PositiveError" ), m_aOuterValue );
        }
    }
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//PROP_CHART_STATISTIC_MEAN_VALUE
class WrappedMeanValueProperty : public WrappedStatisticProperty< sal_Bool >
{
public:
    virtual sal_Bool getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const;
    virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, sal_Bool aNewValue ) const;

    explicit WrappedMeanValueProperty( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
                                       tSeriesOrDiagramPropertyType ePropertyType );
    virtual ~WrappedMeanValueProperty();
};

WrappedMeanValueProperty::WrappedMeanValueProperty(
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
    tSeriesOrDiagramPropertyType ePropertyType )
        : WrappedStatisticProperty< sal_Bool >( C2U("MeanValue"), uno::makeAny( sal_False ), spChart2ModelContact, ePropertyType  )
{
}
WrappedMeanValueProperty::~WrappedMeanValueProperty()
{
}

sal_Bool WrappedMeanValueProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const
{
    sal_Bool bRet = sal_False;
    uno::Reference< chart2::XRegressionCurveContainer > xRegCnt( xSeriesPropertySet, uno::UNO_QUERY );
    if( xRegCnt.is() )
        bRet = RegressionCurveHelper::hasMeanValueLine( xRegCnt );
    return bRet;
}
void WrappedMeanValueProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, sal_Bool aNewValue ) const
{
    uno::Reference< chart2::XRegressionCurveContainer > xRegCnt( xSeriesPropertySet, uno::UNO_QUERY );
    if( xRegCnt.is() )
    {
        if(aNewValue)
            RegressionCurveHelper::addMeanValueLine( xRegCnt, 0, 0 );
        else
            RegressionCurveHelper::removeMeanValueLine( xRegCnt );
    }
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//PROP_CHART_STATISTIC_ERROR_CATEGORY
// deprecated, replaced by ErrorBarStyle
class WrappedErrorCategoryProperty : public WrappedStatisticProperty< ::com::sun::star::chart::ChartErrorCategory >
{
public:
    virtual ::com::sun::star::chart::ChartErrorCategory getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const;
    virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, ::com::sun::star::chart::ChartErrorCategory aNewValue ) const;

    explicit WrappedErrorCategoryProperty( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
                                           tSeriesOrDiagramPropertyType ePropertyType );
    virtual ~WrappedErrorCategoryProperty();
};

WrappedErrorCategoryProperty::WrappedErrorCategoryProperty(
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
    tSeriesOrDiagramPropertyType ePropertyType )
        : WrappedStatisticProperty< ::com::sun::star::chart::ChartErrorCategory >( C2U("ErrorCategory")
            , uno::makeAny( ::com::sun::star::chart::ChartErrorCategory_NONE ), spChart2ModelContact, ePropertyType  )
{
}
WrappedErrorCategoryProperty::~WrappedErrorCategoryProperty()
{
}

::com::sun::star::chart::ChartErrorCategory WrappedErrorCategoryProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const
{
    ::com::sun::star::chart::ChartErrorCategory aRet = ::com::sun::star::chart::ChartErrorCategory_NONE;
    m_aDefaultValue >>= aRet;
    uno::Reference< beans::XPropertySet > xErrorBarProperties;
    if( xSeriesPropertySet.is() && ( xSeriesPropertySet->getPropertyValue( C2U( "ErrorBarY" )) >>= xErrorBarProperties ) && xErrorBarProperties.is())
    {
        sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
        xErrorBarProperties->getPropertyValue( C2U( "ErrorBarStyle" )) >>= nStyle;
        switch(nStyle)
        {
            case ::com::sun::star::chart::ErrorBarStyle::NONE:
                aRet = ::com::sun::star::chart::ChartErrorCategory_NONE;
                break;
            case ::com::sun::star::chart::ErrorBarStyle::VARIANCE:
                aRet = ::com::sun::star::chart::ChartErrorCategory_VARIANCE;
                break;
            case ::com::sun::star::chart::ErrorBarStyle::STANDARD_DEVIATION:
                aRet = ::com::sun::star::chart::ChartErrorCategory_STANDARD_DEVIATION;
                break;
            case ::com::sun::star::chart::ErrorBarStyle::ABSOLUTE:
                aRet = ::com::sun::star::chart::ChartErrorCategory_CONSTANT_VALUE;
                break;
            case ::com::sun::star::chart::ErrorBarStyle::RELATIVE:
                aRet = ::com::sun::star::chart::ChartErrorCategory_PERCENT;
                break;
            case ::com::sun::star::chart::ErrorBarStyle::ERROR_MARGIN:
                aRet = ::com::sun::star::chart::ChartErrorCategory_ERROR_MARGIN;
                break;
            case ::com::sun::star::chart::ErrorBarStyle::STANDARD_ERROR:
                break;
            case ::com::sun::star::chart::ErrorBarStyle::FROM_DATA:
                break;
            default:
                break;
        }
    }
    return aRet;
}
void WrappedErrorCategoryProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, ::com::sun::star::chart::ChartErrorCategory aNewValue ) const
{
    if( !xSeriesPropertySet.is() )
        return;

    uno::Reference< beans::XPropertySet > xErrorBarProperties( getOrCreateErrorBarProperties(xSeriesPropertySet) );
    if( xErrorBarProperties.is() )
    {
        sal_Int32 nNewStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
        switch(aNewValue)
        {
            case ::com::sun::star::chart::ChartErrorCategory_NONE:
                nNewStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
                break;
            case ::com::sun::star::chart::ChartErrorCategory_VARIANCE:
                nNewStyle = ::com::sun::star::chart::ErrorBarStyle::VARIANCE;
                break;
            case ::com::sun::star::chart::ChartErrorCategory_STANDARD_DEVIATION:
                nNewStyle = ::com::sun::star::chart::ErrorBarStyle::STANDARD_DEVIATION;
                break;
            case ::com::sun::star::chart::ChartErrorCategory_CONSTANT_VALUE:
                nNewStyle = ::com::sun::star::chart::ErrorBarStyle::ABSOLUTE;
                break;
            case ::com::sun::star::chart::ChartErrorCategory_PERCENT:
                nNewStyle = ::com::sun::star::chart::ErrorBarStyle::RELATIVE;
                break;
            case ::com::sun::star::chart::ChartErrorCategory_ERROR_MARGIN:
                nNewStyle = ::com::sun::star::chart::ErrorBarStyle::ERROR_MARGIN;
                break;
            default:
                break;
        }
        xErrorBarProperties->setPropertyValue( C2U( "ErrorBarStyle" ), uno::makeAny(nNewStyle) );
    }
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//PROP_CHART_STATISTIC_PERCENT_ERROR
class WrappedPercentageErrorProperty : public WrappedStatisticProperty< double >
{
public:
    virtual double getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const;
    virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, double aNewValue ) const;

    explicit WrappedPercentageErrorProperty( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
                                             tSeriesOrDiagramPropertyType ePropertyType );
    virtual ~WrappedPercentageErrorProperty();

private:
    mutable Any m_aOuterValue;
};

WrappedPercentageErrorProperty::WrappedPercentageErrorProperty(
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
    tSeriesOrDiagramPropertyType ePropertyType )
        : WrappedStatisticProperty< double >( C2U("PercentageError")
            , uno::makeAny( double(0.0) ), spChart2ModelContact, ePropertyType  )
{
}
WrappedPercentageErrorProperty::~WrappedPercentageErrorProperty()
{
}

double WrappedPercentageErrorProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const
{
    double aRet = 0.0;
    m_aDefaultValue >>= aRet;
    uno::Reference< beans::XPropertySet > xErrorBarProperties;
    if( xSeriesPropertySet.is() && ( xSeriesPropertySet->getPropertyValue( C2U( "ErrorBarY" )) >>= xErrorBarProperties ) && xErrorBarProperties.is())
    {
        if( ::com::sun::star::chart::ErrorBarStyle::RELATIVE == lcl_getErrorBarStyle( xErrorBarProperties ) )
            xErrorBarProperties->getPropertyValue( C2U( "PositiveError" )) >>= aRet;
        else
            m_aOuterValue >>= aRet;
    }
    return aRet;
}
void WrappedPercentageErrorProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, double aNewValue ) const
{
    uno::Reference< beans::XPropertySet > xErrorBarProperties( getOrCreateErrorBarProperties(xSeriesPropertySet) );
    if( xErrorBarProperties.is() )
    {
        m_aOuterValue = uno::makeAny( aNewValue );
        if( ::com::sun::star::chart::ErrorBarStyle::RELATIVE == lcl_getErrorBarStyle( xErrorBarProperties ) )
        {
            xErrorBarProperties->setPropertyValue( C2U( "PositiveError" ), m_aOuterValue );
            xErrorBarProperties->setPropertyValue( C2U( "NegativeError" ), m_aOuterValue );
        }
    }
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//PROP_CHART_STATISTIC_ERROR_MARGIN
class WrappedErrorMarginProperty : public WrappedStatisticProperty< double >
{
public:
    virtual double getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const;
    virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, double aNewValue ) const;

    explicit WrappedErrorMarginProperty( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
                                         tSeriesOrDiagramPropertyType ePropertyType );
    virtual ~WrappedErrorMarginProperty();

private:
    mutable Any m_aOuterValue;
};

WrappedErrorMarginProperty::WrappedErrorMarginProperty(
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
    tSeriesOrDiagramPropertyType ePropertyType )
        : WrappedStatisticProperty< double >( C2U("ErrorMargin")
            , uno::makeAny( double(0.0) ), spChart2ModelContact, ePropertyType  )
{
}
WrappedErrorMarginProperty::~WrappedErrorMarginProperty()
{
}

double WrappedErrorMarginProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const
{
    double aRet = 0.0;
    m_aDefaultValue >>= aRet;
    uno::Reference< beans::XPropertySet > xErrorBarProperties;
    if( xSeriesPropertySet.is() && ( xSeriesPropertySet->getPropertyValue( C2U( "ErrorBarY" )) >>= xErrorBarProperties ) && xErrorBarProperties.is())
    {
        if( ::com::sun::star::chart::ErrorBarStyle::ERROR_MARGIN == lcl_getErrorBarStyle( xErrorBarProperties ) )
            xErrorBarProperties->getPropertyValue( C2U( "PositiveError" )) >>= aRet;
        else
            m_aOuterValue >>= aRet;
    }
    return aRet;
}
void WrappedErrorMarginProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, double aNewValue ) const
{
    uno::Reference< beans::XPropertySet > xErrorBarProperties( getOrCreateErrorBarProperties(xSeriesPropertySet) );
    if( xErrorBarProperties.is() )
    {
        m_aOuterValue = uno::makeAny( aNewValue );
        if( ::com::sun::star::chart::ErrorBarStyle::ERROR_MARGIN == lcl_getErrorBarStyle( xErrorBarProperties ) )
        {
            xErrorBarProperties->setPropertyValue( C2U( "PositiveError" ), m_aOuterValue );
            xErrorBarProperties->setPropertyValue( C2U( "NegativeError" ), m_aOuterValue );
        }
    }
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//PROP_CHART_STATISTIC_ERROR_INDICATOR
class WrappedErrorIndicatorProperty : public WrappedStatisticProperty< ::com::sun::star::chart::ChartErrorIndicatorType >
{
public:
    virtual ::com::sun::star::chart::ChartErrorIndicatorType getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const;
    virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, ::com::sun::star::chart::ChartErrorIndicatorType aNewValue ) const;

    explicit WrappedErrorIndicatorProperty( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
                                            tSeriesOrDiagramPropertyType ePropertyType );
    virtual ~WrappedErrorIndicatorProperty();
};

WrappedErrorIndicatorProperty::WrappedErrorIndicatorProperty(
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
    tSeriesOrDiagramPropertyType ePropertyType )
        : WrappedStatisticProperty< ::com::sun::star::chart::ChartErrorIndicatorType >( C2U("ErrorIndicator")
            , uno::makeAny( ::com::sun::star::chart::ChartErrorIndicatorType_NONE ), spChart2ModelContact, ePropertyType  )
{
}
WrappedErrorIndicatorProperty::~WrappedErrorIndicatorProperty()
{
}

::com::sun::star::chart::ChartErrorIndicatorType WrappedErrorIndicatorProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const
{
    ::com::sun::star::chart::ChartErrorIndicatorType aRet = ::com::sun::star::chart::ChartErrorIndicatorType_NONE;
    m_aDefaultValue >>= aRet;
    uno::Reference< beans::XPropertySet > xErrorBarProperties;
    if( xSeriesPropertySet.is() && ( xSeriesPropertySet->getPropertyValue( C2U( "ErrorBarY" )) >>= xErrorBarProperties ) && xErrorBarProperties.is())
    {
        sal_Bool bPositive = sal_False;
        sal_Bool bNegative = sal_False;
        xErrorBarProperties->getPropertyValue( C2U( "ShowPositiveError" )) >>= bPositive;
        xErrorBarProperties->getPropertyValue( C2U( "ShowNegativeError" )) >>= bNegative;

        if( bPositive && bNegative )
            aRet = ::com::sun::star::chart::ChartErrorIndicatorType_TOP_AND_BOTTOM;
        else if( bPositive && !bNegative )
            aRet = ::com::sun::star::chart::ChartErrorIndicatorType_UPPER;
        else if( !bPositive && bNegative )
            aRet = ::com::sun::star::chart::ChartErrorIndicatorType_LOWER;
    }
    return aRet;
}
void WrappedErrorIndicatorProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, ::com::sun::star::chart::ChartErrorIndicatorType aNewValue ) const
{
    uno::Reference< beans::XPropertySet > xErrorBarProperties( getOrCreateErrorBarProperties(xSeriesPropertySet) );
    if( xErrorBarProperties.is() )
    {
        sal_Bool bPositive = sal_False;
        sal_Bool bNegative = sal_False;
        switch( aNewValue )
        {
            case ::com::sun::star::chart::ChartErrorIndicatorType_TOP_AND_BOTTOM:
                bPositive = sal_True;
                bNegative = sal_True;
                break;
            case ::com::sun::star::chart::ChartErrorIndicatorType_UPPER:
                bPositive = sal_True;
                break;
            case ::com::sun::star::chart::ChartErrorIndicatorType_LOWER:
                bNegative = sal_True;
                break;
            default:
                break;
        }

        xErrorBarProperties->setPropertyValue( C2U( "ShowPositiveError" ), uno::makeAny(bPositive) );
        xErrorBarProperties->setPropertyValue( C2U( "ShowNegativeError" ), uno::makeAny(bNegative) );
    }
}


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//PROP_CHART_STATISTIC_ERROR_BAR_STYLE
// this is the new constant group that replaces the deprecated enum ChartErrorCategory
class WrappedErrorBarStyleProperty : public WrappedStatisticProperty< sal_Int32 >
{
public:
    virtual sal_Int32 getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const;
    virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, sal_Int32 nNewValue ) const;

    explicit WrappedErrorBarStyleProperty( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact1,
                                           tSeriesOrDiagramPropertyType ePropertyType );
    virtual ~WrappedErrorBarStyleProperty();
};

WrappedErrorBarStyleProperty::WrappedErrorBarStyleProperty(
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
    tSeriesOrDiagramPropertyType ePropertyType )
        : WrappedStatisticProperty< sal_Int32 >( C2U("ErrorBarStyle")
            , uno::makeAny( ::com::sun::star::chart::ErrorBarStyle::NONE ), spChart2ModelContact, ePropertyType  )
{
}
WrappedErrorBarStyleProperty::~WrappedErrorBarStyleProperty()
{
}

sal_Int32 WrappedErrorBarStyleProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const
{
    sal_Int32 nRet = ::com::sun::star::chart::ErrorBarStyle::NONE;
    m_aDefaultValue >>= nRet;
    uno::Reference< beans::XPropertySet > xErrorBarProperties;
    if( xSeriesPropertySet.is() && ( xSeriesPropertySet->getPropertyValue( C2U( "ErrorBarY" )) >>= xErrorBarProperties ) && xErrorBarProperties.is())
    {
        xErrorBarProperties->getPropertyValue( C2U( "ErrorBarStyle" )) >>= nRet;
    }
    return nRet;
}
void WrappedErrorBarStyleProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, sal_Int32 nNewValue ) const
{
    if( !xSeriesPropertySet.is() )
        return;

    uno::Reference< beans::XPropertySet > xErrorBarProperties( getOrCreateErrorBarProperties(xSeriesPropertySet) );
    if( xErrorBarProperties.is() )
    {
        xErrorBarProperties->setPropertyValue( C2U( "ErrorBarStyle" ), uno::makeAny( nNewValue ));
    }
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//PROP_CHART_STATISTIC_ERROR_RANGE_POSITIVE
class WrappedErrorBarRangePositiveProperty : public WrappedStatisticProperty< OUString >
{
public:
    virtual OUString getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const;
    virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, OUString aNewValue ) const;

    explicit WrappedErrorBarRangePositiveProperty( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
                                                   tSeriesOrDiagramPropertyType ePropertyType );
    virtual ~WrappedErrorBarRangePositiveProperty();

private:
    mutable Any m_aOuterValue;
};

WrappedErrorBarRangePositiveProperty::WrappedErrorBarRangePositiveProperty(
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
    tSeriesOrDiagramPropertyType ePropertyType )
        : WrappedStatisticProperty< OUString >( C2U("ErrorBarRangePositive")
            , uno::makeAny( OUString() ), spChart2ModelContact, ePropertyType  )
{
}
WrappedErrorBarRangePositiveProperty::~WrappedErrorBarRangePositiveProperty()
{
}

OUString WrappedErrorBarRangePositiveProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const
{
    OUString aRet;
    m_aDefaultValue >>= aRet;
    uno::Reference< chart2::data::XDataSource > xErrorBarDataSource;
    if( xSeriesPropertySet.is() &&
        ( xSeriesPropertySet->getPropertyValue( C2U( "ErrorBarY" )) >>= xErrorBarDataSource ) &&
        xErrorBarDataSource.is())
    {
        uno::Reference< chart2::data::XDataSequence > xSeq(
            StatisticsHelper::getErrorDataSequenceFromDataSource(
                xErrorBarDataSource, true /* positive */, true /* y-error */ ));
        if( xSeq.is())
            aRet = xSeq->getSourceRangeRepresentation();
        else
            m_aOuterValue >>= aRet;
    }
    lcl_ConvertRangeToXML( aRet, m_spChart2ModelContact );
    return aRet;
}

void WrappedErrorBarRangePositiveProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, OUString aNewValue ) const
{
    uno::Reference< beans::XPropertySet > xErrorBarProperties( getOrCreateErrorBarProperties(xSeriesPropertySet) );
    if( xErrorBarProperties.is() )
    {
        uno::Reference< chart2::data::XDataProvider > xDataProvider(
            lcl_getDataProviderFromContact( m_spChart2ModelContact ));
        uno::Reference< chart2::data::XDataSource > xDataSource( xErrorBarProperties, uno::UNO_QUERY );
        if( xDataSource.is() && xDataProvider.is())
        {
            OUString aXMLRange( aNewValue );
            lcl_ConvertRangeFromXML( aNewValue, m_spChart2ModelContact );
            StatisticsHelper::setErrorDataSequence(
                xDataSource, xDataProvider, aNewValue, true /* positive */, true /* y-error */, &aXMLRange );
            m_aOuterValue <<= aNewValue;
        }
    }
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//PROP_CHART_STATISTIC_ERROR_RANGE_NEGATIVE
class WrappedErrorBarRangeNegativeProperty : public WrappedStatisticProperty< OUString >
{
public:
    virtual OUString getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const;
    virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, OUString aNewValue ) const;

    explicit WrappedErrorBarRangeNegativeProperty( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
                                                   tSeriesOrDiagramPropertyType ePropertyType );
    virtual ~WrappedErrorBarRangeNegativeProperty();

private:
    mutable Any m_aOuterValue;
};

WrappedErrorBarRangeNegativeProperty::WrappedErrorBarRangeNegativeProperty(
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
    tSeriesOrDiagramPropertyType ePropertyType )
        : WrappedStatisticProperty< OUString >( C2U("ErrorBarRangeNegative")
            , uno::makeAny( OUString() ), spChart2ModelContact, ePropertyType  )
{
}
WrappedErrorBarRangeNegativeProperty::~WrappedErrorBarRangeNegativeProperty()
{
}

OUString WrappedErrorBarRangeNegativeProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const
{
    OUString aRet;
    m_aDefaultValue >>= aRet;
    uno::Reference< chart2::data::XDataSource > xErrorBarDataSource;
    if( xSeriesPropertySet.is() &&
        ( xSeriesPropertySet->getPropertyValue( C2U( "ErrorBarY" )) >>= xErrorBarDataSource ) &&
        xErrorBarDataSource.is())
    {
        uno::Reference< chart2::data::XDataSequence > xSeq(
            StatisticsHelper::getErrorDataSequenceFromDataSource(
                xErrorBarDataSource, false /* positive */, true /* y-error */ ));
        if( xSeq.is())
            aRet = xSeq->getSourceRangeRepresentation();
        else
            m_aOuterValue >>= aRet;
    }
    lcl_ConvertRangeToXML( aRet, m_spChart2ModelContact );
    return aRet;
}

void WrappedErrorBarRangeNegativeProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, OUString aNewValue ) const
{
    uno::Reference< beans::XPropertySet > xErrorBarProperties( getOrCreateErrorBarProperties(xSeriesPropertySet) );
    if( xErrorBarProperties.is() )
    {
        uno::Reference< chart2::data::XDataProvider > xDataProvider(
            lcl_getDataProviderFromContact( m_spChart2ModelContact ));
        uno::Reference< chart2::data::XDataSource > xDataSource( xErrorBarProperties, uno::UNO_QUERY );
        if( xDataSource.is() && xDataProvider.is())
        {
            OUString aXMLRange( aNewValue );
            lcl_ConvertRangeFromXML( aNewValue, m_spChart2ModelContact );
            StatisticsHelper::setErrorDataSequence(
                xDataSource, xDataProvider, aNewValue, false /* positive */, true /* y-error */, &aXMLRange );
            m_aOuterValue <<= aNewValue;
        }
    }
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//PROP_CHART_STATISTIC_REGRESSION_CURVES
class WrappedRegressionCurvesProperty : public WrappedStatisticProperty< ::com::sun::star::chart::ChartRegressionCurveType >
{
public:
    virtual ::com::sun::star::chart::ChartRegressionCurveType getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const;
    virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, ::com::sun::star::chart::ChartRegressionCurveType aNewValue ) const;

    explicit WrappedRegressionCurvesProperty( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
                                              tSeriesOrDiagramPropertyType ePropertyType );
    virtual ~WrappedRegressionCurvesProperty();
};

WrappedRegressionCurvesProperty::WrappedRegressionCurvesProperty(
    ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
    tSeriesOrDiagramPropertyType ePropertyType )
        : WrappedStatisticProperty< ::com::sun::star::chart::ChartRegressionCurveType >( C2U("RegressionCurves")
        , lcl_getRegressionDefault(), spChart2ModelContact, ePropertyType  )
{
}
WrappedRegressionCurvesProperty::~WrappedRegressionCurvesProperty()
{
}

::com::sun::star::chart::ChartRegressionCurveType WrappedRegressionCurvesProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const
{
    ::com::sun::star::chart::ChartRegressionCurveType aRet;
    m_aDefaultValue >>= aRet;
    uno::Reference< chart2::XRegressionCurveContainer > xRegCnt( xSeriesPropertySet, uno::UNO_QUERY );
    if( xRegCnt.is() )
    {
        aRet = lcl_getRegressionCurveType( 
            RegressionCurveHelper::getFirstRegressTypeNotMeanValueLine( xRegCnt ) );
    }
    return aRet;
}
void WrappedRegressionCurvesProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, ::com::sun::star::chart::ChartRegressionCurveType aNewValue ) const
{
    uno::Reference< chart2::XRegressionCurveContainer > xRegCnt( xSeriesPropertySet, uno::UNO_QUERY );
    if( xRegCnt.is() )
    {
        RegressionCurveHelper::tRegressionType eNewRegressionType = lcl_getRegressionType( aNewValue );
        RegressionCurveHelper::removeAllExceptMeanValueLine( xRegCnt );
        if( eNewRegressionType != RegressionCurveHelper::REGRESSION_TYPE_NONE )
            RegressionCurveHelper::addRegressionCurve( eNewRegressionType, xRegCnt, 0, 0 );
    }
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//PROP_CHART_STATISTIC_REGRESSION_PROPERTIES
//PROP_CHART_STATISTIC_ERROR_PROPERTIES
//PROP_CHART_STATISTIC_MEAN_VALUE_PROPERTIES
class WrappedStatisticPropertySetProperty : public WrappedStatisticProperty< Reference< beans::XPropertySet > >
{
public:
    virtual Reference< beans::XPropertySet > getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const;
    // properties are read-only, so this method should never be called
    virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, Reference< beans::XPropertySet > xNewValue ) const;

    enum PropertySetType
    {
        PROPERTY_SET_TYPE_REGRESSION,
        PROPERTY_SET_TYPE_ERROR_BAR,
        PROPERTY_SET_TYPE_MEAN_VALUE
    };

    explicit WrappedStatisticPropertySetProperty(
        PropertySetType ePropertySetType, ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
        tSeriesOrDiagramPropertyType ePropertyType );
    virtual ~WrappedStatisticPropertySetProperty();

private:
    PropertySetType m_eType;
};

WrappedStatisticPropertySetProperty::WrappedStatisticPropertySetProperty(
    PropertySetType ePropertySetType
    , ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact
    , tSeriesOrDiagramPropertyType ePropertyType )
        : WrappedStatisticProperty< Reference< beans::XPropertySet > >(
            (ePropertySetType == PROPERTY_SET_TYPE_REGRESSION)
            ? C2U("DataRegressionProperties")
            : (ePropertySetType == PROPERTY_SET_TYPE_ERROR_BAR)
            ? C2U("DataErrorProperties")
            : C2U("DataMeanValueProperties")
            , uno::Any(), spChart2ModelContact, ePropertyType  )
        , m_eType( ePropertySetType )
{
}
WrappedStatisticPropertySetProperty::~WrappedStatisticPropertySetProperty()
{
}

Reference< beans::XPropertySet > WrappedStatisticPropertySetProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const
{
    Reference< beans::XPropertySet > xResult;
    uno::Reference< chart2::XRegressionCurveContainer > xRegCnt( xSeriesPropertySet, uno::UNO_QUERY );

    switch( m_eType )
    {
        case PROPERTY_SET_TYPE_REGRESSION:
            if( xRegCnt.is() )
                xResult.set( RegressionCurveHelper::getFirstCurveNotMeanValueLine( xRegCnt ), uno::UNO_QUERY );
            break;
        case PROPERTY_SET_TYPE_ERROR_BAR:
            if( xSeriesPropertySet.is())
                xSeriesPropertySet->getPropertyValue( C2U( "ErrorBarY" )) >>= xResult;
            break;
        case PROPERTY_SET_TYPE_MEAN_VALUE:
            if( xRegCnt.is() )
                xResult.set( RegressionCurveHelper::getMeanValueLine( xRegCnt ), uno::UNO_QUERY );
            break;
    }

    return xResult;
}

void WrappedStatisticPropertySetProperty::setValueToSeries(
    const Reference< beans::XPropertySet >& /* xSeriesPropertySet */
    , Reference< beans::XPropertySet > /* xNewValue */ ) const
{
}

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

namespace
{
enum
{
    //statistic properties
    PROP_CHART_STATISTIC_CONST_ERROR_LOW = FAST_PROPERTY_ID_START_CHART_STATISTIC_PROP,
    PROP_CHART_STATISTIC_CONST_ERROR_HIGH,
    PROP_CHART_STATISTIC_MEAN_VALUE,
    PROP_CHART_STATISTIC_ERROR_CATEGORY,
    PROP_CHART_STATISTIC_ERROR_BAR_STYLE,
    PROP_CHART_STATISTIC_PERCENT_ERROR,
    PROP_CHART_STATISTIC_ERROR_MARGIN,
    PROP_CHART_STATISTIC_ERROR_INDICATOR,
    PROP_CHART_STATISTIC_ERROR_RANGE_POSITIVE,
    PROP_CHART_STATISTIC_ERROR_RANGE_NEGATIVE,
    PROP_CHART_STATISTIC_REGRESSION_CURVES,
    PROP_CHART_STATISTIC_REGRESSION_PROPERTIES,
    PROP_CHART_STATISTIC_ERROR_PROPERTIES,
    PROP_CHART_STATISTIC_MEAN_VALUE_PROPERTIES
};

/** @parameter bDataSeriesProperty if true, this property is for a single data
               series, if false, it is for the whole diagram, i.e. for all
               series
 */
void lcl_addWrappedProperties( std::vector< WrappedProperty* >& rList
            , ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact
            , tSeriesOrDiagramPropertyType ePropertyType )
{
    rList.push_back( new WrappedConstantErrorLowProperty( spChart2ModelContact, ePropertyType ) );
    rList.push_back( new WrappedConstantErrorHighProperty( spChart2ModelContact, ePropertyType ) );
    rList.push_back( new WrappedMeanValueProperty( spChart2ModelContact, ePropertyType ) );
    rList.push_back( new WrappedErrorCategoryProperty( spChart2ModelContact, ePropertyType ) );
    rList.push_back( new WrappedErrorBarStyleProperty( spChart2ModelContact, ePropertyType ) );
    rList.push_back( new WrappedPercentageErrorProperty( spChart2ModelContact, ePropertyType ) );
    rList.push_back( new WrappedErrorMarginProperty( spChart2ModelContact, ePropertyType ) );
    rList.push_back( new WrappedErrorIndicatorProperty( spChart2ModelContact, ePropertyType ) );
    rList.push_back( new WrappedErrorBarRangePositiveProperty( spChart2ModelContact, ePropertyType ) );
    rList.push_back( new WrappedErrorBarRangeNegativeProperty( spChart2ModelContact, ePropertyType ) );
    rList.push_back( new WrappedRegressionCurvesProperty( spChart2ModelContact, ePropertyType ) );
    rList.push_back( new WrappedStatisticPropertySetProperty(
                         WrappedStatisticPropertySetProperty::PROPERTY_SET_TYPE_REGRESSION, spChart2ModelContact, ePropertyType ) );
    rList.push_back( new WrappedStatisticPropertySetProperty(
                         WrappedStatisticPropertySetProperty::PROPERTY_SET_TYPE_ERROR_BAR,  spChart2ModelContact, ePropertyType ) );
    rList.push_back( new WrappedStatisticPropertySetProperty(
                         WrappedStatisticPropertySetProperty::PROPERTY_SET_TYPE_MEAN_VALUE, spChart2ModelContact, ePropertyType ) );
}

}//anonymous namespace

void WrappedStatisticProperties::addProperties( ::std::vector< Property > & rOutProperties )
{
    rOutProperties.push_back(
        Property( C2U( "ConstantErrorLow" ),
                  PROP_CHART_STATISTIC_CONST_ERROR_LOW,
                  ::getCppuType( reinterpret_cast< double * >(0)),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT ));
    rOutProperties.push_back(
        Property( C2U( "ConstantErrorHigh" ),
                  PROP_CHART_STATISTIC_CONST_ERROR_HIGH,
                  ::getCppuType( reinterpret_cast< double * >(0)),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT ));
    rOutProperties.push_back(
        Property( C2U( "MeanValue" ),
                  PROP_CHART_STATISTIC_MEAN_VALUE,
                  ::getBooleanCppuType(),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT ));
    rOutProperties.push_back(
        Property( C2U( "ErrorCategory" ),
                  PROP_CHART_STATISTIC_ERROR_CATEGORY,
                  ::getCppuType( reinterpret_cast< ::com::sun::star::chart::ChartErrorCategory * >(0)),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT ));
    rOutProperties.push_back(
        Property( C2U( "ErrorBarStyle" ),
                  PROP_CHART_STATISTIC_ERROR_BAR_STYLE,
                  ::getCppuType( reinterpret_cast< sal_Int32 * >(0)),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT ));
    rOutProperties.push_back(
        Property( C2U( "PercentageError" ),
                  PROP_CHART_STATISTIC_PERCENT_ERROR,
                  ::getCppuType( reinterpret_cast< double * >(0)),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT ));
    rOutProperties.push_back(
        Property( C2U( "ErrorMargin" ),
                  PROP_CHART_STATISTIC_ERROR_MARGIN,
                  ::getCppuType( reinterpret_cast< double * >(0)),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT ));
    rOutProperties.push_back(
        Property( C2U( "ErrorIndicator" ),
                  PROP_CHART_STATISTIC_ERROR_INDICATOR,
                  ::getCppuType( reinterpret_cast< ::com::sun::star::chart::ChartErrorIndicatorType * >(0)),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT ));
    rOutProperties.push_back(
        Property( C2U( "ErrorBarRangePositive" ),
                  PROP_CHART_STATISTIC_ERROR_RANGE_POSITIVE,
                  ::getCppuType( reinterpret_cast< OUString * >(0)),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT ));
    rOutProperties.push_back(
        Property( C2U( "ErrorBarRangeNegative" ),
                  PROP_CHART_STATISTIC_ERROR_RANGE_NEGATIVE,
                  ::getCppuType( reinterpret_cast< OUString * >(0)),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT ));
    rOutProperties.push_back(
        Property( C2U( "RegressionCurves" ),
                  PROP_CHART_STATISTIC_REGRESSION_CURVES,
                  ::getCppuType( reinterpret_cast< const ::com::sun::star::chart::ChartRegressionCurveType * >(0)),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT ));

    rOutProperties.push_back(
        Property( C2U( "DataRegressionProperties" ),
                  PROP_CHART_STATISTIC_REGRESSION_PROPERTIES,
                  ::getCppuType( reinterpret_cast< const Reference< beans::XPropertySet > * >(0)),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::READONLY
                  | beans::PropertyAttribute::MAYBEVOID ));
    rOutProperties.push_back(
        Property( C2U( "DataErrorProperties" ),
                  PROP_CHART_STATISTIC_ERROR_PROPERTIES,
                  ::getCppuType( reinterpret_cast< const Reference< beans::XPropertySet > * >(0)),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::READONLY
                  | beans::PropertyAttribute::MAYBEVOID ));
    rOutProperties.push_back(
        Property( C2U( "DataMeanValueProperties" ),
                  PROP_CHART_STATISTIC_MEAN_VALUE_PROPERTIES,
                  ::getCppuType( reinterpret_cast< const Reference< beans::XPropertySet > * >(0)),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::READONLY
                  | beans::PropertyAttribute::MAYBEVOID ));
}

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

void WrappedStatisticProperties::addWrappedPropertiesForSeries( std::vector< WrappedProperty* >& rList
                                    , ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact )
{
    lcl_addWrappedProperties( rList, spChart2ModelContact, DATA_SERIES );
}

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

void WrappedStatisticProperties::addWrappedPropertiesForDiagram( std::vector< WrappedProperty* >& rList
                                    , ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact )
{
    lcl_addWrappedProperties( rList, spChart2ModelContact, DIAGRAM  );
}

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

} //namespace wrapper
} //namespace chart
//.............................................................................
