/**************************************************************
 * 
 * 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 "ThreeDHelper.hxx"
#include "macros.hxx"
#include "DiagramHelper.hxx"
#include "ChartTypeHelper.hxx"
#include "BaseGFXHelper.hxx"
#include "DataSeriesHelper.hxx"
#include <editeng/unoprnms.hxx>
#include <com/sun/star/beans/XPropertyState.hpp>
#include <com/sun/star/chart2/XDiagram.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>

#include <tools/debug.hxx>

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

using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::rtl::OUString;
using ::rtl::math::cos;
using ::rtl::math::sin;
using ::rtl::math::tan;

#define FIXED_SIZE_FOR_3D_CHART_VOLUME (10000.0)

namespace
{

bool lcl_isRightAngledAxesSetAndSupported( const Reference< beans::XPropertySet >& xSceneProperties )
{
    sal_Bool bRightAngledAxes = sal_False;
    if( xSceneProperties.is() )
    {
        xSceneProperties->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes;
        if(bRightAngledAxes)
        {
            uno::Reference< chart2::XDiagram > xDiagram( xSceneProperties, uno::UNO_QUERY );
            if( ChartTypeHelper::isSupportingRightAngledAxes( 
                    DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
            {
                return true;
            }
        }
    }
    return false;
}

void lcl_RotateLightSource( const Reference< beans::XPropertySet >& xSceneProperties
                           , const OUString& rLightSourceDirection
                           , const OUString& rLightSourceOn
                           , const ::basegfx::B3DHomMatrix& rRotationMatrix )
{
    if( xSceneProperties.is() )
    {
        sal_Bool bLightOn = sal_False;
        if( xSceneProperties->getPropertyValue( rLightSourceOn ) >>= bLightOn )
        {
            if( bLightOn )
            {
                drawing::Direction3D aLight;
                if( xSceneProperties->getPropertyValue( rLightSourceDirection ) >>= aLight )
                {
                    ::basegfx::B3DVector aLightVector( BaseGFXHelper::Direction3DToB3DVector( aLight ) );
                    aLightVector = rRotationMatrix*aLightVector;

                    xSceneProperties->setPropertyValue( rLightSourceDirection
                        , uno::makeAny( BaseGFXHelper::B3DVectorToDirection3D( aLightVector ) ) );
                }
            }
        }
    }
}

void lcl_rotateLights( const ::basegfx::B3DHomMatrix& rLightRottion, const Reference< beans::XPropertySet >& xSceneProperties )
{
    if(!xSceneProperties.is())
        return;

    ::basegfx::B3DHomMatrix aLightRottion( rLightRottion );
    BaseGFXHelper::ReduceToRotationMatrix( aLightRottion );

    lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection1"), C2U("D3DSceneLightOn1"), aLightRottion );
    lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection2"), C2U("D3DSceneLightOn2"), aLightRottion );
    lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection3"), C2U("D3DSceneLightOn3"), aLightRottion );
    lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection4"), C2U("D3DSceneLightOn4"), aLightRottion );
    lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection5"), C2U("D3DSceneLightOn5"), aLightRottion );
    lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection6"), C2U("D3DSceneLightOn6"), aLightRottion );
    lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection7"), C2U("D3DSceneLightOn7"), aLightRottion );
    lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection8"), C2U("D3DSceneLightOn8"), aLightRottion );
}

::basegfx::B3DHomMatrix lcl_getInverseRotationMatrix( const Reference< beans::XPropertySet >& xSceneProperties )
{
    ::basegfx::B3DHomMatrix aInverseRotation;
    double fXAngleRad=0.0;
    double fYAngleRad=0.0;
    double fZAngleRad=0.0;
    ThreeDHelper::getRotationAngleFromDiagram(
        xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    aInverseRotation.rotate( 0.0, 0.0, -fZAngleRad );
    aInverseRotation.rotate( 0.0, -fYAngleRad, 0.0 );
    aInverseRotation.rotate( -fXAngleRad, 0.0, 0.0 );
    return aInverseRotation;
}

::basegfx::B3DHomMatrix lcl_getCompleteRotationMatrix( const Reference< beans::XPropertySet >& xSceneProperties )
{
    ::basegfx::B3DHomMatrix aCompleteRotation;
    double fXAngleRad=0.0;
    double fYAngleRad=0.0;
    double fZAngleRad=0.0;
    ThreeDHelper::getRotationAngleFromDiagram(
        xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    aCompleteRotation.rotate( fXAngleRad, fYAngleRad, fZAngleRad );
    return aCompleteRotation;
}

bool lcl_isEqual( const drawing::Direction3D& rA, const drawing::Direction3D& rB )
{
    return ::rtl::math::approxEqual(rA.DirectionX, rB.DirectionX)
        && ::rtl::math::approxEqual(rA.DirectionY, rB.DirectionY)
        && ::rtl::math::approxEqual(rA.DirectionZ, rB.DirectionZ);
}

bool lcl_isLightScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps, bool bRealistic )
{
    if(!xDiagramProps.is())
        return false;

    sal_Bool bIsOn = sal_False;
    xDiagramProps->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_2 ) ) >>= bIsOn;
    if(!bIsOn)
        return false;

    uno::Reference< chart2::XDiagram > xDiagram( xDiagramProps, uno::UNO_QUERY );
    uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );    

    sal_Int32 nColor = 0;
    xDiagramProps->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_2 ) ) >>= nColor;
    if( nColor != ::chart::ChartTypeHelper::getDefaultDirectLightColor( !bRealistic, xChartType ) )
        return false;

    sal_Int32 nAmbientColor = 0;
    xDiagramProps->getPropertyValue( C2U( UNO_NAME_3D_SCENE_AMBIENTCOLOR ) ) >>= nAmbientColor;
    if( nAmbientColor != ::chart::ChartTypeHelper::getDefaultAmbientLightColor( !bRealistic, xChartType ) )
        return false;

    drawing::Direction3D aDirection(0,0,0);
    xDiagramProps->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2 ) ) >>= aDirection;

    drawing::Direction3D aDefaultDirection( bRealistic
        ? ChartTypeHelper::getDefaultRealisticLightDirection(xChartType)
        : ChartTypeHelper::getDefaultSimpleLightDirection(xChartType) );

    //rotate default light direction when right angled axes are off but supported
    {
        sal_Bool bRightAngledAxes = sal_False;
        xDiagramProps->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes;
        if(!bRightAngledAxes)
        {
            if( ChartTypeHelper::isSupportingRightAngledAxes( 
                    DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
            {
                ::basegfx::B3DHomMatrix aRotation( lcl_getCompleteRotationMatrix( xDiagramProps ) );
                BaseGFXHelper::ReduceToRotationMatrix( aRotation );
                ::basegfx::B3DVector aLightVector( BaseGFXHelper::Direction3DToB3DVector( aDefaultDirection ) );
                aLightVector = aRotation*aLightVector;
                aDefaultDirection = BaseGFXHelper::B3DVectorToDirection3D( aLightVector );
            }
        }
    }

    return lcl_isEqual( aDirection, aDefaultDirection );
}

bool lcl_isRealisticLightScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps )
{
    return lcl_isLightScheme( xDiagramProps, true /*bRealistic*/ );
}
bool lcl_isSimpleLightScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps )
{
    return lcl_isLightScheme( xDiagramProps, false /*bRealistic*/ );
}
void lcl_setLightsForScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps, const ThreeDLookScheme& rScheme )
{
    if(!xDiagramProps.is())
        return;
    if( rScheme == ThreeDLookScheme_Unknown)
        return;

    xDiagramProps->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_2 ), uno::makeAny( sal_True ) );

    uno::Reference< chart2::XDiagram > xDiagram( xDiagramProps, uno::UNO_QUERY );
    uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
    uno::Any aADirection( uno::makeAny( rScheme == ThreeDLookScheme_Simple
        ? ChartTypeHelper::getDefaultSimpleLightDirection(xChartType)
        : ChartTypeHelper::getDefaultRealisticLightDirection(xChartType) ) );

    xDiagramProps->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2 ), aADirection );
    //rotate light direction when right angled axes are off but supported
    {
        sal_Bool bRightAngledAxes = sal_False;
        xDiagramProps->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes;
        if(!bRightAngledAxes)
        {
            if( ChartTypeHelper::isSupportingRightAngledAxes( xChartType ) )
            {
                ::basegfx::B3DHomMatrix aRotation( lcl_getCompleteRotationMatrix( xDiagramProps ) );
                BaseGFXHelper::ReduceToRotationMatrix( aRotation );
                lcl_RotateLightSource( xDiagramProps, C2U("D3DSceneLightDirection2"), C2U("D3DSceneLightOn2"), aRotation );
            }
        }
    }

    sal_Int32 nColor = ::chart::ChartTypeHelper::getDefaultDirectLightColor( rScheme==ThreeDLookScheme_Simple, xChartType );
    xDiagramProps->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_2 ), uno::makeAny( nColor ) );

    sal_Int32 nAmbientColor = ::chart::ChartTypeHelper::getDefaultAmbientLightColor( rScheme==ThreeDLookScheme_Simple, xChartType );
    xDiagramProps->setPropertyValue( C2U( UNO_NAME_3D_SCENE_AMBIENTCOLOR ), uno::makeAny( nAmbientColor ) );
}

