/**************************************************************
 * 
 * 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 "PieChart.hxx"
#include "PlottingPositionHelper.hxx"
#include "ShapeFactory.hxx"
#include "PolarLabelPositionHelper.hxx"
#include "macros.hxx"
#include "CommonConverters.hxx"
#include "ViewDefines.hxx"
#include "ObjectIdentifier.hxx"

#include <com/sun/star/chart/DataLabelPlacement.hpp>
#include <com/sun/star/chart2/XColorScheme.hpp>

#include <com/sun/star/container/XChild.hpp>

//#include "chartview/servicenames_charttypes.hxx"
//#include "servicenames_coosystems.hxx"
#include <tools/debug.hxx>
#include <rtl/math.hxx>

//.............................................................................
namespace chart
{
//.............................................................................
using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;

class PiePositionHelper : public PolarPlottingPositionHelper
{
public:
    PiePositionHelper( NormalAxis eNormalAxis, double fAngleDegreeOffset );
    virtual ~PiePositionHelper();

    bool    getInnerAndOuterRadius( double fCategoryX, double& fLogicInnerRadius, double& fLogicOuterRadius, bool bUseRings, double fMaxOffset ) const;

public:
    //Distance between different category rings, seen relative to width of a ring:
    double  m_fRingDistance; //>=0 m_fRingDistance=1 --> distance == width
};

PiePositionHelper::PiePositionHelper( NormalAxis eNormalAxis, double fAngleDegreeOffset )
        : PolarPlottingPositionHelper(eNormalAxis)
        , m_fRingDistance(0.0)
{
    m_fRadiusOffset = 0.0;
    m_fAngleDegreeOffset = fAngleDegreeOffset;
}

PiePositionHelper::~PiePositionHelper()
{
}

bool PiePositionHelper::getInnerAndOuterRadius( double fCategoryX
                                               , double& fLogicInnerRadius, double& fLogicOuterRadius
                                               , bool bUseRings, double fMaxOffset ) const
{
    if( !bUseRings )
        fCategoryX = 1.0;

    bool bIsVisible = true;
    double fLogicInner = fCategoryX -0.5+m_fRingDistance/2.0;
    double fLogicOuter = fCategoryX +0.5-m_fRingDistance/2.0;

    if( !isMathematicalOrientationRadius() )
    {
        //in this case the given getMaximumX() was not corrcect instead the minimum should have been smaller by fMaxOffset
        //but during getMaximumX and getMimumX we do not know the axis orientation
        fLogicInner += fMaxOffset;
        fLogicOuter += fMaxOffset;
    }

    if( fLogicInner >= getLogicMaxX() )
        return false;
    if( fLogicOuter <= getLogicMinX() )
        return false;

    if( fLogicInner < getLogicMinX() )
        fLogicInner = getLogicMinX();
    if( fLogicOuter > getLogicMaxX() )
        fLogicOuter = getLogicMaxX();

    fLogicInnerRadius = fLogicInner;
    fLogicOuterRadius = fLogicOuter;
    if( !isMathematicalOrientationRadius() )
        std::swap(fLogicInnerRadius,fLogicOuterRadius);
    return bIsVisible;
}

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

PieChart::PieChart( const uno::Reference<XChartType>& xChartTypeModel
                   , sal_Int32 nDimensionCount
                   , bool bExcludingPositioning )
        : VSeriesPlotter( xChartTypeModel, nDimensionCount )
        , m_pPosHelper( new PiePositionHelper( NormalAxis_Z, (m_nDimension==3)?0.0:90.0 ) )
        , m_bUseRings(false)
        , m_bSizeExcludesLabelsAndExplodedSegments(bExcludingPositioning)
{
    ::rtl::math::setNan(&m_fMaxOffset);

    PlotterBase::m_pPosHelper = m_pPosHelper;
    VSeriesPlotter::m_pMainPosHelper = m_pPosHelper;
    m_pPosHelper->m_fRadiusOffset = 0.0;
    m_pPosHelper->m_fRingDistance = 0.0;

    uno::Reference< beans::XPropertySet > xChartTypeProps( xChartTypeModel, uno::UNO_QUERY );
    if( xChartTypeProps.is() ) try
    {
        xChartTypeProps->getPropertyValue( C2U( "UseRings" )) >>= m_bUseRings;
        if( m_bUseRings )
        {
            m_pPosHelper->m_fRadiusOffset = 1.0;
            if( nDimensionCount==3 )
                m_pPosHelper->m_fRingDistance = 0.1;
        }
    }
    catch( uno::Exception& e )
	{
        ASSERT_EXCEPTION( e );
    }
}

PieChart::~PieChart()
{
    delete m_pPosHelper;
}

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

void PieChart::setScales( const std::vector< ExplicitScaleData >& rScales, bool /* bSwapXAndYAxis */ )
{
    DBG_ASSERT(m_nDimension<=static_cast<sal_Int32>(rScales.size()),"Dimension of Plotter does not fit two dimension of given scale sequence");
    m_pPosHelper->setScales( rScales, true );
}

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

