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

// must be first
#include <canvas/debug.hxx>
#include <tools/diagnose_ex.h>

#include "viewbackgroundshape.hxx"
#include "tools.hxx"

#include <rtl/logfile.hxx>
#include <rtl/math.hxx>

#include <comphelper/anytostring.hxx>
#include <cppuhelper/exc_hlp.hxx>

#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>

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

#include <canvas/verbosetrace.hxx>
#include <canvas/canvastools.hxx>
#include <cppcanvas/vclfactory.hxx>
#include <cppcanvas/basegfxfactory.hxx>
#include <cppcanvas/renderer.hxx>
#include <cppcanvas/bitmap.hxx>

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


namespace slideshow
{
    namespace internal
    {
        
        bool ViewBackgroundShape::prefetch( const ::cppcanvas::CanvasSharedPtr&	rDestinationCanvas,
                                            const GDIMetaFileSharedPtr&			rMtf ) const
        {
            RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewBackgroundShape::prefetch()" );
            ENSURE_OR_RETURN_FALSE( rMtf,
                               "ViewBackgroundShape::prefetch(): no valid metafile!" );

            const ::basegfx::B2DHomMatrix& rCanvasTransform( 
                mpViewLayer->getTransformation() );

            if( !mxBitmap.is() ||
                rMtf != mpLastMtf ||
                rCanvasTransform != maLastTransformation )
            {
                // buffered bitmap is invalid, re-create

                // determine transformed page bounds
                ::basegfx::B2DRectangle aTmpRect;
                ::canvas::tools::calcTransformedRectBounds( aTmpRect, 
                                                            maBounds, 
                                                            rCanvasTransform );

                // determine pixel size of bitmap (choose it one pixel
                // larger, as polygon rendering takes one pixel more
                // to the right and to the bottom)
                const ::basegfx::B2ISize aBmpSizePixel( 
                    ::basegfx::fround( aTmpRect.getRange().getX() + 1),
                    ::basegfx::fround( aTmpRect.getRange().getY() + 1) );

                // create a bitmap of appropriate size
                ::cppcanvas::BitmapSharedPtr pBitmap( 
                    ::cppcanvas::BaseGfxFactory::getInstance().createBitmap( 
                        rDestinationCanvas, 
                        aBmpSizePixel ) );

                ENSURE_OR_THROW( pBitmap,
                                  "ViewBackgroundShape::prefetch(): Cannot create background bitmap" );

                ::cppcanvas::BitmapCanvasSharedPtr pBitmapCanvas( pBitmap->getBitmapCanvas() );

                ENSURE_OR_THROW( pBitmapCanvas,
                                  "ViewBackgroundShape::prefetch(): Cannot create background bitmap canvas" );

                // clear bitmap
                initSlideBackground( pBitmapCanvas,
                                     aBmpSizePixel );

                // apply linear part of destination canvas transformation (linear means in this context: 
                // transformation without any translational components)
                ::basegfx::B2DHomMatrix aLinearTransform( rCanvasTransform );
                aLinearTransform.set( 0, 2, 0.0 );
                aLinearTransform.set( 1, 2, 0.0 );
                pBitmapCanvas->setTransformation( aLinearTransform );

                const basegfx::B2DHomMatrix aShapeTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(
                    maBounds.getWidth(), maBounds.getHeight(),
                    maBounds.getMinX(), maBounds.getMinY()));

                ::cppcanvas::RendererSharedPtr pRenderer(
                    ::cppcanvas::VCLFactory::getInstance().createRenderer( 
                        pBitmapCanvas, 
                        *rMtf.get(),
                        ::cppcanvas::Renderer::Parameters() ) );

                ENSURE_OR_RETURN_FALSE( pRenderer,
                                   "ViewBackgroundShape::prefetch(): Could not create Renderer" );

                pRenderer->setTransformation( aShapeTransform );
                pRenderer->draw();

                mxBitmap = pBitmap->getUNOBitmap();
            }

            mpLastMtf 			 = rMtf;
            maLastTransformation = rCanvasTransform;

            return mxBitmap.is();
        }

        ViewBackgroundShape::ViewBackgroundShape( const ViewLayerSharedPtr& 		rViewLayer,
                                                  const ::basegfx::B2DRectangle&	rShapeBounds ) :
            mpViewLayer( rViewLayer ),
            mxBitmap(),
            mpLastMtf(),
            maLastTransformation(),
            maBounds( rShapeBounds )
        {
            ENSURE_OR_THROW( mpViewLayer, "ViewBackgroundShape::ViewBackgroundShape(): Invalid View" );
            ENSURE_OR_THROW( mpViewLayer->getCanvas(), "ViewBackgroundShape::ViewBackgroundShape(): Invalid ViewLayer canvas" );
        }

        ViewLayerSharedPtr ViewBackgroundShape::getViewLayer() const
        {
            return mpViewLayer;
        }

        bool ViewBackgroundShape::render( const GDIMetaFileSharedPtr& rMtf ) const
        {
            RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewBackgroundShape::draw()" );

            const ::cppcanvas::CanvasSharedPtr&	rDestinationCanvas( mpViewLayer->getCanvas() );
                                          
            if( !prefetch( rDestinationCanvas, rMtf ) )
                return false;

            ENSURE_OR_RETURN_FALSE( mxBitmap.is(), 
                               "ViewBackgroundShape::draw(): Invalid background bitmap" );

            ::basegfx::B2DHomMatrix aTransform( mpViewLayer->getTransformation() );

            // invert the linear part of the view transformation
            // (i.e. the view transformation without translational
            // components), to be able to leave the canvas
            // transformation intact (would otherwise destroy possible
            // clippings, as the clip polygon is relative to the view
            // coordinate system).
            aTransform.set(0,2, 0.0 );
            aTransform.set(1,2, 0.0 );
            aTransform.invert();

            rendering::RenderState aRenderState;
            ::canvas::tools::initRenderState( aRenderState );
            
            ::canvas::tools::setRenderStateTransform( aRenderState, aTransform );

            try
            {
                rDestinationCanvas->getUNOCanvas()->drawBitmap( mxBitmap, 
                                                                rDestinationCanvas->getViewState(), 
                                                                aRenderState );
            }
            catch( uno::Exception& )
            {
                OSL_ENSURE( false,
                            rtl::OUStringToOString(
                                comphelper::anyToString( cppu::getCaughtException() ),
                                RTL_TEXTENCODING_UTF8 ).getStr() );

                return false;
            }

            return true;
        }

    }
}