bool lcl_isRealisticScheme( drawing::ShadeMode aShadeMode
                    , sal_Int32 nRoundedEdges
                    , sal_Int32 nObjectLines )
{
    if(aShadeMode!=drawing::ShadeMode_SMOOTH)
        return false;
    if(nRoundedEdges!=5)
        return false;
    if(nObjectLines!=0)
        return false;
    return true;
}

bool lcl_isSimpleScheme( drawing::ShadeMode aShadeMode
                    , sal_Int32 nRoundedEdges
                    , sal_Int32 nObjectLines
                    , const uno::Reference< XDiagram >& xDiagram )
{
    if(aShadeMode!=drawing::ShadeMode_FLAT)
        return false;
    if(nRoundedEdges!=0)
        return false;
    if(nObjectLines==0)
    {
        uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );    
        return ChartTypeHelper::noBordersForSimpleScheme( xChartType );
    }
    if(nObjectLines!=1)
        return false;
    return true;
}

void lcl_setRealisticScheme( drawing::ShadeMode& rShadeMode
                    , sal_Int32& rnRoundedEdges
                    , sal_Int32& rnObjectLines )
{
    rShadeMode = drawing::ShadeMode_SMOOTH;
    rnRoundedEdges = 5;
    rnObjectLines = 0;
}

void lcl_setSimpleScheme( drawing::ShadeMode& rShadeMode
                    , sal_Int32& rnRoundedEdges
                    , sal_Int32& rnObjectLines
                    , const uno::Reference< XDiagram >& xDiagram )
{
    rShadeMode = drawing::ShadeMode_FLAT;
    rnRoundedEdges = 0;

    uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );    
    rnObjectLines = ChartTypeHelper::noBordersForSimpleScheme( xChartType ) ? 0 : 1;
}

} //end anonymous namespace


drawing::CameraGeometry ThreeDHelper::getDefaultCameraGeometry( bool bPie )
{
    // ViewReferencePoint (Point on the View plane)
    drawing::Position3D vrp(17634.6218373783, 10271.4823817647, 24594.8639082739);
    // ViewPlaneNormal (Normal to the View Plane)
    drawing::Direction3D vpn(0.416199821709347, 0.173649045905254, 0.892537795986984);
    // ViewUpVector (determines the v-axis direction on the view plane as
    // projection of VUP parallel to VPN onto th view pane)
    drawing::Direction3D vup(-0.0733876362771618, 0.984807599917971, -0.157379306090273);

    if( bPie )
    {
        vrp = drawing::Position3D( 0.0, 0.0, 87591.2408759124 );//--> 5 percent perspecitve
        vpn = drawing::Direction3D( 0.0, 0.0, 1.0 );
        vup = drawing::Direction3D( 0.0, 1.0, 0.0 );
    }

    return drawing::CameraGeometry( vrp, vpn, vup );
}

namespace
{
::basegfx::B3DHomMatrix lcl_getCameraMatrix( const uno::Reference< beans::XPropertySet >& xSceneProperties )
{
    drawing::HomogenMatrix aCameraMatrix;

    drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
    if( xSceneProperties.is() )
        xSceneProperties->getPropertyValue( C2U( "D3DCameraGeometry" ) ) >>= aCG;

    ::basegfx::B3DVector aVPN( BaseGFXHelper::Direction3DToB3DVector( aCG.vpn ) );
    ::basegfx::B3DVector aVUP( BaseGFXHelper::Direction3DToB3DVector( aCG.vup ) );

    //normalize vectors:
    aVPN.normalize();
    aVUP.normalize();

    ::basegfx::B3DVector aCross = ::basegfx::cross( aVUP, aVPN );

    //first line is VUP x VPN
    aCameraMatrix.Line1.Column1 = aCross[0];
    aCameraMatrix.Line1.Column2 = aCross[1];
    aCameraMatrix.Line1.Column3 = aCross[2];
    aCameraMatrix.Line1.Column4 = 0.0;

    //second line is VUP
    aCameraMatrix.Line2.Column1 = aVUP[0];
    aCameraMatrix.Line2.Column2 = aVUP[1];
    aCameraMatrix.Line2.Column3 = aVUP[2];
    aCameraMatrix.Line2.Column4 = 0.0;

    //third line is VPN
    aCameraMatrix.Line3.Column1 = aVPN[0];
    aCameraMatrix.Line3.Column2 = aVPN[1];
    aCameraMatrix.Line3.Column3 = aVPN[2];
    aCameraMatrix.Line3.Column4 = 0.0;

    //fourth line is 0 0 0 1
    aCameraMatrix.Line4.Column1 = 0.0;
    aCameraMatrix.Line4.Column2 = 0.0;
    aCameraMatrix.Line4.Column3 = 0.0;
    aCameraMatrix.Line4.Column4 = 1.0;

    return BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aCameraMatrix );
}

