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