/**************************************************************
 *
 * 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 "StatisticsHelper.hxx"
#include "DataSeriesHelper.hxx"
#include "ErrorBar.hxx"
#include "macros.hxx"

#include <rtl/math.hxx>
#include <rtl/ustrbuf.hxx>
#include <comphelper/processfactory.hxx>

#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
#include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
#include <com/sun/star/chart2/data/XDataSink.hpp>
#include <com/sun/star/chart/ErrorBarStyle.hpp>

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

namespace
{

double lcl_getVariance( const Sequence< double > & rData, sal_Int32 & rOutValidCount,
        bool bUnbiasedEstimator )
{
    const sal_Int32 nCount = rData.getLength();
    rOutValidCount = nCount;

    double fSum = 0.0;
    double fQuadSum = 0.0;

    for( sal_Int32 i = 0; i < nCount; ++i )
    {
        const double fData = rData[i];
        if( ::rtl::math::isNan( fData ))
            --rOutValidCount;
        else
        {
            fSum     += fData;
            fQuadSum += fData * fData;
        }
    }

    double fResult;
    if( rOutValidCount == 0 )
        ::rtl::math::setNan( & fResult );
    else
    {
        const double fN = static_cast< double >( rOutValidCount );
        if( bUnbiasedEstimator )
            fResult = (fQuadSum - fSum*fSum/fN) / (fN - 1);
        else
            fResult = (fQuadSum - fSum*fSum/fN) / fN;
    }

    return fResult;
}

Reference< chart2::data::XLabeledDataSequence > lcl_getErrorBarLabeledSequence(
    const Reference< chart2::data::XDataSource > & xDataSource,
    bool bPositiveValue, bool bYError,
    OUString & rOutRoleNameUsed )
{
    OUStringBuffer aRole( C2U("error-bars-"));
    if( bYError )
        aRole.append( sal_Unicode( 'y' ));
    else
        aRole.append( sal_Unicode( 'x' ));

    OUString aPlainRole = aRole.makeStringAndClear();
    aRole.append( aPlainRole );
    aRole.append( sal_Unicode( '-' ));

    if( bPositiveValue )
        aRole = aRole.appendAscii( "positive" );
    else
        aRole = aRole.appendAscii( "negative" );

    OUString aLongRole = aRole.makeStringAndClear();
    Reference< chart2::data::XLabeledDataSequence > xLSeq(
        ::chart::DataSeriesHelper::getDataSequenceByRole( xDataSource, aLongRole ));
    // try role without "-negative" or "-positive" postfix
    if( xLSeq.is())
        rOutRoleNameUsed = aLongRole;
    else
    {
        xLSeq.set( ::chart::DataSeriesHelper::getDataSequenceByRole( xDataSource, aPlainRole ));
        if( xLSeq.is())
            rOutRoleNameUsed = aPlainRole;
        else
            rOutRoleNameUsed = aLongRole;
    }

    return xLSeq;
}

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

void lcl_addSequenceToDataSource(
    const Reference< chart2::data::XDataSource > & xDataSource,
    const Reference< chart2::data::XDataSequence > & xNewSequence,
    const OUString & rRole )
{
    Reference< chart2::data::XDataSink > xSink( xDataSource, uno::UNO_QUERY );
    Reference< lang::XMultiServiceFactory > xFact( comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
    if( ! ( xFact.is() && xSink.is() ))
        return;

    Reference< chart2::data::XLabeledDataSequence > xLSeq(
        xFact->createInstance( C2U("com.sun.star.chart2.data.LabeledDataSequence")), uno::UNO_QUERY );
    if( xLSeq.is())
    {
        lcl_setRole( xNewSequence, rRole );
        xLSeq->setValues( xNewSequence );
        Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences(
            xDataSource->getDataSequences());
        aSequences.realloc( aSequences.getLength() + 1 );
        aSequences[ aSequences.getLength() - 1 ] = xLSeq;
        xSink->setData( aSequences );
    }
}

void lcl_setXMLRangePropertyAtDataSequence(
    const Reference< chart2::data::XDataSequence > & xDataSequence,
    const OUString & rXMLRange )
{
    try
    {
        const OUString aXMLRangePropName( C2U( "CachedXMLRange" ));
        Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY_THROW );
        Reference< beans::XPropertySetInfo > xInfo( xProp->getPropertySetInfo());
        if( xInfo.is() && xInfo->hasPropertyByName( aXMLRangePropName ))
            xProp->setPropertyValue( aXMLRangePropName, uno::makeAny( rXMLRange ));
    }
    catch( const uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }
}

} // anonymous namespace

namespace chart
{

double StatisticsHelper::getVariance(
    const Sequence< double > & rData,
    bool bUnbiasedEstimator /* = false */ )
{
    sal_Int32 nValCount;
    return lcl_getVariance( rData, nValCount, bUnbiasedEstimator );
}