double lcl_shiftAngleToIntervalMinusPiToPi( double fAngleRad )
{
    //valid range:  ]-Pi,Pi]
    while( fAngleRad<=-F_PI )
        fAngleRad+=(2*F_PI);
    while( fAngleRad>F_PI )
        fAngleRad-=(2*F_PI);
    return fAngleRad;
}

void lcl_shiftAngleToIntervalMinus180To180( sal_Int32& rnAngleDegree )
{
    //valid range:  ]-180,180]
    while( rnAngleDegree<=-180 )
        rnAngleDegree+=360;
    while( rnAngleDegree>180 )
        rnAngleDegree-=360;
}

void lcl_shiftAngleToIntervalZeroTo360( sal_Int32& rnAngleDegree )
{
    //valid range:  [0,360[
    while( rnAngleDegree<0 )
        rnAngleDegree+=360;
    while( rnAngleDegree>=360 )
        rnAngleDegree-=360;
}

void lcl_ensureIntervalMinus1To1( double& rSinOrCos )
{
    if (rSinOrCos < -1.0)
       rSinOrCos = -1.0;
    else if (rSinOrCos > 1.0)
        rSinOrCos = 1.0;
}

bool lcl_isSinZero( double fAngleRad )
{
    return ::basegfx::fTools::equalZero( sin(fAngleRad), 0.0000001 );
}
bool lcl_isCosZero( double fAngleRad )
{
    return ::basegfx::fTools::equalZero( cos(fAngleRad), 0.0000001 );
}

}

void ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
    sal_Int32 nElevationDeg, sal_Int32 nRotationDeg,
    double& rfXAngleRad, double& rfYAngleRad, double& rfZAngleRad)
{
    // for a description of the algorithm see issue 72994
    //http://www.openoffice.org/issues/show_bug.cgi?id=72994
    //http://www.openoffice.org/nonav/issues/showattachment.cgi/50608/DescriptionCorrected.odt

    lcl_shiftAngleToIntervalZeroTo360( nElevationDeg );
    lcl_shiftAngleToIntervalZeroTo360( nRotationDeg );

    double& x = rfXAngleRad;
    double& y = rfYAngleRad;
    double& z = rfZAngleRad;

    double E = F_PI*nElevationDeg/180; //elevation in Rad
    double R = F_PI*nRotationDeg/180; //rotation in Rad
    
    if( (nRotationDeg == 0 || nRotationDeg == 180 )
        && ( nElevationDeg == 90 || nElevationDeg == 270 ) )
    {
        //sR==0 && cE==0
        z = 0.0;
        //element 23
        double f23 = cos(R)*sin(E);
        if(f23>0)
            x = F_PI/2;
        else
            x = -F_PI/2;
        y = R;
    }
    else if( ( nRotationDeg == 90 || nRotationDeg == 270 )
        && ( nElevationDeg == 90 || nElevationDeg == 270 ) )
    {
        //cR==0 && cE==0
        z = F_PI/2;
        if( sin(R)>0 )
            x = F_PI/2.0;
        else
            x = -F_PI/2.0;

        if( (sin(R)*sin(E))>0 )
            y = 0.0;
        else
            y = F_PI;
    }
    else if( (nRotationDeg == 0 || nRotationDeg == 180 )
        && ( nElevationDeg == 0 || nElevationDeg == 180 ) )
    {
        //sR==0 && sE==0
        z = 0.0;
        y = R;
        x = E;
    }
    else if( ( nRotationDeg == 90 || nRotationDeg == 270 )
        && ( nElevationDeg == 0 || nElevationDeg == 180 ) )
    {
        //cR==0 && sE==0
        z = 0.0;

        if( (sin(R)/cos(E))>0 )
            y = F_PI/2;
        else
            y = -F_PI/2;

        if( (cos(E))>0 )
            x = 0;
        else
            x = F_PI;
    }
    else if ( nElevationDeg == 0 || nElevationDeg == 180 )
    {
        //sR!=0 cR!=0 sE==0
        z = 0.0;
        x = E;
        y = R;
        //use element 13 for sign
        if((cos(x)*sin(y)*sin(R))<0.0)
            y *= -1.0;
    }
    else if ( nElevationDeg == 90 || nElevationDeg == 270 )
    {
        //sR!=0 cR!=0 cE==0
        //element 12 + 22 --> y=0 or F_PI and x=+-F_PI/2
        //-->element 13/23:
        z = atan(sin(R)/(cos(R)*sin(E)));
        //use element 13 for sign for x
        if( (sin(R)*sin(z))>0.0 )
            x = F_PI/2;
        else
            x = -F_PI/2;
        //use element 21 for y
        if( (sin(R)*sin(E)*sin(z))>0.0)
            y = 0.0;
        else
            y = F_PI;
    }
    else if ( nRotationDeg == 0 || nRotationDeg == 180 )
    {
        //sE!=0 cE!=0 sR==0
        z = 0.0;
        x = E;
        y = R;
        double f23 = cos(R)*sin(E);
        if( (f23 * sin(x)) < 0.0 ) 
            x *= -1.0; //todo ??
    }
    else if (nRotationDeg == 90 || nRotationDeg == 270)
    {
        //sE!=0 cE!=0 cR==0
        //z = +- F_PI/2;
        //x = +- F_PI/2;
        z = F_PI/2;
        x = F_PI/2;
        double sR = sin(R);
        if( sR<0.0 )
            x *= -1.0; //different signs for x and z

        //use element 21:
        double cy = sR*sin(E)/sin(z);
        lcl_ensureIntervalMinus1To1(cy);
        y = acos(cy);

        //use element 22 for sign:
        if( (sin(x)*sin(y)*sin(z)*cos(E))<0.0)
            y *= -1.0;
    }
    else
    {
        z = atan(tan(R) * sin(E));
        if(cos(z)==0.0)
        {
            DBG_ERROR("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
            return;
        }
        double cy = cos(R)/cos(z);
        lcl_ensureIntervalMinus1To1(cy);
        y = acos(cy);
        
        //element 12 in 23
        double fDenominator = cos(z)*(1.0-pow(sin(y),2));
        if(fDenominator==0.0)
        {
            DBG_ERROR("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
            return;
        }
        double sx = cos(R)*sin(E)/fDenominator;
        lcl_ensureIntervalMinus1To1(sx);
        x = asin( sx );

        //use element 13 for sign:
        double f13a = cos(x)*cos(z)*sin(y);
        double f13b = sin(R)-sx*sin(z);
        if( (f13b*f13a)<0.0 )
        {
            //change x or y
            //use element 22 for further investigations:
            //try
            y *= -1;
            double f22a = cos(x)*cos(z);
            double f22b = cos(E)-(sx*sin(y)*sin(z));
            if( (f22a*f22b)<0.0 )
            {
                y *= -1;
                x=(F_PI-x);
            }
        }
        else
        {
            //change nothing or both
            //use element 22 for further investigations:
            double f22a = cos(x)*cos(z);
            double f22b = cos(E)-(sx*sin(y)*sin(z));
            if( (f22a*f22b)<0.0 )
            {
                y *= -1;
                x=(F_PI-x);
            }
        }
    }
}

void ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
    sal_Int32& rnElevationDeg, sal_Int32& rnRotationDeg,
    double fXRad, double fYRad, double fZRad)
{
    // for a description of the algorithm see issue 72994
    //http://www.openoffice.org/issues/show_bug.cgi?id=72994
    //http://www.openoffice.org/nonav/issues/showattachment.cgi/50608/DescriptionCorrected.odt

    double R = 0.0; //Rotation in Rad
    double E = 0.0; //Elevation in Rad

    double& x = fXRad;
    double& y = fYRad;
    double& z = fZRad;
    
    double f11 = cos(y)*cos(z);

    if( lcl_isSinZero(y) )
    {
        //siny == 0

        if( lcl_isCosZero(x) )
        {
            //siny == 0 && cosx == 0

            if( lcl_isSinZero(z) )
            {
                //siny == 0 && cosx == 0 && sinz == 0
                //example: x=+-90 y=0oder180 z=0(oder180)

                //element 13+11
                if( f11 > 0 )
                    R = 0.0;
                else
                    R = F_PI;

                //element 23
                double f23 = cos(z)*sin(x) / cos(R);
                if( f23 > 0 )
                    E = F_PI/2.0;
                else
                    E = -F_PI/2.0;
            }
            else if( lcl_isCosZero(z) )
            {
                //siny == 0 && cosx == 0 && cosz == 0
                //example: x=+-90 y=0oder180 z=+-90

                double f13 = sin(x)*sin(z);
                //element 13+11
                if( f13 > 0 )
                    R = F_PI/2.0;
                else
                    R = -F_PI/2.0;

                //element 21
                double f21 = cos(y)*sin(z) / sin(R);
                if( f21 > 0 )
                    E = F_PI/2.0;
                else
                    E = -F_PI/2.0;
            }
            else
            {
                //siny == 0 && cosx == 0 && cosz != 0 && sinz != 0
                //element 11 && 13
                double f13 = sin(x)*sin(z);
                R = atan( f13/f11 );

                if(f11<0)
                    R+=F_PI;

                //element 23
                double f23 = cos(z)*sin(x);
                if( f23/cos(R) > 0 )
                    E = F_PI/2.0;
                else
                    E = -F_PI/2.0;
            }
        }
        else if( lcl_isSinZero(x) )
        {
            //sinY==0 sinX==0
            //element 13+11
            if( f11 > 0 )
                R = 0.0;
            else
                R = F_PI;

            double f22 = cos(x)*cos(z);
            if( f22 > 0 )
                E = 0.0;
            else
                E = F_PI;
        }
        else if( lcl_isSinZero(z) )
        {
            //sinY==0 sinZ==0 sinx!=0 cosx!=0 
            //element 13+11
            if( f11 > 0 )
                R = 0.0;
            else
                R = F_PI;

            //element 22 && 23
            double f22 = cos(x)*cos(z);
            double f23 = cos(z)*sin(x);
            E = atan( f23/(f22*cos(R)) );
            if( (f22*cos(E))<0 )
                E+=F_PI;
        }
        else if( lcl_isCosZero(z) )
        {
            //sinY == 0 && cosZ == 0 && cosx != 0 && sinx != 0
            double f13 = sin(x)*sin(z);
            //element 13+11
            if( f13 > 0 )
                R = F_PI/2.0;
            else
                R = -F_PI/2.0;

            //element 21+22
            double f21 = cos(y)*sin(z);
            if( f21/sin(R) > 0 )
                E = F_PI/2.0;
            else
                E = -F_PI/2.0;
        }
        else
        {
            //sinY == 0 && all other !=0
            double f13 = sin(x)*sin(z);
            R = atan( f13/f11 );
            if( (f11*cos(R))<0.0 )
                R+=F_PI;

            double f22 = cos(x)*cos(z);
            if( !lcl_isCosZero(R) )
                E = atan( cos(z)*sin(x) /( f22*cos(R) ) );
            else
                E = atan( cos(y)*sin(z) /( f22*sin(R) ) );
            if( (f22*cos(E))<0 )
                E+=F_PI;
        }
    }
    else if( lcl_isCosZero(y) )
    {
        //cosY==0

        double f13 = sin(x)*sin(z)+cos(x)*cos(z)*sin(y);
        if( f13 >= 0 )
            R = F_PI/2.0;
        else
            R = -F_PI/2.0;

        double f22 = cos(x)*cos(z)+sin(x)*sin(y)*sin(z);
        if( f22 >= 0 )
            E = 0.0;
        else
            E = F_PI;
    }
    else if( lcl_isSinZero(x) )
    {
        //cosY!=0 sinY!=0 sinX=0
        if( lcl_isSinZero(z) )
        {
            //cosY!=0 sinY!=0 sinX=0 sinZ=0
            double f13 = cos(x)*cos(z)*sin(y);
            R = atan( f13/f11 );
            //R = asin(f13);
            if( f11<0 )
                R+=F_PI;

            double f22 = cos(x)*cos(z);
            if( f22>0 )
                E = 0.0;
            else
                E = F_PI;
        }
        else if( lcl_isCosZero(z) )
        {
            //cosY!=0 sinY!=0 sinX=0 cosZ=0
            R = x;
            E = y;//or -y
            //use 23 for 'signs'
            double f23 =  -1.0*cos(x)*sin(y)*sin(z);
            if( (f23*cos(R)*sin(E))<0.0 )
            {
                //change R or E
                E = -y;
            }
        }
        else
        {
            //cosY!=0 sinY!=0 sinX=0 sinZ!=0 cosZ!=0
            double f13 = cos(x)*cos(z)*sin(y);
            R = atan( f13/f11 );
            
            if( f11<0 )
                R+=F_PI;

            double f21 = cos(y)*sin(z);
            double f22 = cos(x)*cos(z);
            E = atan(f21/(f22*sin(R)) );

            if( (f22*cos(E))<0.0 )
                E+=F_PI;
        }
    }
    else if( lcl_isCosZero(x) )
    {
        //cosY!=0 sinY!=0 cosX=0

        if( lcl_isSinZero(z) )
        {
            //cosY!=0 sinY!=0 cosX=0 sinZ=0
            R=0;//13 -> R=0 or F_PI
            if( f11<0.0 )
                R=F_PI;
            E=F_PI/2;//22 -> E=+-F_PI/2
            //use element 11 and 23 for sign
            double f23 = cos(z)*sin(x);
            if( (f11*f23*sin(E))<0.0 )
                E=-F_PI/2.0;
        }
        else if( lcl_isCosZero(z) )
        {
            //cosY!=0 sinY!=0 cosX=0 cosZ=0
            //element 11 & 13:
            if( (sin(x)*sin(z))>0.0 )
                R=F_PI/2.0;
            else
                R=-F_PI/2.0;
            //element 22:
            E=acos( sin(x)*sin(y)*sin(z));
            //use element 21 for sign:
            if( (cos(y)*sin(z)*sin(R)*sin(E))<0.0 )
                E*=-1.0;
        }
        else
        {
            //cosY!=0 sinY!=0 cosX=0 sinZ!=0 cosZ!=0
            //element 13/11
            R = atan( sin(x)*sin(z)/(cos(y)*cos(z)) );
            //use 13 for 'sign'
            if( (sin(x)*sin(z))<0.0 )
                R += F_PI;
            //element 22
            E = acos(sin(x)*sin(y)*sin(z) );
            //use 21 for sign
            if( (cos(y)*sin(z)*sin(R)*sin(E))<0.0 )
                E*=-1.0;
        }
    }
    else if( lcl_isSinZero(z) )
    {
        //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ=0
        //element 11
        R=y;
        //use elenment 13 for sign
        if( (cos(x)*cos(z)*sin(y)*sin(R))<0.0 )
            R*=-1.0;
        //element 22
        E = acos( cos(x)*cos(z) );
        //use element 23 for sign
        if( (cos(z)*sin(x)*cos(R)*sin(E))<0.0 )
            E*=-1.0;
    }
    else if( lcl_isCosZero(z) )
    {
        //cosY!=0 sinY!=0 sinX!=0 cosX!=0 cosZ=0
        //element 21/23
        R=atan(-cos(y)/(cos(x)*sin(y)));
        //use element 13 for 'sign'
        if( (sin(x)*sin(z)*sin(R))<0.0 )
            R+=F_PI;
        //element 21/22
        E=atan( cos(y)*sin(z)/(sin(R)*sin(x)*sin(y)*sin(z)) );
        //use element 23 for 'sign'
        if( (-cos(x)*sin(y)*sin(z)*cos(R)*sin(E))<0.0 )
            E+=F_PI;
    }
    else
    {
        //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ!=0 cosZ!=0
        //13/11:
        double f13 = sin(x)*sin(z)+cos(x)*cos(z)*sin(y);
        R = atan( f13/ f11 );
        if(f11<0.0)
            R+=F_PI;
        double f22 = cos(x)*cos(z)+sin(x)*sin(y)*sin(z);
        double f23 = cos(x)*sin(y)*sin(z)-cos(z)*sin(x);
        //23/22:
        E = atan( -1.0*f23/(f22*cos(R)) );
        if(f22<0.0)
            E+=F_PI;
    }
    
    rnElevationDeg = ::basegfx::fround( BaseGFXHelper::Rad2Deg( E ) );
    rnRotationDeg = ::basegfx::fround( BaseGFXHelper::Rad2Deg( R ) );
}

double ThreeDHelper::getValueClippedToRange( double fAngle, const double& fPositivLimit )
{
    if( fAngle<-1*fPositivLimit )
        fAngle=-1*fPositivLimit;
    else if( fAngle>fPositivLimit )
        fAngle=fPositivLimit;
    return fAngle;
}

double ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()
{
    return 90.0;
}

double ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()
{
    return 45.0;
}

void ThreeDHelper::adaptRadAnglesForRightAngledAxes( double& rfXAngleRad, double& rfYAngleRad )
{
    rfXAngleRad = ThreeDHelper::getValueClippedToRange(rfXAngleRad, BaseGFXHelper::Deg2Rad(ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()) );
    rfYAngleRad = ThreeDHelper::getValueClippedToRange(rfYAngleRad, BaseGFXHelper::Deg2Rad(ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()) );
}

void ThreeDHelper::getRotationAngleFromDiagram(
        const Reference< beans::XPropertySet >& xSceneProperties, double& rfXAngleRad, double& rfYAngleRad, double& rfZAngleRad )
{
    //takes the camera and the transformation matrix into account

    rfXAngleRad = rfYAngleRad = rfZAngleRad = 0.0;

    if( !xSceneProperties.is() )
        return;

    //get camera rotation
    ::basegfx::B3DHomMatrix aFixCameraRotationMatrix( lcl_getCameraMatrix( xSceneProperties ) );
    BaseGFXHelper::ReduceToRotationMatrix( aFixCameraRotationMatrix );

    //get scene rotation
    ::basegfx::B3DHomMatrix aSceneRotation;
    {
        drawing::HomogenMatrix aHomMatrix;
        if( xSceneProperties->getPropertyValue( C2U("D3DTransformMatrix")) >>= aHomMatrix )
        {
            aSceneRotation = BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aHomMatrix );
            BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation );
        }
    }

    ::basegfx::B3DHomMatrix aResultRotation = aFixCameraRotationMatrix * aSceneRotation;
    ::basegfx::B3DTuple aRotation( BaseGFXHelper::GetRotationFromMatrix( aResultRotation ) );

    rfXAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getX());
    rfYAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getY());
    rfZAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getZ());

    if(rfZAngleRad<(-F_PI/2) || rfZAngleRad>(F_PI/2))
    {
        rfZAngleRad-=F_PI;
        rfXAngleRad-=F_PI;
        rfYAngleRad=(F_PI-rfYAngleRad);

        rfXAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfXAngleRad);
        rfYAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfYAngleRad);
        rfZAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfZAngleRad);
    }
}