drawing::Direction3D PieChart::getPreferredDiagramAspectRatio() const
{
    if( m_nDimension == 3 )
        return drawing::Direction3D(1,1,0.25);
    return drawing::Direction3D(1,1,1);
}

bool PieChart::keepAspectRatio() const
{
    if( m_nDimension == 3 )
        return false;
    return true;
}

bool PieChart::shouldSnapRectToUsedArea()
{
    return true;
}

//-----------------------------------------------------------------
// lang::XServiceInfo
//-----------------------------------------------------------------
/*
APPHELPER_XSERVICEINFO_IMPL(PieChart,CHART2_VIEW_PIECHART_SERVICE_IMPLEMENTATION_NAME)

	uno::Sequence< rtl::OUString > PieChart
::getSupportedServiceNames_Static()
{
	uno::Sequence< rtl::OUString > aSNS( 1 );
	aSNS.getArray()[ 0 ] = CHART2_VIEW_PIECHART_SERVICE_NAME;
	return aSNS;
}
*/

uno::Reference< drawing::XShape > PieChart::createDataPoint(
          const uno::Reference< drawing::XShapes >& xTarget
        , const uno::Reference< beans::XPropertySet >& xObjectProperties
        , double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree
        , double fUnitCircleInnerRadius, double fUnitCircleOuterRadius
        , double fLogicZ, double fDepth, double fExplodePercentage
        , tPropertyNameValueMap* pOverwritePropertiesMap )
{
    //---------------------------
    //transform position:
    drawing::Direction3D aOffset;
    if( !::rtl::math::approxEqual( fExplodePercentage, 0.0 ) )
    {
        double fAngle  = fUnitCircleStartAngleDegree + fUnitCircleWidthAngleDegree/2.0;
        double fRadius = (fUnitCircleOuterRadius-fUnitCircleInnerRadius)*fExplodePercentage;
        drawing::Position3D aOrigin = m_pPosHelper->transformUnitCircleToScene( 0, 0, fLogicZ );
        drawing::Position3D aNewOrigin = m_pPosHelper->transformUnitCircleToScene( fAngle, fRadius, fLogicZ );
        aOffset = aNewOrigin - aOrigin;
    }

    //---------------------------
    //create point
    uno::Reference< drawing::XShape > xShape(0);
    if(m_nDimension==3)
    {
        xShape = m_pShapeFactory->createPieSegment( xTarget
            , fUnitCircleStartAngleDegree, fUnitCircleWidthAngleDegree
            , fUnitCircleInnerRadius, fUnitCircleOuterRadius
            , aOffset, B3DHomMatrixToHomogenMatrix( m_pPosHelper->getUnitCartesianToScene() )
            , fDepth );
    }
    else
    {
        xShape = m_pShapeFactory->createPieSegment2D( xTarget
            , fUnitCircleStartAngleDegree, fUnitCircleWidthAngleDegree
            , fUnitCircleInnerRadius, fUnitCircleOuterRadius
            , aOffset, B3DHomMatrixToHomogenMatrix( m_pPosHelper->getUnitCartesianToScene() ) );
    }
    this->setMappedProperties( xShape, xObjectProperties, PropertyMapper::getPropertyNameMapForFilledSeriesProperties(), pOverwritePropertiesMap );
    return xShape;
}

void PieChart::addSeries( VDataSeries* pSeries, sal_Int32 /* zSlot */, sal_Int32 /* xSlot */, sal_Int32 /* ySlot */ )
{
    VSeriesPlotter::addSeries( pSeries, 0, -1, 0 );
}