double StatisticsHelper::getStandardDeviation( const Sequence< double > & rData )
{
    double fResult = getVariance( rData );
    if( ! ::rtl::math::isNan( fResult ))
        fResult = sqrt( fResult );

    return fResult;
}

double StatisticsHelper::getStandardError( const Sequence< double > & rData )
{
    sal_Int32 nValCount;
    double fVar = lcl_getVariance( rData, nValCount, false );
    double fResult;

    if( nValCount == 0 ||
        ::rtl::math::isNan( fVar ))
    {
        ::rtl::math::setNan( & fResult );
    }
    else
    {
        // standard-deviation / sqrt(n)
        fResult = sqrt( fVar ) / sqrt( double(nValCount) );
    }

    return fResult;
}

Reference< chart2::data::XLabeledDataSequence > StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
    const Reference< chart2::data::XDataSource > & xDataSource,
    bool bPositiveValue,
    bool bYError /* = true */ )
{
    Reference< chart2::data::XLabeledDataSequence > xResult;
    if( !xDataSource.is())
        return xResult;

    OUString aRole;
    Reference< chart2::data::XLabeledDataSequence > xLSeq(
        lcl_getErrorBarLabeledSequence( xDataSource, bPositiveValue, bYError, aRole ));
    if( xLSeq.is())
        xResult.set( xLSeq );

    return xResult;
}

Reference< chart2::data::XDataSequence > StatisticsHelper::getErrorDataSequenceFromDataSource(
    const Reference< chart2::data::XDataSource > & xDataSource,
    bool bPositiveValue,
    bool bYError /* = true */ )
{
    Reference< chart2::data::XLabeledDataSequence > xLSeq(
        StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
            xDataSource, bPositiveValue,
            bYError ));
    if( !xLSeq.is())
        return Reference< chart2::data::XDataSequence >();

    return xLSeq->getValues();
}

double StatisticsHelper::getErrorFromDataSource(
    const Reference< chart2::data::XDataSource > & xDataSource,
    sal_Int32 nIndex,
    bool bPositiveValue,
    bool bYError /* = true */ )
{
    double fResult = 0.0;
    ::rtl::math::setNan( & fResult );

    Reference< chart2::data::XDataSequence > xValues(
        StatisticsHelper::getErrorDataSequenceFromDataSource( xDataSource, bPositiveValue, bYError ));

    Reference< chart2::data::XNumericalDataSequence > xNumValues( xValues, uno::UNO_QUERY );
    if( xNumValues.is())
    {
        Sequence< double > aData( xNumValues->getNumericalData());
        if( nIndex < aData.getLength())
            fResult = aData[nIndex];
    }
    else if( xValues.is())
    {
        Sequence< uno::Any > aData( xValues->getData());
        if( nIndex < aData.getLength())
            aData[nIndex] >>= fResult;
    }

    return fResult;
}