void ThreeDHelper::switchRightAngledAxes( const Reference< beans::XPropertySet >& xSceneProperties, sal_Bool bRightAngledAxes, bool bRotateLights )
{
    try
    {
        if( xSceneProperties.is() )
        {
            sal_Bool bOldRightAngledAxes = sal_False;
            xSceneProperties->getPropertyValue( C2U("RightAngledAxes")) >>= bOldRightAngledAxes;
            if( bOldRightAngledAxes!=bRightAngledAxes)
            {
                xSceneProperties->setPropertyValue( C2U("RightAngledAxes"), uno::makeAny( bRightAngledAxes ));
                if( bRotateLights )
                {
                    if(bRightAngledAxes)
                    {
                        ::basegfx::B3DHomMatrix aInverseRotation( lcl_getInverseRotationMatrix( xSceneProperties ) );
                        lcl_rotateLights( aInverseRotation, xSceneProperties );
                    }
                    else
                    {
                        ::basegfx::B3DHomMatrix aCompleteRotation( lcl_getCompleteRotationMatrix( xSceneProperties ) );
                        lcl_rotateLights( aCompleteRotation, xSceneProperties );
                    }
                }
            }
        }
    }
    catch( const uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }
}

void ThreeDHelper::setRotationAngleToDiagram(
    const Reference< beans::XPropertySet >& xSceneProperties
        , double fXAngleRad, double fYAngleRad, double fZAngleRad )
{
    //the rotation of the camera is not touched but taken into account
    //the rotation difference is applied to the transformation matrix

    //the light sources will be adapted also

    if( !xSceneProperties.is() )
        return;

    try
    {
        //remind old rotation for adaption of light directions
        ::basegfx::B3DHomMatrix aInverseOldRotation( lcl_getInverseRotationMatrix( xSceneProperties ) );
        
        ::basegfx::B3DHomMatrix aInverseCameraRotation;
        {
            ::basegfx::B3DTuple aR( BaseGFXHelper::GetRotationFromMatrix(
                    lcl_getCameraMatrix( xSceneProperties ) ) );
            aInverseCameraRotation.rotate( 0.0, 0.0, -aR.getZ() );
            aInverseCameraRotation.rotate( 0.0, -aR.getY(), 0.0 );
            aInverseCameraRotation.rotate( -aR.getX(), 0.0, 0.0 );
        }

        ::basegfx::B3DHomMatrix aCumulatedRotation;
        aCumulatedRotation.rotate( fXAngleRad, fYAngleRad, fZAngleRad );

        //calculate new scene matrix
        ::basegfx::B3DHomMatrix aSceneRotation = aInverseCameraRotation*aCumulatedRotation;
        BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation );

        //set new rotation to transformation matrix
        xSceneProperties->setPropertyValue(
            C2U("D3DTransformMatrix"), uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation )));

        //rotate lights if RightAngledAxes are not set or not supported
        sal_Bool bRightAngledAxes = sal_False;
        xSceneProperties->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes;
        uno::Reference< chart2::XDiagram > xDiagram( xSceneProperties, uno::UNO_QUERY );
        if(!bRightAngledAxes || !ChartTypeHelper::isSupportingRightAngledAxes( 
                    DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
        {
            ::basegfx::B3DHomMatrix aNewRotation;
            aNewRotation.rotate( fXAngleRad, fYAngleRad, fZAngleRad );
            lcl_rotateLights( aNewRotation*aInverseOldRotation, xSceneProperties );
        }
    }
    catch( const uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }
}