double PieChart::getMinimumX()
{
    return 0.5;
}
double PieChart::getMaxOffset()
{
    if (!::rtl::math::isNan(m_fMaxOffset))
        // Value already cached.  Use it.
        return m_fMaxOffset;

    m_fMaxOffset = 0.0;
    if( m_aZSlots.size()<=0 )
        return m_fMaxOffset;
    if( m_aZSlots[0].size()<=0 )
        return m_fMaxOffset;

    const ::std::vector< VDataSeries* >& rSeriesList( m_aZSlots[0][0].m_aSeriesVector );
    if( rSeriesList.size()<=0 )
        return m_fMaxOffset;

    VDataSeries* pSeries = rSeriesList[0];
    uno::Reference< beans::XPropertySet > xSeriesProp( pSeries->getPropertiesOfSeries() );
    if( !xSeriesProp.is() )
        return m_fMaxOffset;

    double fExplodePercentage=0.0;
    xSeriesProp->getPropertyValue( C2U( "Offset" )) >>= fExplodePercentage;
    if(fExplodePercentage>m_fMaxOffset)
        m_fMaxOffset=fExplodePercentage;

    if(!m_bSizeExcludesLabelsAndExplodedSegments)
    {
        uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
        if( xSeriesProp->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
        {
            for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
            {
                uno::Reference< beans::XPropertySet > xPointProp( pSeries->getPropertiesOfPoint(aAttributedDataPointIndexList[nN]) );
                if(xPointProp.is())
                {
                    fExplodePercentage=0.0;
                    xPointProp->getPropertyValue( C2U( "Offset" )) >>= fExplodePercentage;
                    if(fExplodePercentage>m_fMaxOffset)
                        m_fMaxOffset=fExplodePercentage;
                }
            }
        }
    }
    return m_fMaxOffset;
}
double PieChart::getMaximumX()
{
    double fMaxOffset = getMaxOffset();
    if( m_aZSlots.size()>0 && m_bUseRings)
        return m_aZSlots[0].size()+0.5+fMaxOffset;
    return 1.5+fMaxOffset;
}
double PieChart::getMinimumYInRange( double /* fMinimumX */, double /* fMaximumX */, sal_Int32 /* nAxisIndex */ )
{
    return 0.0;
}

double PieChart::getMaximumYInRange( double /* fMinimumX */, double /* fMaximumX */, sal_Int32 /* nAxisIndex */ )
{
    return 1.0;
}

bool PieChart::isExpandBorderToIncrementRhythm( sal_Int32 /* nDimensionIndex */ )
{
    return false;
}

bool PieChart::isExpandIfValuesCloseToBorder( sal_Int32 /* nDimensionIndex */ )
{
    return false;
}

bool PieChart::isExpandWideValuesToZero( sal_Int32 /* nDimensionIndex */ )
{
    return false;
}

bool PieChart::isExpandNarrowValuesTowardZero( sal_Int32 /* nDimensionIndex */ )
{
    return false;
}

bool PieChart::isSeperateStackingForDifferentSigns( sal_Int32 /* nDimensionIndex */ )
{
    return false;
}

void PieChart::createShapes()
{
    if( m_aZSlots.begin() == m_aZSlots.end() ) //no series
        return;

    DBG_ASSERT(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is(),"PieChart is not proper initialized");
    if(!(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()))
        return;

    //the text labels should be always on top of the other series shapes
    //therefore create an own group for the texts to move them to front
    //(because the text group is created after the series group the texts are displayed on top)
    uno::Reference< drawing::XShapes > xSeriesTarget(
        createGroupShape( m_xLogicTarget,rtl::OUString() ));
    uno::Reference< drawing::XShapes > xTextTarget(
        m_pShapeFactory->createGroup2D( m_xFinalTarget,rtl::OUString() ));
    //---------------------------------------------
    //check necessary here that different Y axis can not be stacked in the same group? ... hm?

//=============================================================================
    ::std::vector< VDataSeriesGroup >::iterator             aXSlotIter = m_aZSlots[0].begin();
    const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = m_aZSlots[0].end();

    ::std::vector< VDataSeriesGroup >::size_type nExplodeableSlot = 0;
    if( m_pPosHelper->isMathematicalOrientationRadius() && m_bUseRings )
        nExplodeableSlot = m_aZSlots[0].size()-1;

    m_aLabelInfoList.clear();
    ::rtl::math::setNan(&m_fMaxOffset);
    sal_Int32 n3DRelativeHeight = 100;
    uno::Reference< beans::XPropertySet > xPropertySet( m_xChartTypeModel, uno::UNO_QUERY );
    if ( (m_nDimension==3) && xPropertySet.is())
    {
		try
		{
			uno::Any aAny = xPropertySet->getPropertyValue( C2U("3DRelativeHeight") );
			aAny >>= n3DRelativeHeight;
		}
		catch(const uno::Exception& e) {}
    }

//=============================================================================
    for( double fSlotX=0; aXSlotIter != aXSlotEnd && (m_bUseRings||fSlotX<0.5 ); aXSlotIter++, fSlotX+=1.0 )
	{
        ::std::vector< VDataSeries* >* pSeriesList = &(aXSlotIter->m_aSeriesVector);
        if( pSeriesList->size()<=0 )//there should be only one series in each x slot
            continue;
        VDataSeries* pSeries = (*pSeriesList)[0];
        if(!pSeries)
            continue;

        m_pPosHelper->m_fAngleDegreeOffset = pSeries->getStartingAngle();
	   
        double fLogicYSum = 0.0;
        //iterate through all points to get the sum
        sal_Int32 nPointIndex=0;
        sal_Int32 nPointCount=pSeries->getTotalPointCount();
        for( nPointIndex = 0; nPointIndex < nPointCount; nPointIndex++ )
	    {
            double fY = pSeries->getYValue( nPointIndex );
            if(fY<0.0)
            {
                //@todo warn somehow that negative values are treated as positive
            }
            if( ::rtl::math::isNan(fY) )
                continue;
            fLogicYSum += fabs(fY);
        }
        if(fLogicYSum==0.0)
            continue;
        double fLogicYForNextPoint = 0.0;
        //iterate through all points to create shapes
        for( nPointIndex = 0; nPointIndex < nPointCount; nPointIndex++ )
        {
            double fLogicInnerRadius, fLogicOuterRadius;
            double fOffset = getMaxOffset();
            bool bIsVisible = m_pPosHelper->getInnerAndOuterRadius( fSlotX+1.0, fLogicInnerRadius, fLogicOuterRadius, m_bUseRings, fOffset );
            if( !bIsVisible )
                continue;

            double fLogicZ = -1.0;//as defined
            double fDepth  = this->getTransformedDepth() * (n3DRelativeHeight / 100.0);
//=============================================================================

            uno::Reference< drawing::XShapes > xSeriesGroupShape_Shapes = getSeriesGroupShape(pSeries, xSeriesTarget);
            //collect data point information (logic coordinates, style ):
            double fLogicYValue = fabs(pSeries->getYValue( nPointIndex ));
            if( ::rtl::math::isNan(fLogicYValue) )
                continue;
            if(fLogicYValue==0.0)//@todo: continue also if the resolution to small
                continue;
            double fLogicYPos = fLogicYForNextPoint;
            fLogicYForNextPoint += fLogicYValue;

            uno::Reference< beans::XPropertySet > xPointProperties = pSeries->getPropertiesOfPoint( nPointIndex );

            //iterate through all subsystems to create partial points
            {
                //logic values on angle axis:
                double fLogicStartAngleValue = fLogicYPos/fLogicYSum;
                double fLogicEndAngleValue = (fLogicYPos+fLogicYValue)/fLogicYSum;

                double fExplodePercentage=0.0;
                bool bDoExplode = ( nExplodeableSlot == static_cast< ::std::vector< VDataSeriesGroup >::size_type >(fSlotX) );
                if(bDoExplode) try
                {
                    xPointProperties->getPropertyValue( C2U( "Offset" )) >>= fExplodePercentage;
                }
                catch( uno::Exception& e )
	            {
                    ASSERT_EXCEPTION( e );
                }

                //---------------------------
                //transforme to unit circle:
                double fUnitCircleWidthAngleDegree = m_pPosHelper->getWidthAngleDegree( fLogicStartAngleValue, fLogicEndAngleValue );
                double fUnitCircleStartAngleDegree = m_pPosHelper->transformToAngleDegree( fLogicStartAngleValue );
                double fUnitCircleInnerRadius = m_pPosHelper->transformToRadius( fLogicInnerRadius );
                double fUnitCircleOuterRadius = m_pPosHelper->transformToRadius( fLogicOuterRadius );

                //---------------------------
                //point color:
                std::auto_ptr< tPropertyNameValueMap > apOverwritePropertiesMap(0);
                {
                    if(!pSeries->hasPointOwnColor(nPointIndex) && m_xColorScheme.is())
                    {
                        apOverwritePropertiesMap = std::auto_ptr< tPropertyNameValueMap >( new tPropertyNameValueMap() );
                        (*apOverwritePropertiesMap)[C2U("FillColor")] = uno::makeAny(
                            m_xColorScheme->getColorByIndex( nPointIndex ));
                    }
                }

                //create data point
                uno::Reference<drawing::XShape> xPointShape(
                    createDataPoint( xSeriesGroupShape_Shapes, xPointProperties
                                    , fUnitCircleStartAngleDegree, fUnitCircleWidthAngleDegree
                                    , fUnitCircleInnerRadius, fUnitCircleOuterRadius
                                    , fLogicZ, fDepth, fExplodePercentage, apOverwritePropertiesMap.get() ) );

                //create label
                if( pSeries->getDataPointLabelIfLabel(nPointIndex) )
                {
                    if( !::rtl::math::approxEqual( fExplodePercentage, 0.0 ) )
                    {
                        double fExplodeOffset = (fUnitCircleOuterRadius-fUnitCircleInnerRadius)*fExplodePercentage;
                        fUnitCircleInnerRadius += fExplodeOffset;
                        fUnitCircleOuterRadius += fExplodeOffset;
                    }

                    sal_Int32 nLabelPlacement = pSeries->getLabelPlacement( nPointIndex, m_xChartTypeModel, m_nDimension, m_pPosHelper->isSwapXAndY() );
                    bool bMovementAllowed = ( nLabelPlacement == ::com::sun::star::chart::DataLabelPlacement::AVOID_OVERLAP );
                    if( bMovementAllowed )
                        nLabelPlacement = ::com::sun::star::chart::DataLabelPlacement::OUTSIDE;
                    
                    LabelAlignment eAlignment(LABEL_ALIGN_CENTER);
                    sal_Int32 nScreenValueOffsetInRadiusDirection = 0 ;
                    if( nLabelPlacement == ::com::sun::star::chart::DataLabelPlacement::OUTSIDE )
                        nScreenValueOffsetInRadiusDirection = (3!=m_nDimension) ? 150 : 0;//todo maybe calculate this font height dependent
                    else if( nLabelPlacement == ::com::sun::star::chart::DataLabelPlacement::INSIDE )
                        nScreenValueOffsetInRadiusDirection = (3!=m_nDimension) ? -150 : 0;//todo maybe calculate this font height dependent
                    PolarLabelPositionHelper aPolarPosHelper(m_pPosHelper,m_nDimension,m_xLogicTarget,m_pShapeFactory);
                    awt::Point aScreenPosition2D(
                        aPolarPosHelper.getLabelScreenPositionAndAlignmentForUnitCircleValues(eAlignment, nLabelPlacement
                        , fUnitCircleStartAngleDegree, fUnitCircleWidthAngleDegree
                        , fUnitCircleInnerRadius, fUnitCircleOuterRadius, fLogicZ+0.5, 0 ));

                    PieLabelInfo aPieLabelInfo;
                    aPieLabelInfo.aFirstPosition = basegfx::B2IVector( aScreenPosition2D.X, aScreenPosition2D.Y );
                    awt::Point aOrigin( aPolarPosHelper.transformSceneToScreenPosition( m_pPosHelper->transformUnitCircleToScene( 0.0, 0.0, fLogicZ+1.0 ) ) );
                    aPieLabelInfo.aOrigin = basegfx::B2IVector( aOrigin.X, aOrigin.Y );

                    //add a scaling independent Offset if requested
                    if( nScreenValueOffsetInRadiusDirection != 0)
                    {
                        basegfx::B2IVector aDirection( aScreenPosition2D.X- aOrigin.X, aScreenPosition2D.Y- aOrigin.Y );
                        aDirection.setLength(nScreenValueOffsetInRadiusDirection);
                        aScreenPosition2D.X += aDirection.getX();
                        aScreenPosition2D.Y += aDirection.getY();
                    }
                    
                    aPieLabelInfo.xTextShape = this->createDataLabel( xTextTarget, *pSeries, nPointIndex
                                    , fLogicYValue, fLogicYSum, aScreenPosition2D, eAlignment );

                    uno::Reference< container::XChild > xChild( aPieLabelInfo.xTextShape, uno::UNO_QUERY );
                    if( xChild.is() )
                        aPieLabelInfo.xLabelGroupShape = uno::Reference<drawing::XShape>( xChild->getParent(), uno::UNO_QUERY );
                    aPieLabelInfo.fValue = fLogicYValue;
                    aPieLabelInfo.bMovementAllowed = bMovementAllowed;
                    aPieLabelInfo.bMoved= false;
                    aPieLabelInfo.xTextTarget = xTextTarget;
                    m_aLabelInfoList.push_back(aPieLabelInfo);
                }

                if(!bDoExplode)
                {
                    ShapeFactory::setShapeName( xPointShape
                                , ObjectIdentifier::createPointCID( pSeries->getPointCID_Stub(), nPointIndex ) );
                }
                else try
                {
                    //enable dragging of outer segments

                    double fAngle  = fUnitCircleStartAngleDegree + fUnitCircleWidthAngleDegree/2.0;
                    double fMaxDeltaRadius = fUnitCircleOuterRadius-fUnitCircleInnerRadius;
                    drawing::Position3D aOrigin = m_pPosHelper->transformUnitCircleToScene( fAngle, fUnitCircleOuterRadius, fLogicZ );
                    drawing::Position3D aNewOrigin = m_pPosHelper->transformUnitCircleToScene( fAngle, fUnitCircleOuterRadius + fMaxDeltaRadius, fLogicZ );
                    
                    sal_Int32 nOffsetPercent( static_cast<sal_Int32>(fExplodePercentage * 100.0) );

                    awt::Point aMinimumPosition( PlottingPositionHelper::transformSceneToScreenPosition(
                        aOrigin, m_xLogicTarget, m_pShapeFactory, m_nDimension ) );
                    awt::Point aMaximumPosition( PlottingPositionHelper::transformSceneToScreenPosition(
                        aNewOrigin, m_xLogicTarget, m_pShapeFactory, m_nDimension ) );

                    //enable draging of piesegments
                    rtl::OUString aPointCIDStub( ObjectIdentifier::createSeriesSubObjectStub( OBJECTTYPE_DATA_POINT
                        , pSeries->getSeriesParticle()
                        , ObjectIdentifier::getPieSegmentDragMethodServiceName()
                        , ObjectIdentifier::createPieSegmentDragParameterString(
                            nOffsetPercent, aMinimumPosition, aMaximumPosition )
                        ) );

                    ShapeFactory::setShapeName( xPointShape
                                , ObjectIdentifier::createPointCID( aPointCIDStub, nPointIndex ) );
                }
                catch( uno::Exception& e )
	            {
                    ASSERT_EXCEPTION( e );
                }
            }//next series in x slot (next y slot)
        }//next category
	}//next x slot
//=============================================================================
//=============================================================================
//=============================================================================
    /* @todo remove series shapes if empty
    //remove and delete point-group-shape if empty
    if(!xSeriesGroupShape_Shapes->getCount())
    {
        (*aSeriesIter)->m_xShape.set(NULL);
        m_xLogicTarget->remove(xSeriesGroupShape_Shape);
    }
    */

	//remove and delete series-group-shape if empty

    //... todo
}

namespace
{

::basegfx::B2IRectangle lcl_getRect( const uno::Reference< drawing::XShape >& xShape )
{
    ::basegfx::B2IRectangle aRect;
    if( xShape.is() )
        aRect = BaseGFXHelper::makeRectangle(xShape->getPosition(),xShape->getSize() );
    return aRect;
}

bool lcl_isInsidePage( const awt::Point& rPos, const awt::Size& rSize, const awt::Size& rPageSize )
{
    if( rPos.X < 0  || rPos.Y < 0 )
        return false;
    if( (rPos.X + rSize.Width) > rPageSize.Width  )
        return false;
    if( (rPos.Y + rSize.Height) > rPageSize.Height )
        return false;
    return true;
}

}//end anonymous namespace

PieChart::PieLabelInfo::PieLabelInfo()
    : xTextShape(0), xLabelGroupShape(0), aFirstPosition(), aOrigin(), fValue(0.0)
    , bMovementAllowed(false), bMoved(false), xTextTarget(0), pPrevious(0),pNext(0)
{
}

bool PieChart::PieLabelInfo::moveAwayFrom( const PieChart::PieLabelInfo* pFix, const awt::Size& rPageSize, bool bMoveHalfWay, bool bMoveClockwise, bool bAlternativeMoveDirection )
{
    //return true if the move was successful
    if(!this->bMovementAllowed)
        return false;

    const sal_Int32 nLabelDistanceX = rPageSize.Width/50;
    const sal_Int32 nLabelDistanceY = rPageSize.Height/50;

    ::basegfx::B2IRectangle aOverlap( lcl_getRect( this->xLabelGroupShape ) );
    aOverlap.intersect( lcl_getRect( pFix->xLabelGroupShape ) );
    if( !aOverlap.isEmpty() )
    {
        (void)bAlternativeMoveDirection;//todo

        basegfx::B2IVector aRadiusDirection = this->aFirstPosition - this->aOrigin;
        aRadiusDirection.setLength(1.0);
        basegfx::B2IVector aTangentialDirection( -aRadiusDirection.getY(), aRadiusDirection.getX() );
        bool bShiftHorizontal = abs(aTangentialDirection.getX()) > abs(aTangentialDirection.getY());

        sal_Int32 nShift = bShiftHorizontal ? static_cast<sal_Int32>(aOverlap.getWidth()) : static_cast<sal_Int32>(aOverlap.getHeight());
        nShift += (bShiftHorizontal ? nLabelDistanceX : nLabelDistanceY);
        if( bMoveHalfWay )
            nShift/=2;
        if(!bMoveClockwise)
            nShift*=-1;
        awt::Point aOldPos( this->xLabelGroupShape->getPosition() );
        basegfx::B2IVector aNewPos = basegfx::B2IVector( aOldPos.X, aOldPos.Y ) + nShift*aTangentialDirection;
    
        //check whether the new position is ok
        awt::Point aNewAWTPos( aNewPos.getX(), aNewPos.getY() );
        if( !lcl_isInsidePage( aNewAWTPos, this->xLabelGroupShape->getSize(), rPageSize ) )
            return false;
        
        this->xLabelGroupShape->setPosition( aNewAWTPos );
        this->bMoved = true;
    }
    return true;
}

void PieChart::resetLabelPositionsToPreviousState()
{
    std::vector< PieLabelInfo >::iterator aIt = m_aLabelInfoList.begin();
    std::vector< PieLabelInfo >::const_iterator aEnd = m_aLabelInfoList.end();
    for( ;aIt!=aEnd; ++aIt )
        aIt->xLabelGroupShape->setPosition(aIt->aPreviousPosition);
}

bool PieChart::detectLabelOverlapsAndMove( const awt::Size& rPageSize )
{
    //returns true when there might be more to do
    
    //find borders of a group of overlapping labels
    bool bOverlapFound = false;
    PieLabelInfo* pStart = &(*(m_aLabelInfoList.rbegin()));
    PieLabelInfo* pFirstBorder = 0;
    PieLabelInfo* pSecondBorder = 0;
    PieLabelInfo* pCurrent = pStart;
    do
    {
        ::basegfx::B2IRectangle aPreviousOverlap( lcl_getRect( pCurrent->xLabelGroupShape ) );
        ::basegfx::B2IRectangle aNextOverlap( aPreviousOverlap );
        aPreviousOverlap.intersect( lcl_getRect( pCurrent->pPrevious->xLabelGroupShape ) );
        aNextOverlap.intersect( lcl_getRect( pCurrent->pNext->xLabelGroupShape ) );
        
        bool bPreviousOverlap = !aPreviousOverlap.isEmpty();
        bool bNextOverlap = !aNextOverlap.isEmpty();
        if( bPreviousOverlap || bNextOverlap )
            bOverlapFound = true;
        if( !bPreviousOverlap && bNextOverlap )
        {
            pFirstBorder = pCurrent;
            break;
        }
        pCurrent = pCurrent->pNext;
    }
    while( pCurrent != pStart );

    if( !bOverlapFound )
        return false;

    if( pFirstBorder )
    {
        pCurrent = pFirstBorder;
        do
        {
            ::basegfx::B2IRectangle aPreviousOverlap( lcl_getRect( pCurrent->xLabelGroupShape ) );
            ::basegfx::B2IRectangle aNextOverlap( aPreviousOverlap );
            aPreviousOverlap.intersect( lcl_getRect( pCurrent->pPrevious->xLabelGroupShape ) );
            aNextOverlap.intersect( lcl_getRect( pCurrent->pNext->xLabelGroupShape ) );

            if( !aPreviousOverlap.isEmpty() && aNextOverlap.isEmpty() )
            {
                pSecondBorder = pCurrent;
                break;
            }
            pCurrent = pCurrent->pNext;
        }
        while( pCurrent != pFirstBorder );
    }

    if( !pFirstBorder || !pSecondBorder )
    {
        pFirstBorder = &(*(m_aLabelInfoList.rbegin()));
        pSecondBorder = &(*(m_aLabelInfoList.begin()));
    }

    //find center
    PieLabelInfo* pCenter = pFirstBorder;
    sal_Int32 nOverlapGroupCount = 1;
    for( pCurrent = pFirstBorder ;pCurrent != pSecondBorder; pCurrent = pCurrent->pNext )
        nOverlapGroupCount++;
    sal_Int32 nCenterPos = nOverlapGroupCount/2;
    bool bSingleCenter = nOverlapGroupCount%2 != 0;
    if( bSingleCenter )
        nCenterPos++;
    if(nCenterPos>1)
    {
        pCurrent = pFirstBorder;
        while( --nCenterPos )
            pCurrent = pCurrent->pNext;
        pCenter = pCurrent;
    }

    //remind current positions
    pCurrent = pStart;
    do
    {
        pCurrent->aPreviousPosition = pCurrent->xLabelGroupShape->getPosition();
        pCurrent = pCurrent->pNext;
    }
    while( pCurrent != pStart );

    //
    bool bAlternativeMoveDirection = false;
    if( !tryMoveLabels( pFirstBorder, pSecondBorder, pCenter, bSingleCenter, bAlternativeMoveDirection, rPageSize ) )
        tryMoveLabels( pFirstBorder, pSecondBorder, pCenter, bSingleCenter, bAlternativeMoveDirection, rPageSize );
    return true;
}

bool PieChart::tryMoveLabels( PieLabelInfo* pFirstBorder, PieLabelInfo* pSecondBorder
                             , PieLabelInfo* pCenter
                             , bool bSingleCenter, bool& rbAlternativeMoveDirection, const awt::Size& rPageSize )
{
    PieLabelInfo* p1 = bSingleCenter ? pCenter->pPrevious : pCenter;
    PieLabelInfo* p2 = pCenter->pNext;
    //return true when successful

    bool bLabelOrderIsAntiClockWise = m_pPosHelper->isMathematicalOrientationAngle();

    PieLabelInfo* pCurrent = 0;
    for( pCurrent = p2 ;pCurrent->pPrevious != pSecondBorder; pCurrent = pCurrent->pNext )
    {
        PieLabelInfo* pFix = 0;
        for( pFix = p2->pPrevious ;pFix != pCurrent; pFix = pFix->pNext )
        {
            if( !pCurrent->moveAwayFrom( pFix, rPageSize, !bSingleCenter && pCurrent == p2, !bLabelOrderIsAntiClockWise, rbAlternativeMoveDirection ) )
            {
                if( !rbAlternativeMoveDirection )
                {
                    rbAlternativeMoveDirection = true;
                    resetLabelPositionsToPreviousState();
                    return false;
                }
            }
        }
    }
    for( pCurrent = p1 ;pCurrent->pNext != pFirstBorder; pCurrent = pCurrent->pPrevious )
    {
        PieLabelInfo* pFix = 0;
        for( pFix = p2->pNext ;pFix != pCurrent; pFix = pFix->pPrevious )
        {
            if( !pCurrent->moveAwayFrom( pFix, rPageSize, false, bLabelOrderIsAntiClockWise, rbAlternativeMoveDirection ) )
            {
                if( !rbAlternativeMoveDirection )
                {
                    rbAlternativeMoveDirection = true;
                    resetLabelPositionsToPreviousState();
                    return false;
                }
            }
        }
    }
    return true;
}

void PieChart::rearrangeLabelToAvoidOverlapIfRequested( const awt::Size& rPageSize )
{
    //------------------------------------------------------------------
    //check whether there are any labels that should be moved
    std::vector< PieLabelInfo >::iterator aIt1 = m_aLabelInfoList.begin();
    std::vector< PieLabelInfo >::const_iterator aEnd = m_aLabelInfoList.end();
    bool bMoveableFound = false;
    for( ;aIt1!=aEnd; ++aIt1 )
    {
        if(aIt1->bMovementAllowed)
        {
            bMoveableFound = true;
            break;
        }
    }
    if(!bMoveableFound)
        return;

    double fPageDiagonaleLength = sqrt( double( rPageSize.Width*rPageSize.Width + rPageSize.Height*rPageSize.Height) );
    if( ::rtl::math::approxEqual( fPageDiagonaleLength, 0.0 ) )
        return;

    //------------------------------------------------------------------
    //init next and previous
    aIt1 = m_aLabelInfoList.begin();
    std::vector< PieLabelInfo >::iterator aIt2 = aIt1;
    if( aIt1==aEnd )//no need to do anything when we only have one label
        return;
    aIt1->pPrevious = &(*(m_aLabelInfoList.rbegin()));
    ++aIt2;
    for( ;aIt2!=aEnd; ++aIt1, ++aIt2 )
    {
        PieLabelInfo& rInfo1( *aIt1 );
        PieLabelInfo& rInfo2( *aIt2 );
        rInfo1.pNext = &rInfo2;
        rInfo2.pPrevious = &rInfo1;
    }
    aIt1->pNext = &(*(m_aLabelInfoList.begin()));


    //------------------------------------------------------------------
    //detect overlaps and move
    sal_Int32 nMaxIterations = 50;
    while( detectLabelOverlapsAndMove( rPageSize ) && nMaxIterations > 0 )
        nMaxIterations--;

    //------------------------------------------------------------------
    //create connection lines for the moved labels
    aEnd = m_aLabelInfoList.end();
    VLineProperties aVLineProperties;
    for( aIt1 = m_aLabelInfoList.begin(); aIt1!=aEnd; ++aIt1 )
    {
        PieLabelInfo& rInfo( *aIt1 );
        if( rInfo.bMoved )
        {
            sal_Int32 nX1 = rInfo.aFirstPosition.getX();
            sal_Int32 nY1 = rInfo.aFirstPosition.getY();
            sal_Int32 nX2 = nX1;
            sal_Int32 nY2 = nY1;
            ::basegfx::B2IRectangle aRect( lcl_getRect( rInfo.xLabelGroupShape ) );
            if( nX1 < aRect.getMinX() )
                nX2 = aRect.getMinX();
            else if( nX1 > aRect.getMaxX() )
                nX2 = aRect.getMaxX();

            if( nY1 < aRect.getMinY() )
                nY2 = aRect.getMinY();
            else if( nY1 > aRect.getMaxY() )
                nY2 = aRect.getMaxY();


            //when the line is very short compared to the page size don't create one
            ::basegfx::B2DVector aLength(nX1-nX2, nY1-nY2);
            if( (aLength.getLength()/fPageDiagonaleLength) < 0.01 )
                continue;

            drawing::PointSequenceSequence aPoints(1);
            aPoints[0].realloc(2);
            aPoints[0][0].X = nX1;
            aPoints[0][0].Y = nY1;
            aPoints[0][1].X = nX2;
            aPoints[0][1].Y = nY2;

            uno::Reference< beans::XPropertySet > xProp( rInfo.xTextShape, uno::UNO_QUERY);
            if( xProp.is() )
            {
                sal_Int32 nColor = 0;
                xProp->getPropertyValue(C2U("CharColor")) >>= nColor;
                if( nColor != -1 )//automatic font color does not work for lines -> fallback to black
                    aVLineProperties.Color = uno::makeAny(nColor);
            }
            m_pShapeFactory->createLine2D( rInfo.xTextTarget, aPoints, &aVLineProperties );
        }
    }
}

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