/**************************************************************
 * 
 * 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_cppcanvas.hxx"

#include <tools/gen.hxx>

#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>
#include <canvas/canvastools.hxx>

#include <rtl/logfile.hxx>

#include <com/sun/star/rendering/XBitmap.hpp>
#include <com/sun/star/rendering/XCanvas.hpp>

#include <rtl/math.hxx>

#include <vcl/metaact.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/canvastools.hxx>
#include <vcl/svapp.hxx>
#include <vcl/outdev.hxx>
#include <vcl/virdev.hxx>
#include <vcl/virdev.hxx>
#include <vcl/gdimtf.hxx>
#include <vcl/gradient.hxx>

#include <canvas/canvastools.hxx>

#include <basegfx/range/b2drange.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/vector/b2dsize.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/tuple/b2dtuple.hxx>
#include <basegfx/tools/canvastools.hxx>

#include <boost/utility.hpp>

#include "transparencygroupaction.hxx"
#include "outdevstate.hxx"
#include "mtftools.hxx"
#include "cppcanvas/vclfactory.hxx"


using namespace ::com::sun::star;

namespace cppcanvas
{
    namespace internal
    {
		// free support functions
		// ======================
        namespace
        {
            class TransparencyGroupAction : public Action, private ::boost::noncopyable
            {
            public:
                /** Create new transparency group action.

        	    	@param rGroupMtf
                    Metafile that groups all actions to be rendered
                    transparent

                    @param rParms
                    Render parameters

                    @param rDstPoint
                    Left, top edge of destination, in current state
                    coordinate system

                    @param rDstSize
                    Size of the transparency group object, in current
                    state coordinate system.

                    @param nAlpha
                    Alpha value, must be in the range [0,1]
                */
                TransparencyGroupAction( MtfAutoPtr&					rGroupMtf,
                                         const Renderer::Parameters& 	rParms,
                                         const ::basegfx::B2DPoint& 	rDstPoint,
                                         const ::basegfx::B2DVector& 	rDstSize,
                                         double 						nAlpha,
                                         const CanvasSharedPtr&			rCanvas,
                                         const OutDevState& 			rState );

                /** Create new transparency group action.

	            	@param rGroupMtf
                    Metafile that groups all actions to be rendered
                    transparent.

                    @param rAlphaGradient
                    VCL gradient, to be rendered into the action's alpha
                    channel.

                    @param rParms
                    Render parameters

                    @param rDstPoint
                    Left, top edge of destination, in current state
                    coordinate system

                    @param rDstSize
                    Size of the transparency group object, in current
                    state coordinate system.
                */
                TransparencyGroupAction( MtfAutoPtr&					rGroupMtf,
                                         GradientAutoPtr&				rAlphaGradient,
                                         const Renderer::Parameters& 	rParms,
                                         const ::basegfx::B2DPoint& 	rDstPoint,
                                         const ::basegfx::B2DVector& 	rDstSize,
                                         const CanvasSharedPtr&			rCanvas,
                                         const OutDevState& 			rState );

                virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation ) const;
                virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation,
                                     const Subset&					rSubset ) const;

                virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const;
                virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix&	rTransformation,
                                                       const Subset&					rSubset ) const;

                virtual sal_Int32 getActionCount() const;

            private:
                MtfAutoPtr											mpGroupMtf;
                GradientAutoPtr										mpAlphaGradient;

                const Renderer::Parameters 							maParms;

                const ::basegfx::B2DSize 							maDstSize;

                mutable uno::Reference< rendering::XBitmap > 		mxBufferBitmap; // contains last rendered version
                mutable ::basegfx::B2DHomMatrix						maLastTransformation; // contains last active transformation
                mutable Subset										maLastSubset; // contains last effective subset

                // transformation for
                // mxBufferBitmap content
                CanvasSharedPtr										mpCanvas;
                rendering::RenderState								maState;
                const double										mnAlpha;
            };


            /** Setup transformation such that the next render call is
                moved rPoint away, and scaled according to the ratio
                given by src and dst size.
            */
            void implSetupTransform( rendering::RenderState& 	rRenderState,
                                     const ::basegfx::B2DPoint&	rDstPoint	)
            {
                ::basegfx::B2DHomMatrix	aLocalTransformation;

                aLocalTransformation.translate( rDstPoint.getX(),
                                                rDstPoint.getY() );
                ::canvas::tools::appendToRenderState( rRenderState,
                                                      aLocalTransformation );
            }

            TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr&					rGroupMtf,
                                                              const Renderer::Parameters& 	rParms,
                                                              const ::basegfx::B2DPoint& 	rDstPoint,
                                                              const ::basegfx::B2DVector& 	rDstSize,
                                                              double 						nAlpha,
                                                              const CanvasSharedPtr&		rCanvas,
                                                              const OutDevState& 			rState ) :
                mpGroupMtf( rGroupMtf ),
                mpAlphaGradient(),
                maParms( rParms ),
                maDstSize( rDstSize ),
                mxBufferBitmap(),
                maLastTransformation(),
                mpCanvas( rCanvas ),
                maState(),
                mnAlpha( nAlpha )
            {
                tools::initRenderState(maState,rState);
                implSetupTransform( maState, rDstPoint );

                // correct clip (which is relative to original transform)
                tools::modifyClip( maState,
                                   rState,
                                   rCanvas,
                                   rDstPoint,
                                   NULL,
                                   NULL );

                maLastSubset.mnSubsetBegin = 0;
                maLastSubset.mnSubsetEnd = -1;
            }

            TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr&					rGroupMtf,
                                                              GradientAutoPtr&				rAlphaGradient,
                                                              const Renderer::Parameters& 	rParms,
                                                              const ::basegfx::B2DPoint& 	rDstPoint,
                                                              const ::basegfx::B2DVector& 	rDstSize,
                                                              const CanvasSharedPtr&		rCanvas,
                                                              const OutDevState& 			rState ) :
                mpGroupMtf( rGroupMtf ),
                mpAlphaGradient( rAlphaGradient ),
                maParms( rParms ),
                maDstSize( rDstSize ),
                mxBufferBitmap(),
                maLastTransformation(),
                mpCanvas( rCanvas ),
                maState(),
                mnAlpha( 1.0 )
            {
                tools::initRenderState(maState,rState);
                implSetupTransform( maState, rDstPoint );

                // correct clip (which is relative to original transform)
                tools::modifyClip( maState,
                                   rState,
                                   rCanvas,
                                   rDstPoint,
                                   NULL,
                                   NULL );

                maLastSubset.mnSubsetBegin = 0;
                maLastSubset.mnSubsetEnd = -1;
            }

            // TODO(P3): The whole float transparency handling is a mess,
            // this should be refactored. What's more, the old idea of
            // having only internal 'metaactions', and not the original
            // GDIMetaFile now looks a lot less attractive. Try to move
            // into the direction of having a direct GDIMetaFile2XCanvas
            // renderer, and maybe a separate metafile XCanvas
            // implementation.
            bool TransparencyGroupAction::render( const ::basegfx::B2DHomMatrix&	rTransformation,
                                                  const Subset&						rSubset ) const
            {
                RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::TransparencyGroupAction::render()" );
                RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::TransparencyGroupAction: 0x%X", this );

                // determine overall transformation matrix (render, view,
                // and passed transformation)
                ::basegfx::B2DHomMatrix aTransform;
                ::canvas::tools::getRenderStateTransform( aTransform, maState );
                aTransform = rTransformation * aTransform;

                ::basegfx::B2DHomMatrix aTotalTransform;
                ::canvas::tools::getViewStateTransform( aTotalTransform, mpCanvas->getViewState() );
                aTotalTransform = aTotalTransform * aTransform;

                // since pure translational changes to the transformation
                // does not matter, remove them before comparing
                aTotalTransform.set( 0, 2, 0.0 );
                aTotalTransform.set( 1, 2, 0.0 );

                // if there's no buffer bitmap, or as soon as the
                // total transformation changes, we've got to
                // re-render the bitmap
                if( !mxBufferBitmap.is() ||
                    aTotalTransform != maLastTransformation ||
                    rSubset.mnSubsetBegin != maLastSubset.mnSubsetBegin ||
                    rSubset.mnSubsetEnd != maLastSubset.mnSubsetEnd )
                {
                    DBG_TESTSOLARMUTEX();

                    // determine total scaling factor of the
                    // transformation matrix - need to make the bitmap
                    // large enough
                    ::basegfx::B2DTuple aScale;
                    ::basegfx::B2DTuple aTranslate;
                    double				nRotate;
                    double				nShearX;
                    if( !aTotalTransform.decompose( aScale,
                                                    aTranslate,
                                                    nRotate,
                                                    nShearX ) )
                    {
                        OSL_ENSURE( false,
                                    "TransparencyGroupAction::render(): non-decomposable transformation" );
                        return false;
                    }

                    // output size of metafile
                    ::Size aOutputSizePixel( ::basegfx::fround( aScale.getX() * maDstSize.getX() ),
                                             ::basegfx::fround( aScale.getY() * maDstSize.getY() ) );

                    // pixel size of cache bitmap: round up to nearest int
                    ::Size aBitmapSizePixel( static_cast<sal_Int32>( aScale.getX() * maDstSize.getX() )+1,
                                             static_cast<sal_Int32>( aScale.getY() * maDstSize.getY() )+1 );

                    ::Point aEmptyPoint;

                    // render our content into an appropriately sized
                    // VirtualDevice with alpha channel
                    VirtualDevice aVDev(
                        *::Application::GetDefaultDevice(), 0, 0 );
                    aVDev.SetOutputSizePixel( aBitmapSizePixel );
                    aVDev.SetMapMode();

                    if( rSubset.mnSubsetBegin != 0 ||
                        rSubset.mnSubsetEnd != -1 )
                    {
                        // true subset - extract referenced
                        // metaactions from mpGroupMtf
                        GDIMetaFile aMtf;
                        MetaAction* pCurrAct;
                        int 		nCurrActionIndex;

                        // extract subset actions
                        for( nCurrActionIndex=0,
                                 pCurrAct=mpGroupMtf->FirstAction();
                             pCurrAct;
                             ++nCurrActionIndex, pCurrAct = mpGroupMtf->NextAction() )
                        {
                            switch( pCurrAct->GetType() )
                            {
                                case META_PUSH_ACTION:
                                case META_POP_ACTION:
                                case META_CLIPREGION_ACTION:
                                case META_ISECTRECTCLIPREGION_ACTION:
                                case META_ISECTREGIONCLIPREGION_ACTION:
                                case META_MOVECLIPREGION_ACTION:
                                case META_LINECOLOR_ACTION:
                                case META_FILLCOLOR_ACTION:
                                case META_TEXTCOLOR_ACTION:
                                case META_TEXTFILLCOLOR_ACTION:
                                case META_TEXTLINECOLOR_ACTION:
                                case META_TEXTALIGN_ACTION:
                                case META_FONT_ACTION:
                                case META_RASTEROP_ACTION:
                                case META_REFPOINT_ACTION:
                                case META_LAYOUTMODE_ACTION:
                                    // state-changing action - copy as-is
                                    aMtf.AddAction( pCurrAct->Clone() );
                                    break;

                                case META_GRADIENT_ACTION:
                                case META_HATCH_ACTION:
                                case META_EPS_ACTION:
                                case META_COMMENT_ACTION:
                                case META_POINT_ACTION:
                                case META_PIXEL_ACTION:
                                case META_LINE_ACTION:
                                case META_RECT_ACTION:
                                case META_ROUNDRECT_ACTION:
                                case META_ELLIPSE_ACTION:
                                case META_ARC_ACTION:
                                case META_PIE_ACTION:
                                case META_CHORD_ACTION:
                                case META_POLYLINE_ACTION:
                                case META_POLYGON_ACTION:
                                case META_POLYPOLYGON_ACTION:
                                case META_BMP_ACTION:
                                case META_BMPSCALE_ACTION:
                                case META_BMPSCALEPART_ACTION:
                                case META_BMPEX_ACTION:
                                case META_BMPEXSCALE_ACTION:
                                case META_BMPEXSCALEPART_ACTION:
                                case META_MASK_ACTION:
                                case META_MASKSCALE_ACTION:
                                case META_MASKSCALEPART_ACTION:
                                case META_GRADIENTEX_ACTION:
                                case META_WALLPAPER_ACTION:
                                case META_TRANSPARENT_ACTION:
                                case META_FLOATTRANSPARENT_ACTION:
                                case META_TEXT_ACTION:
                                case META_TEXTARRAY_ACTION:
                                case META_TEXTLINE_ACTION:
                                case META_TEXTRECT_ACTION:
                                case META_STRETCHTEXT_ACTION:
                                    // output-generating action - only
                                    // copy, if we're within the
                                    // requested subset
                                    if( rSubset.mnSubsetBegin <= nCurrActionIndex &&
                                        rSubset.mnSubsetEnd > nCurrActionIndex )
                                    {
                                        aMtf.AddAction( pCurrAct->Clone() );
                                    }
                                    break;

                                default:
                                    OSL_ENSURE( false,
                                                "Unknown meta action type encountered" );
                                    break;
                            }
                        }

                        aVDev.DrawTransparent( aMtf,
                                               aEmptyPoint,
                                               aOutputSizePixel,
                                               *mpAlphaGradient );
                    }
                    else
                    {
                        // no subsetting - render whole mtf
                        aVDev.DrawTransparent( *mpGroupMtf,
                                               aEmptyPoint,
                                               aOutputSizePixel,
                                               *mpAlphaGradient );
                    }


                    // update buffered bitmap and transformation
                    BitmapSharedPtr aBmp( VCLFactory::getInstance().createBitmap(
                                              mpCanvas,
                                              aVDev.GetBitmapEx(
                                                  aEmptyPoint,
                                                  aBitmapSizePixel ) ) );
                    mxBufferBitmap = aBmp->getUNOBitmap();
                    maLastTransformation = aTotalTransform;
                    maLastSubset = rSubset;
                }

                // determine target transformation (we can't simply pass
                // aTotalTransform as assembled above, since we must take
                // the canvas' view state as is, it might contain clipping
                // (which, in turn, is relative to the view
                // transformation))

                // given that aTotalTransform is the identity
                // transformation, we could simply render our bitmap
                // as-is. Now, since the mxBufferBitmap content already
                // accounts for scale changes in the overall
                // transformation, we must factor this out
                // before. Generally, the transformation matrix should be
                // structured like this:
                // Translation*Rotation*Shear*Scale. Thus, to neutralize
                // the contained scaling, we've got to right-multiply with
                // the inverse.
                ::basegfx::B2ISize aBmpSize(
                    ::basegfx::unotools::b2ISizeFromIntegerSize2D( mxBufferBitmap->getSize() ) );

                ::basegfx::B2DHomMatrix aScaleCorrection;
                aScaleCorrection.scale( (double)maDstSize.getX() / aBmpSize.getX(),
                                        (double)maDstSize.getY() / aBmpSize.getY() );
                aTransform = aTransform * aScaleCorrection;

                rendering::RenderState aLocalState( maState );
                ::canvas::tools::setRenderStateTransform(aLocalState, aTransform);

#ifdef SPECIAL_DEBUG
                aLocalState.Clip.clear();
                aLocalState.DeviceColor =
                    ::vcl::unotools::colorToDoubleSequence(
                        ::Color( 0x80FF0000 ),
                        mpCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace() );

                if( maState.Clip.is() )
                    mpCanvas->getUNOCanvas()->fillPolyPolygon( maState.Clip,
                                                               mpCanvas->getViewState(),
                                                               aLocalState );

                aLocalState.DeviceColor = maState.DeviceColor;
#endif

                if( ::rtl::math::approxEqual(mnAlpha, 1.0) )
                {
                    // no further alpha changes necessary -> draw directly
                    mpCanvas->getUNOCanvas()->drawBitmap( mxBufferBitmap,
                                                          mpCanvas->getViewState(),
                                                          aLocalState );
                }
                else
                {
                    // add alpha modulation value to DeviceColor
                    uno::Sequence<rendering::ARGBColor> aCols(1);
                    aCols[0] = rendering::ARGBColor( mnAlpha, 1.0, 1.0, 1.0);
                    aLocalState.DeviceColor =
                        mpCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace()->convertFromARGB(
                            aCols);

                    mpCanvas->getUNOCanvas()->drawBitmapModulated( mxBufferBitmap,
                                                                   mpCanvas->getViewState(),
                                                                   aLocalState );
                }

                return true;
            }

            // TODO(P3): The whole float transparency handling is a mess,
            // this should be refactored. What's more, the old idea of
            // having only internal 'metaactions', and not the original
            // GDIMetaFile now looks a lot less attractive. Try to move
            // into the direction of having a direct GDIMetaFile2XCanvas
            // renderer, and maybe a separate metafile XCanvas
            // implementation.
            bool TransparencyGroupAction::render( const ::basegfx::B2DHomMatrix& rTransformation ) const
            {
                Subset aSubset;

                aSubset.mnSubsetBegin = 0;
                aSubset.mnSubsetEnd   = -1;

                return render( rTransformation, aSubset );
            }

            ::basegfx::B2DRange TransparencyGroupAction::getBounds( const ::basegfx::B2DHomMatrix&	rTransformation ) const
            {
                rendering::RenderState aLocalState( maState );
                ::canvas::tools::prependToRenderState(aLocalState, rTransformation);

                return tools::calcDevicePixelBounds(
                    ::basegfx::B2DRange( 0,0,
                                         maDstSize.getX(),
                                         maDstSize.getY() ),
                    mpCanvas->getViewState(),
                    aLocalState );
            }

            ::basegfx::B2DRange TransparencyGroupAction::getBounds( const ::basegfx::B2DHomMatrix&	rTransformation,
                                                                    const Subset&					rSubset ) const
            {
                // TODO(F3): Currently, the bounds for
                // TransparencyGroupAction subsets equal those of the
                // full set, although this action is able to render
                // true subsets.

                // polygon only contains a single action, empty bounds
                // if subset requests different range
                if( rSubset.mnSubsetBegin != 0 ||
                    rSubset.mnSubsetEnd != 1 )
                    return ::basegfx::B2DRange();

                return getBounds( rTransformation );
            }

            sal_Int32 TransparencyGroupAction::getActionCount() const
            {
                return mpGroupMtf.get() ? mpGroupMtf->GetActionCount() : 0;
            }

        }

        ActionSharedPtr TransparencyGroupActionFactory::createTransparencyGroupAction( MtfAutoPtr&					rGroupMtf,
                                                                                       const Renderer::Parameters&	rParms,
                                                                                       const ::basegfx::B2DPoint& 	rDstPoint,
                                                                                       const ::basegfx::B2DVector& 	rDstSize,
                                                                                       double 						nAlpha,
                                                                                       const CanvasSharedPtr&		rCanvas,
                                                                                       const OutDevState& 			rState )
        {
            return ActionSharedPtr( new TransparencyGroupAction(rGroupMtf,
                                                                rParms,
                                                                rDstPoint,
                                                                rDstSize,
                                                                nAlpha,
                                                                rCanvas,
                                                                rState ) );
        }

        ActionSharedPtr TransparencyGroupActionFactory::createTransparencyGroupAction( MtfAutoPtr&					rGroupMtf,
                                                                                       GradientAutoPtr&				rAlphaGradient,
                                                                                       const Renderer::Parameters&	rParms,
                                                                                       const ::basegfx::B2DPoint& 	rDstPoint,
                                                                                       const ::basegfx::B2DVector&  rDstSize,
                                                                                       const CanvasSharedPtr&		rCanvas,
                                                                                       const OutDevState& 			rState )
        {
            return ActionSharedPtr( new TransparencyGroupAction(rGroupMtf,
                                                                rAlphaGradient,
                                                                rParms,
                                                                rDstPoint,
                                                                rDstSize,
                                                                rCanvas,
                                                                rState ) );
        }

    }
}