void ThreeDHelper::getRotationFromDiagram( const uno::Reference< beans::XPropertySet >& xSceneProperties
            , sal_Int32& rnHorizontalAngleDegree, sal_Int32& rnVerticalAngleDegree )
{
    double fXAngle, fYAngle, fZAngle;
    ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngle, fYAngle, fZAngle );

    if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    {
        ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
            rnHorizontalAngleDegree, rnVerticalAngleDegree, fXAngle, fYAngle, fZAngle);
        rnVerticalAngleDegree*=-1;
    }
    else
    {
        fXAngle = BaseGFXHelper::Rad2Deg( fXAngle );
        fYAngle = BaseGFXHelper::Rad2Deg( fYAngle );
        fZAngle = BaseGFXHelper::Rad2Deg( fZAngle );

        rnHorizontalAngleDegree = ::basegfx::fround(fXAngle);
        rnVerticalAngleDegree = ::basegfx::fround(-1.0*fYAngle);
        //nZRotation = ::basegfx::fround(-1.0*fZAngle);
    }

    lcl_shiftAngleToIntervalMinus180To180( rnHorizontalAngleDegree );
    lcl_shiftAngleToIntervalMinus180To180( rnVerticalAngleDegree );
}

void ThreeDHelper::setRotationToDiagram( const uno::Reference< beans::XPropertySet >& xSceneProperties
            , sal_Int32 nHorizontalAngleDegree, sal_Int32 nVerticalYAngleDegree )
{
    //todo: x and y is not equal to horz and vert in case of RightAngledAxes==false
    double fXAngle = BaseGFXHelper::Deg2Rad( nHorizontalAngleDegree );
    double fYAngle = BaseGFXHelper::Deg2Rad( -1*nVerticalYAngleDegree );
    double fZAngle = 0.0;

    if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
        ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
            nHorizontalAngleDegree, -1*nVerticalYAngleDegree, fXAngle, fYAngle, fZAngle );

    ThreeDHelper::setRotationAngleToDiagram( xSceneProperties, fXAngle, fYAngle, fZAngle );
}

void ThreeDHelper::getCameraDistanceRange( double& rfMinimumDistance, double& rfMaximumDistance )
{
    rfMinimumDistance = 3.0/4.0*FIXED_SIZE_FOR_3D_CHART_VOLUME;//empiric value
    rfMaximumDistance = 20.0*FIXED_SIZE_FOR_3D_CHART_VOLUME;//empiric value
}

void ThreeDHelper::ensureCameraDistanceRange( double& rfCameraDistance )
{
    double fMin, fMax;
    getCameraDistanceRange( fMin, fMax );
    if( rfCameraDistance < fMin )
        rfCameraDistance = fMin;
    if( rfCameraDistance > fMax )
        rfCameraDistance = fMax;
}

double ThreeDHelper::getCameraDistance(
        const Reference< beans::XPropertySet >& xSceneProperties )
{
    double fCameraDistance = FIXED_SIZE_FOR_3D_CHART_VOLUME;

    if( !xSceneProperties.is() )
        return fCameraDistance;

    try
    {
        drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
        xSceneProperties->getPropertyValue( C2U( "D3DCameraGeometry" ) ) >>= aCG;
        ::basegfx::B3DVector aVRP( BaseGFXHelper::Position3DToB3DVector( aCG.vrp ) );
        fCameraDistance = aVRP.getLength();

        ensureCameraDistanceRange( fCameraDistance );
    }
    catch( const uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }
    return fCameraDistance;
}

