/**************************************************************
 * 
 * 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 "BaseGFXHelper.hxx"
#include <com/sun/star/drawing/DoubleSequence.hpp>

using namespace ::com::sun::star;
using namespace ::com::sun::star::drawing;
using namespace ::basegfx;

namespace chart
{
namespace BaseGFXHelper
{

::basegfx::B3DRange getBoundVolume( const drawing::PolyPolygonShape3D& rPolyPoly )
{
    ::basegfx::B3DRange aRet;

    bool bInited = false;
    sal_Int32 nPolyCount = rPolyPoly.SequenceX.getLength();
    for(sal_Int32 nPoly = 0; nPoly < nPolyCount; nPoly++)
    {
        sal_Int32 nPointCount = rPolyPoly.SequenceX[nPoly].getLength();
        for( sal_Int32 nPoint = 0; nPoint < nPointCount; nPoint++)
        {
            if(!bInited)
            {
                aRet = ::basegfx::B3DRange(::basegfx::B3DTuple(
                          rPolyPoly.SequenceX[nPoly][nPoint]
                        , rPolyPoly.SequenceY[nPoly][nPoint]
                        , rPolyPoly.SequenceZ[nPoly][nPoint]));
                bInited = true;
            }
            else
            {
                aRet.expand( ::basegfx::B3DTuple(
                          rPolyPoly.SequenceX[nPoly][nPoint]
                        , rPolyPoly.SequenceY[nPoly][nPoint]
                        , rPolyPoly.SequenceZ[nPoly][nPoint]));
            }
        }
    }

    return aRet;
}
 
B2IRectangle makeRectangle( const awt::Point& rPos, const awt::Size& rSize )
{
    return B2IRectangle(rPos.X,rPos.Y,rPos.X+rSize.Width,rPos.Y+rSize.Height);
}

awt::Point B2IRectangleToAWTPoint( const ::basegfx::B2IRectangle& rB2IRectangle )
{
    return awt::Point( rB2IRectangle.getMinX(), rB2IRectangle.getMinY() );
}

awt::Size B2IRectangleToAWTSize( const ::basegfx::B2IRectangle& rB2IRectangle )
{
    return awt::Size( static_cast< sal_Int32 >( rB2IRectangle.getWidth()),
                      static_cast< sal_Int32 >( rB2IRectangle.getHeight()));
}

awt::Rectangle B2IRectangleToAWTRectangle(
    const ::basegfx::B2IRectangle& rB2IRectangle )
{
    return awt::Rectangle( rB2IRectangle.getMinX(), rB2IRectangle.getMinY(),
                           static_cast< sal_Int32 >( rB2IRectangle.getWidth()),
                           static_cast< sal_Int32 >( rB2IRectangle.getHeight()));
}

B3DVector Direction3DToB3DVector( const Direction3D& rDirection )
{
    return B3DVector(
          rDirection.DirectionX
        , rDirection.DirectionY
        , rDirection.DirectionZ
        );
}

Direction3D B3DVectorToDirection3D( const B3DVector& rB3DVector )
{
    return Direction3D(
          rB3DVector.getX()
        , rB3DVector.getY()
        , rB3DVector.getZ()
        );
}

B3DVector Position3DToB3DVector( const Position3D& rPosition )
{
    return B3DVector(
          rPosition.PositionX
        , rPosition.PositionY
        , rPosition.PositionZ
        );
}

Position3D B3DVectorToPosition3D( const B3DVector& rB3DVector )
{
    return Position3D(
          rB3DVector.getX()
        , rB3DVector.getY()
        , rB3DVector.getZ()
        );
}

B3DHomMatrix HomogenMatrixToB3DHomMatrix( const HomogenMatrix & rHomogenMatrix )
{
    B3DHomMatrix aResult;

    aResult.set( 0, 0, rHomogenMatrix.Line1.Column1 );
    aResult.set( 0, 1, rHomogenMatrix.Line1.Column2 );
    aResult.set( 0, 2, rHomogenMatrix.Line1.Column3 );
    aResult.set( 0, 3, rHomogenMatrix.Line1.Column4 );

    aResult.set( 1, 0, rHomogenMatrix.Line2.Column1 );
    aResult.set( 1, 1, rHomogenMatrix.Line2.Column2 );
    aResult.set( 1, 2, rHomogenMatrix.Line2.Column3 );
    aResult.set( 1, 3, rHomogenMatrix.Line2.Column4 );

    aResult.set( 2, 0, rHomogenMatrix.Line3.Column1 );
    aResult.set( 2, 1, rHomogenMatrix.Line3.Column2 );
    aResult.set( 2, 2, rHomogenMatrix.Line3.Column3 );
    aResult.set( 2, 3, rHomogenMatrix.Line3.Column4 );

    aResult.set( 3, 0, rHomogenMatrix.Line4.Column1 );
    aResult.set( 3, 1, rHomogenMatrix.Line4.Column2 );
    aResult.set( 3, 2, rHomogenMatrix.Line4.Column3 );
    aResult.set( 3, 3, rHomogenMatrix.Line4.Column4 );

    return aResult;
}

HomogenMatrix B3DHomMatrixToHomogenMatrix( const B3DHomMatrix & rB3DMatrix )
{
    HomogenMatrix aResult;

    aResult.Line1.Column1 = rB3DMatrix.get( 0, 0 );
    aResult.Line1.Column2 = rB3DMatrix.get( 0, 1 );
    aResult.Line1.Column3 = rB3DMatrix.get( 0, 2 );
    aResult.Line1.Column4 = rB3DMatrix.get( 0, 3 );

    aResult.Line2.Column1 = rB3DMatrix.get( 1, 0 );
    aResult.Line2.Column2 = rB3DMatrix.get( 1, 1 );
    aResult.Line2.Column3 = rB3DMatrix.get( 1, 2 );
    aResult.Line2.Column4 = rB3DMatrix.get( 1, 3 );

    aResult.Line3.Column1 = rB3DMatrix.get( 2, 0 );
    aResult.Line3.Column2 = rB3DMatrix.get( 2, 1 );
    aResult.Line3.Column3 = rB3DMatrix.get( 2, 2 );
    aResult.Line3.Column4 = rB3DMatrix.get( 2, 3 );

    aResult.Line4.Column1 = rB3DMatrix.get( 3, 0 );
    aResult.Line4.Column2 = rB3DMatrix.get( 3, 1 );
    aResult.Line4.Column3 = rB3DMatrix.get( 3, 2 );
    aResult.Line4.Column4 = rB3DMatrix.get( 3, 3 );

    return aResult;
}

B3DTuple GetRotationFromMatrix( const B3DHomMatrix & rB3DMatrix )
{
    B3DTuple aScale, aTranslation, aRotation, aShearing;
    rB3DMatrix.decompose( aScale, aTranslation, aRotation, aShearing );
    return aRotation;
}

B3DTuple GetScaleFromMatrix( const B3DHomMatrix & rB3DMatrix )
{
    B3DTuple aScale, aTranslation, aRotation, aShearing;
    rB3DMatrix.decompose( aScale, aTranslation, aRotation, aShearing );
    return aScale;
}

void ReduceToRotationMatrix( ::basegfx::B3DHomMatrix & rB3DMatrix )
{
    B3DTuple aR( GetRotationFromMatrix( rB3DMatrix ) );
    ::basegfx::B3DHomMatrix aRotationMatrix;
    aRotationMatrix.rotate(aR.getX(),aR.getY(),aR.getZ());
    rB3DMatrix = aRotationMatrix;
}

double Deg2Rad( double fDegrees )
{
    return fDegrees * ( F_PI / 180.0 );
}

double Rad2Deg( double fRadians )
{
    return fRadians * ( 180.0 / F_PI );
}

} //  namespace BaseGFXHelper
} //  namespace chart
