/**************************************************************
 *
 * 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;
        }

    }
}