void ThreeDHelper::setCameraDistance(
        const Reference< beans::XPropertySet >& xSceneProperties, double fCameraDistance )
{
    if( !xSceneProperties.is() )
        return;

    try
    {
        if( fCameraDistance <= 0 )
            fCameraDistance = FIXED_SIZE_FOR_3D_CHART_VOLUME;

        drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
        xSceneProperties->getPropertyValue( C2U( "D3DCameraGeometry" ) ) >>= aCG;
        ::basegfx::B3DVector aVRP( BaseGFXHelper::Position3DToB3DVector( aCG.vrp ) );
        if( ::basegfx::fTools::equalZero( aVRP.getLength() ) )
            aVRP = ::basegfx::B3DVector(0,0,1);
        aVRP.setLength(fCameraDistance);
        aCG.vrp = BaseGFXHelper::B3DVectorToPosition3D( aVRP );

        xSceneProperties->setPropertyValue( C2U("D3DCameraGeometry"), uno::makeAny( aCG ));
    }
    catch( const uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }
}

double ThreeDHelper::CameraDistanceToPerspective( double fCameraDistance )
{
    double fRet = fCameraDistance;
    double fMin, fMax;
    ThreeDHelper::getCameraDistanceRange( fMin, fMax );
    //fMax <-> 0; fMin <->100
    //a/x + b = y
    double a = 100.0*fMax*fMin/(fMax-fMin);
    double b = -a/fMax;

    fRet = a/fCameraDistance + b;

    return fRet;
}

double ThreeDHelper::PerspectiveToCameraDistance( double fPerspective )
{
    double fRet = fPerspective;
    double fMin, fMax;
    ThreeDHelper::getCameraDistanceRange( fMin, fMax );
    //fMax <-> 0; fMin <->100
    //a/x + b = y
    double a = 100.0*fMax*fMin/(fMax-fMin);
    double b = -a/fMax;

    fRet = a/(fPerspective - b);

    return fRet;
}

ThreeDLookScheme ThreeDHelper::detectScheme( const uno::Reference< XDiagram >& xDiagram )
{
    ThreeDLookScheme aScheme = ThreeDLookScheme_Unknown;

    sal_Int32 nRoundedEdges;
    sal_Int32 nObjectLines;
    ThreeDHelper::getRoundedEdgesAndObjectLines( xDiagram, nRoundedEdges, nObjectLines );

    //get shade mode and light settings:
    drawing::ShadeMode aShadeMode( drawing::ShadeMode_SMOOTH );
    uno::Reference< beans::XPropertySet > xDiagramProps( xDiagram, uno::UNO_QUERY );
    try
    {
        if( xDiagramProps.is() )
            xDiagramProps->getPropertyValue( C2U( "D3DSceneShadeMode" ) )>>= aShadeMode;
    }
    catch( uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }

    if( lcl_isSimpleScheme( aShadeMode, nRoundedEdges, nObjectLines, xDiagram ) )
    {
        if( lcl_isSimpleLightScheme(xDiagramProps) )
            aScheme = ThreeDLookScheme_Simple;
    }
    else if( lcl_isRealisticScheme( aShadeMode, nRoundedEdges, nObjectLines ) )
    {
        if( lcl_isRealisticLightScheme(xDiagramProps) )
            aScheme = ThreeDLookScheme_Realistic;
    }

    return aScheme;
}

void ThreeDHelper::setScheme( const uno::Reference< XDiagram >& xDiagram, ThreeDLookScheme aScheme )
{
    if( aScheme == ThreeDLookScheme_Unknown )
        return;

    drawing::ShadeMode aShadeMode;
    sal_Int32 nRoundedEdges;
    sal_Int32 nObjectLines;

    if( aScheme == ThreeDLookScheme_Simple )
        lcl_setSimpleScheme(aShadeMode,nRoundedEdges,nObjectLines,xDiagram);
    else
        lcl_setRealisticScheme(aShadeMode,nRoundedEdges,nObjectLines);

    try
    {
        ThreeDHelper::setRoundedEdgesAndObjectLines( xDiagram, nRoundedEdges, nObjectLines );

        uno::Reference< beans::XPropertySet > xProp( xDiagram, uno::UNO_QUERY );
        if( xProp.is() )
        {
            drawing::ShadeMode aOldShadeMode;
            if( ! ( (xProp->getPropertyValue( C2U( "D3DSceneShadeMode" ) )>>=aOldShadeMode) &&
                    aOldShadeMode == aShadeMode ))
            {
                xProp->setPropertyValue( C2U( "D3DSceneShadeMode" ), uno::makeAny( aShadeMode ));
            }
        }

        lcl_setLightsForScheme( xProp, aScheme );
    }
    catch( uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }

}

void ThreeDHelper::set3DSettingsToDefault( const uno::Reference< beans::XPropertySet >& xSceneProperties )
{
    Reference< beans::XPropertyState > xState( xSceneProperties, uno::UNO_QUERY );
    if(xState.is())
    {
        xState->setPropertyToDefault( C2U("D3DSceneDistance"));
        xState->setPropertyToDefault( C2U("D3DSceneFocalLength"));
    }
    ThreeDHelper::setDefaultRotation( xSceneProperties );
    ThreeDHelper::setDefaultIllumination( xSceneProperties );
}

void ThreeDHelper::setDefaultRotation( const uno::Reference< beans::XPropertySet >& xSceneProperties, bool bPieOrDonut )
{
    if( !xSceneProperties.is() )
        return;

    drawing::CameraGeometry aCameraGeo( ThreeDHelper::getDefaultCameraGeometry( bPieOrDonut ) );
    xSceneProperties->setPropertyValue( C2U("D3DCameraGeometry"), uno::makeAny( aCameraGeo ));

    ::basegfx::B3DHomMatrix aSceneRotation;
    if( bPieOrDonut )
        aSceneRotation.rotate( -F_PI/3.0, 0, 0 );
    xSceneProperties->setPropertyValue( C2U("D3DTransformMatrix"),
        uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation )));
}

void ThreeDHelper::setDefaultRotation( const uno::Reference< beans::XPropertySet >& xSceneProperties )
{
    bool bPieOrDonut( DiagramHelper::isPieOrDonutChart( uno::Reference< XDiagram >(xSceneProperties, uno::UNO_QUERY) ) );
    ThreeDHelper::setDefaultRotation( xSceneProperties, bPieOrDonut );
}

