/**************************************************************
 *
 * 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 perspective
        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
//.............................................................................