void StatisticsHelper::setErrorDataSequence(
    const Reference< chart2::data::XDataSource > & xDataSource,
    const Reference< chart2::data::XDataProvider > & xDataProvider,
    const OUString & rNewRange,
    bool bPositiveValue,
    bool bYError /* = true */,
    OUString * pXMLRange /* = 0 */ )
{
    Reference< chart2::data::XDataSink > xDataSink( xDataSource, uno::UNO_QUERY );
    if( ! ( xDataSink.is() && xDataProvider.is()))
        return;

    OUString aRole;
    Reference< chart2::data::XLabeledDataSequence > xLSeq(
        lcl_getErrorBarLabeledSequence( xDataSource, bPositiveValue, bYError, aRole ));
    Reference< chart2::data::XDataSequence > xNewSequence(
        xDataProvider->createDataSequenceByRangeRepresentation( rNewRange ));
    if( xNewSequence.is())
    {
        if( pXMLRange )
            lcl_setXMLRangePropertyAtDataSequence( xNewSequence, *pXMLRange );
        if( xLSeq.is())
        {
            lcl_setRole( xNewSequence, aRole );
            xLSeq->setValues( xNewSequence );
        }
        else
            lcl_addSequenceToDataSource( xDataSource, xNewSequence, aRole );
    }
}

Reference< beans::XPropertySet > StatisticsHelper::addErrorBars(
    const Reference< chart2::XDataSeries > & xDataSeries,
    const Reference< uno::XComponentContext > & xContext,
    sal_Int32 nStyle,
    bool bYError /* = true */ )
{
    Reference< beans::XPropertySet > xErrorBar;
    Reference< beans::XPropertySet > xSeriesProp( xDataSeries, uno::UNO_QUERY );
    if( !xSeriesProp.is())
        return xErrorBar;

    const OUString aPropName( bYError ? C2U("ErrorBarY") : C2U("ErrorBarX"));
    if( !( xSeriesProp->getPropertyValue( aPropName ) >>= xErrorBar ) ||
        !xErrorBar.is())
    {
        xErrorBar.set( createErrorBar( xContext ));
    }

    OSL_ASSERT( xErrorBar.is());
    if( xErrorBar.is())
    {
        xErrorBar->setPropertyValue( C2U("ErrorBarStyle"), uno::makeAny( nStyle ));
    }

    xSeriesProp->setPropertyValue( aPropName, uno::makeAny( xErrorBar ));

    return xErrorBar;
}

Reference< beans::XPropertySet > StatisticsHelper::getErrorBars(
    const Reference< chart2::XDataSeries > & xDataSeries,
    bool bYError /* = true */ )
{
    Reference< beans::XPropertySet > xSeriesProp( xDataSeries, uno::UNO_QUERY );
    Reference< beans::XPropertySet > xErrorBar;
    const OUString aPropName( bYError ? C2U("ErrorBarY") : C2U("ErrorBarX"));

    if ( xSeriesProp.is())
        xSeriesProp->getPropertyValue( aPropName ) >>= xErrorBar;

    return xErrorBar;
}

bool StatisticsHelper::hasErrorBars(
    const Reference< chart2::XDataSeries > & xDataSeries,
    bool bYError /* = true */ )
{
    Reference< beans::XPropertySet > xErrorBar( getErrorBars( xDataSeries, bYError ));
    sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;

    return ( xErrorBar.is() &&
             ( xErrorBar->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle ) &&
             nStyle != ::com::sun::star::chart::ErrorBarStyle::NONE );
}

void StatisticsHelper::removeErrorBars(
    const Reference< chart2::XDataSeries > & xDataSeries,
    bool bYError /* = true  */ )
{
    Reference< beans::XPropertySet > xErrorBar( getErrorBars( xDataSeries, bYError ));
    if ( xErrorBar.is())
        xErrorBar->setPropertyValue( C2U("ErrorBarStyle"), uno::makeAny(
                                         ::com::sun::star::chart::ErrorBarStyle::NONE ));
}

bool StatisticsHelper::usesErrorBarRanges(
    const Reference< chart2::XDataSeries > & xDataSeries,
    bool bYError /* = true */ )
{
    Reference< beans::XPropertySet > xErrorBar( getErrorBars( xDataSeries, bYError ));
    sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;

    return ( xErrorBar.is() &&
             ( xErrorBar->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle ) &&
             nStyle == ::com::sun::star::chart::ErrorBarStyle::FROM_DATA );
}

} //  namespace chart