void ThreeDHelper::setDefaultIllumination( const uno::Reference< beans::XPropertySet >& xSceneProperties )
{
    if( !xSceneProperties.is() )
        return;

    drawing::ShadeMode aShadeMode( drawing::ShadeMode_SMOOTH );
    try
    {
        xSceneProperties->getPropertyValue( C2U( "D3DSceneShadeMode" ) )>>= aShadeMode;
        xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_1 ), uno::makeAny( sal_False ) );
        xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_3 ), uno::makeAny( sal_False ) );
        xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_4 ), uno::makeAny( sal_False ) );
        xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_5 ), uno::makeAny( sal_False ) );
        xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_6 ), uno::makeAny( sal_False ) );
        xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_7 ), uno::makeAny( sal_False ) );
        xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_8 ), uno::makeAny( sal_False ) );
    }
    catch( uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }

    ThreeDLookScheme aScheme = (drawing::ShadeMode_FLAT==aShadeMode) ? ThreeDLookScheme_Simple : ThreeDLookScheme_Realistic;
    lcl_setLightsForScheme( xSceneProperties, aScheme );
}

void ThreeDHelper::getRoundedEdgesAndObjectLines(
            const uno::Reference< XDiagram > & xDiagram
            , sal_Int32& rnRoundedEdges, sal_Int32& rnObjectLines )
{
    rnRoundedEdges = -1;
    rnObjectLines = -1;
    try
    {
        bool bDifferentRoundedEdges = false;
        bool bDifferentObjectLines = false;

        drawing::LineStyle aLineStyle( drawing::LineStyle_SOLID );

        ::std::vector< uno::Reference< XDataSeries > > aSeriesList(
            DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
        sal_Int32 nSeriesCount = static_cast<sal_Int32>( aSeriesList.size() );

        rtl::OUString aPercentDiagonalPropertyName( C2U( "PercentDiagonal" ) );
        rtl::OUString aBorderStylePropertyName( C2U( "BorderStyle" ) );

        for( sal_Int32 nS = 0; nS < nSeriesCount; ++nS )
        {
		    uno::Reference< XDataSeries > xSeries( aSeriesList[nS] );
            uno::Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
            if(!nS)
            {
                rnRoundedEdges = 0;
                try
                {
                    sal_Int16 nPercentDiagonal = 0;

                    xProp->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
                    rnRoundedEdges = static_cast< sal_Int32 >( nPercentDiagonal );

                    if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
                        , aPercentDiagonalPropertyName, uno::makeAny(nPercentDiagonal) ) )
                        bDifferentRoundedEdges = true;
                }
                catch( uno::Exception& e )
		        {
                    ASSERT_EXCEPTION( e );
                    bDifferentRoundedEdges = true;
                }
                try
                {
                    xProp->getPropertyValue( aBorderStylePropertyName ) >>= aLineStyle;

                    if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
                        , aBorderStylePropertyName, uno::makeAny(aLineStyle) ) )
                        bDifferentObjectLines = true;
                }
                catch( uno::Exception& e )
		        {
                    ASSERT_EXCEPTION( e );
                    bDifferentObjectLines = true;
                }
            }
            else
            {
                if( !bDifferentRoundedEdges )
                {
                    sal_Int16 nPercentDiagonal = 0;
                    xProp->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
                    sal_Int32 nCurrentRoundedEdges = static_cast< sal_Int32 >( nPercentDiagonal );
                    if(nCurrentRoundedEdges!=rnRoundedEdges
                        || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
                            , aPercentDiagonalPropertyName, uno::makeAny( static_cast< sal_Int16 >(rnRoundedEdges) ) ) )
                    {
                        bDifferentRoundedEdges = true;
                        nCurrentRoundedEdges = -1;
                    }
                }
                
                if( !bDifferentObjectLines )
                {
                    drawing::LineStyle aCurrentLineStyle;
                    xProp->getPropertyValue( aBorderStylePropertyName ) >>= aCurrentLineStyle;
                    if(aCurrentLineStyle!=aLineStyle
                        || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
                            , aBorderStylePropertyName, uno::makeAny(aLineStyle) ) )
                        bDifferentObjectLines = true;
                }
            }
            if( bDifferentRoundedEdges && bDifferentObjectLines )
                break;
        }

        //set rnObjectLines
        rnObjectLines = 0;
        if( bDifferentObjectLines )
            rnObjectLines = -1;
        else if( aLineStyle == drawing::LineStyle_SOLID )
            rnObjectLines = 1;
    }
    catch( uno::Exception& e )
	{
        ASSERT_EXCEPTION( e );
    }
}
void ThreeDHelper::setRoundedEdgesAndObjectLines(
            const uno::Reference< XDiagram > & xDiagram
            , sal_Int32 nRoundedEdges, sal_Int32 nObjectLines )
{
    if( (nRoundedEdges<0||nRoundedEdges>100) && nObjectLines!=0 && nObjectLines!=1 )
        return;

    drawing::LineStyle aLineStyle( drawing::LineStyle_NONE );
    if(nObjectLines==1)
        aLineStyle = drawing::LineStyle_SOLID;

    uno::Any aALineStyle( uno::makeAny(aLineStyle));
    uno::Any aARoundedEdges( uno::makeAny( static_cast< sal_Int16 >( nRoundedEdges )));

    ::std::vector< uno::Reference< XDataSeries > > aSeriesList(
        DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
    sal_Int32 nSeriesCount = static_cast<sal_Int32>( aSeriesList.size() );
    for( sal_Int32 nS = 0; nS < nSeriesCount; ++nS )
    {
		uno::Reference< XDataSeries > xSeries( aSeriesList[nS] );

        if( nRoundedEdges>=0 && nRoundedEdges<=100 )
            DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "PercentDiagonal" ), aARoundedEdges );

        if( nObjectLines==0 || nObjectLines==1 )
            DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "BorderStyle" ), aALineStyle );
    }
}

CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( const Reference< beans::XPropertySet >& xSceneProperties )
{
    CuboidPlanePosition eRet(CuboidPlanePosition_Left);

    double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
    ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    {
        ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
        fZAngleRad=0.0;
    }
    if( sin(fYAngleRad)>0.0 )
        eRet = CuboidPlanePosition_Right;
    return eRet;
}

CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( const Reference< beans::XPropertySet >& xSceneProperties )
{
    CuboidPlanePosition eRet(CuboidPlanePosition_Back);

    double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
    ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    {
        ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
        fZAngleRad=0.0;
    }
    if( cos(fXAngleRad)*cos(fYAngleRad)<0.0 )
        eRet = CuboidPlanePosition_Front;
    return eRet;
}

CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( const Reference< beans::XPropertySet >& xSceneProperties )
{
    CuboidPlanePosition eRet(CuboidPlanePosition_Bottom);

    double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
    ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    {
        ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
        fZAngleRad=0.0;
    }
    if( sin(fXAngleRad)*cos(fYAngleRad)<0.0 )
        eRet = CuboidPlanePosition_Top;
    return eRet;
}

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