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

#include <cppcanvas/canvas.hxx>
#include <canvas/canvastools.hxx>

#include <basegfx/vector/b2dvector.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/numeric/ftools.hxx>


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

namespace slideshow
{
    namespace internal
    {
        AnimatedSprite::AnimatedSprite( const ViewLayerSharedPtr&	rViewLayer,
                                        const ::basegfx::B2DSize& 	rSpriteSizePixel,
                                        double                      nSpritePrio ) :
            mpViewLayer( rViewLayer ),
            mpSprite(),
            maEffectiveSpriteSizePixel( rSpriteSizePixel ),
            maContentPixelOffset(),
            mnSpritePrio(nSpritePrio),
            mnAlpha(0.0),
            maPosPixel(),
            maClip(),
            maTransform(),
            mbSpriteVisible( false )
        {
            ENSURE_OR_THROW( mpViewLayer, "AnimatedSprite::AnimatedSprite(): Invalid view layer" );
            
            // Add half a pixel tolerance to sprite size, since we later on compare
            // against it in resize(). And view transformations will almost never yield
            // the same data bits when transforming to device coordinates
            maEffectiveSpriteSizePixel += ::basegfx::B2DSize(0.5, 0.5);

            mpSprite = mpViewLayer->createSprite( maEffectiveSpriteSizePixel,
                                                  mnSpritePrio );

            ENSURE_OR_THROW( mpSprite, "AnimatedSprite::AnimatedSprite(): Could not create sprite" );
        }

        ::cppcanvas::CanvasSharedPtr AnimatedSprite::getContentCanvas() const
        {
            ENSURE_OR_THROW( mpViewLayer->getCanvas(), "AnimatedSprite::getContentCanvas(): No view layer canvas" );

            const ::cppcanvas::CanvasSharedPtr pContentCanvas( mpSprite->getContentCanvas() );
            pContentCanvas->clear();
            
            // extract linear part of canvas view transformation
            // (linear means: without translational components). The
            // only translation that is imposed at the view transform
            // is the local content pixel offset.
            // 
            // We can apply that directly here, no need to call
            // aLinearTransform.translate(), since, as said above, the
            // last column of aLinearTransform is assumed [0 0 1]
            ::basegfx::B2DHomMatrix aLinearTransform( mpViewLayer->getTransformation() );
            aLinearTransform.set( 0, 2, maContentPixelOffset.getX() );
            aLinearTransform.set( 1, 2, maContentPixelOffset.getY() );
            
            // apply linear part of canvas view transformation to sprite canvas
            pContentCanvas->setTransformation( aLinearTransform );

            return pContentCanvas;
        }

        bool AnimatedSprite::resize( const ::basegfx::B2DSize& rSpriteSizePixel )
        {
            // Enlarge or reduce the sprite size, if necessary.  This
            // method employs a strategy similar to container, when
            // allocating memory: size is doubled or halved everytime
            // the limit is reached. This makes for amortized constant
            // time in runtime complexity. Note that we take exact
            // powers of two here, since several HW-accelerated canvas
            // implementations are limited to such sprite sizes
            // (otherwise, those implementations would internally
            // round up, too, wasting precious mem).
            ::basegfx::B2DSize	aNewSize( maEffectiveSpriteSizePixel );
            bool				bNeedResize( false );
            
            if( rSpriteSizePixel.getX() > maEffectiveSpriteSizePixel.getX() ||
                rSpriteSizePixel.getX() < 0.5*maEffectiveSpriteSizePixel.getX() )
            {
                // enlarge or shrink width
                aNewSize.setX( ::canvas::tools::nextPow2( ::basegfx::fround(rSpriteSizePixel.getX()) ) );
                bNeedResize = true;
            }

            if( rSpriteSizePixel.getY() > maEffectiveSpriteSizePixel.getY() ||
                rSpriteSizePixel.getY() < 0.5*maEffectiveSpriteSizePixel.getY() )
            {
                // enlarge or shrink height, by doubling it
                aNewSize.setY( ::canvas::tools::nextPow2( ::basegfx::fround(rSpriteSizePixel.getY()) ) );
                bNeedResize = true;
            }

            if( bNeedResize )
            {
                // as the old sprite might have already been altered
                // (and therefore been placed in the update list of
                // the spritecanvas for this frame), must hide it
                // here, to ensure it's not visible on screen any
                // longer.
                mpSprite->hide();

                maEffectiveSpriteSizePixel = aNewSize;
                mpSprite = mpViewLayer->createSprite( maEffectiveSpriteSizePixel,
                                                      mnSpritePrio );

                ENSURE_OR_THROW( mpSprite, 
                                  "AnimatedSprite::resize(): Could not create new sprite" );

                // set attributes similar to previous sprite
                if( mpSprite && mbSpriteVisible )
                {
                    mpSprite->show();
                    mpSprite->setAlpha( mnAlpha );

                    if( maPosPixel )
                        mpSprite->movePixel( *maPosPixel );

                    if( maClip )
                        mpSprite->setClip( *maClip );
                }
            }

			return (mpSprite.get() != NULL);
        }

        void AnimatedSprite::setPixelOffset( const ::basegfx::B2DSize& rPixelOffset )
        {
            maContentPixelOffset = rPixelOffset;
        }

        ::basegfx::B2DSize AnimatedSprite::getPixelOffset() const
        {
            return maContentPixelOffset;
        }

        void AnimatedSprite::movePixel( const ::basegfx::B2DPoint& rNewPos )
        {
            maPosPixel.reset( rNewPos );
            mpSprite->movePixel( rNewPos );
        }

        void AnimatedSprite::setAlpha( double nAlpha )
        {
            mnAlpha = nAlpha;
            mpSprite->setAlpha( nAlpha );
        }

        void AnimatedSprite::clip( const ::basegfx::B2DPolyPolygon& rClip )
        {
            maClip.reset( rClip );
            mpSprite->setClipPixel( rClip );
        }

        void AnimatedSprite::clip()
        {
            maClip.reset();
            mpSprite->setClip();
        }

        void AnimatedSprite::transform( const ::basegfx::B2DHomMatrix& rTransform )
        {
            maTransform.reset( rTransform );
            mpSprite->transform( rTransform );
        }

		void AnimatedSprite::setPriority( double nPrio )
		{
            mpSprite->setPriority( nPrio );
		}

        void AnimatedSprite::hide()
        {
            mpSprite->hide();
            mbSpriteVisible = false;
        }
        
        void AnimatedSprite::show()
        {
            mbSpriteVisible = true;
            mpSprite->show();
        }

    }
}
