/**************************************************************
 * 
 * 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 <basegfx/range/b2drange.hxx>
#include <basegfx/range/b1drange.hxx>
#include <basegfx/range/b2dpolyrange.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygoncutter.hxx>

#include "layer.hxx"

#include <boost/bind.hpp>
 

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

namespace slideshow
{
    namespace internal
    {
        Layer::Layer( const basegfx::B2DRange& rMaxLayerBounds,
                      Dummy                     ) :
            maViewEntries(),
            maBounds(),
            maNewBounds(),
            maMaxBounds( rMaxLayerBounds ),
            mbBoundsDirty(false),
            mbBackgroundLayer(true),
            mbClipSet(false)
        { 
        }

        Layer::Layer( const basegfx::B2DRange& rMaxLayerBounds ) :
            maViewEntries(),
            maBounds(),
            maNewBounds(),
            maMaxBounds( rMaxLayerBounds ),
            mbBoundsDirty(false),
            mbBackgroundLayer(false),
            mbClipSet(false)
        { 
        }

        ViewLayerSharedPtr Layer::addView( const ViewSharedPtr& rNewView )
        {
            OSL_ASSERT( rNewView );

            ViewEntryVector::iterator aIter;
            const ViewEntryVector::iterator aEnd( maViewEntries.end() );
            if( (aIter=std::find_if( maViewEntries.begin(), 
                                     aEnd,
                                     boost::bind<bool>( 
                                         std::equal_to< ViewSharedPtr >(),
                                         boost::bind( &ViewEntry::getView, _1 ),
                                         boost::cref( rNewView )))) != aEnd )
            {
                // already added - just return existing layer
                return aIter->mpViewLayer;

            }

            // not yet added - create new view layer
            ViewLayerSharedPtr pNewLayer;
            if( mbBackgroundLayer )
                pNewLayer = rNewView;
            else
                pNewLayer = rNewView->createViewLayer(maBounds);
            
            // add to local list
            maViewEntries.push_back( 
                ViewEntry( rNewView, 
                           pNewLayer ));
            
            return maViewEntries.back().mpViewLayer;
        }

        ViewLayerSharedPtr Layer::removeView( const ViewSharedPtr& rView )
        {
            OSL_ASSERT( rView );

            ViewEntryVector::iterator       aIter;
            const ViewEntryVector::iterator aEnd( maViewEntries.end() );            
            if( (aIter=std::find_if( maViewEntries.begin(),
                                       aEnd,
                                       boost::bind<bool>( 
                                           std::equal_to< ViewSharedPtr >(),
                                           boost::bind( &ViewEntry::getView, _1 ),
                                           boost::cref( rView )))) == aEnd )
            {
                // View was not added/is already removed
                return ViewLayerSharedPtr();
            }

            OSL_ENSURE( std::count_if( maViewEntries.begin(),
                                       aEnd,
                                       boost::bind<bool>( 
                                           std::equal_to< ViewSharedPtr >(),
                                           boost::bind( &ViewEntry::getView, _1 ),
                                           boost::cref( rView ))) == 1,
                        "Layer::removeView(): view added multiple times" );

            ViewLayerSharedPtr pRet( aIter->mpViewLayer );
            maViewEntries.erase(aIter);

            return pRet;
        }

        void Layer::viewChanged( const ViewSharedPtr& rChangedView )
        {
            ViewEntryVector::iterator aIter;
            const ViewEntryVector::iterator aEnd( maViewEntries.end() );            
            if( (aIter=std::find_if( maViewEntries.begin(), 
                                     aEnd,
                                     boost::bind<bool>( 
                                         std::equal_to< ViewSharedPtr >(),
                                         boost::bind( &ViewEntry::getView, _1 ),
                                         boost::cref( rChangedView )))) != 
                aEnd )
            {
                // adapt size of given ViewLayer - background layer
                // resizes with view.
                if( !mbBackgroundLayer )
                    aIter->mpViewLayer->resize(maBounds);
            }
        }

        void Layer::viewsChanged()
        {
            // adapt size of given ViewLayer - background layer
            // resizes with view.
            if( !mbBackgroundLayer )
            {
                std::for_each( maViewEntries.begin(),
                               maViewEntries.end(),
                               boost::bind( &ViewLayer::resize,
                                            boost::bind( &ViewEntry::getViewLayer,
                                                         _1 ),
                                            boost::cref(maBounds)));
            }
        }

        void Layer::setShapeViews( ShapeSharedPtr const& rShape ) const
        {
            rShape->clearAllViewLayers();

            std::for_each( maViewEntries.begin(),
                           maViewEntries.end(),
                           boost::bind(&Shape::addViewLayer,
                                       boost::cref(rShape),
                                       boost::bind(&ViewEntry::getViewLayer,
                                                   _1),
                                       false ));
        }

        void Layer::setPriority( const ::basegfx::B1DRange& rPrioRange )
        {
            if( !mbBackgroundLayer )
            {
                std::for_each( maViewEntries.begin(),
                               maViewEntries.end(),
                               boost::bind( &ViewLayer::setPriority,
                                            boost::bind( &ViewEntry::getViewLayer,
                                                         _1 ),
                                            boost::cref(rPrioRange)));
            }
        }

        void Layer::addUpdateRange( ::basegfx::B2DRange const& rUpdateRange )
        {
            // TODO(Q1): move this to B2DMultiRange
            if( !rUpdateRange.isEmpty() )
                maUpdateAreas.appendElement( rUpdateRange, 
                                             basegfx::ORIENTATION_POSITIVE );
        }

        void Layer::updateBounds( ShapeSharedPtr const& rShape )
        {
            if( !mbBackgroundLayer )
            {
                if( !mbBoundsDirty )
                    maNewBounds.reset();
                
                maNewBounds.expand( rShape->getUpdateArea() );
            }

            mbBoundsDirty = true;
        }

        bool Layer::commitBounds()
        {
            mbBoundsDirty = false;

            if( mbBackgroundLayer )
                return false;

            if( maNewBounds == maBounds )
                return false;

            maBounds = maNewBounds;
            if( std::count_if( maViewEntries.begin(),
                               maViewEntries.end(),
                               boost::bind( &ViewLayer::resize,
                                            boost::bind( &ViewEntry::getViewLayer,
                                                         _1 ),
                                            boost::cref(maBounds)) ) == 0 )
            {
                return false;
            }

            // layer content invalid, update areas have wrong
            // coordinates/not sensible anymore.
            clearUpdateRanges();

            return true;
        }
        
        void Layer::clearUpdateRanges()
        {
            maUpdateAreas.clear();
        }

        void Layer::clearContent()
        {
            // clear content on all view layers
            std::for_each( maViewEntries.begin(),
                           maViewEntries.end(),
                           boost::bind( 
                               &ViewLayer::clear,
                               boost::bind( 
                                   &ViewEntry::getViewLayer,
                                   _1)));

            // layer content cleared, update areas are not sensible
            // anymore.
            clearUpdateRanges();
        }

        class LayerEndUpdate : private boost::noncopyable
        {
        public:
            LayerEndUpdate( LayerSharedPtr const& rLayer ) :
                mpLayer( rLayer )
            {}

            ~LayerEndUpdate() { if(mpLayer) mpLayer->endUpdate(); }

            void dismiss() { mpLayer.reset(); }

        private:
            LayerSharedPtr mpLayer;
        };

        Layer::EndUpdater Layer::beginUpdate()
        {
            if( maUpdateAreas.count() )
            {
                // perform proper layer update. That means, setup proper
                // clipping, and render each shape that intersects with 
                // the calculated update area
                ::basegfx::B2DPolyPolygon aClip( maUpdateAreas.solveCrossovers() );
                aClip = ::basegfx::tools::stripNeutralPolygons(aClip);
                aClip = ::basegfx::tools::stripDispensablePolygons(aClip, false);
 
                // actually, if there happen to be shapes with zero
                // update area in the maUpdateAreas vector, the
                // resulting clip polygon will be empty.
                if( aClip.count() )
                {
                    // set clip to all view layers
                    std::for_each( maViewEntries.begin(),
                                   maViewEntries.end(),
                                   boost::bind( 
                                       &ViewLayer::setClip,
                                       boost::bind( 
                                           &ViewEntry::getViewLayer,
                                           _1),
                                       boost::cref(aClip)));

                    // clear update area on all view layers
                    std::for_each( maViewEntries.begin(),
                                   maViewEntries.end(),
                                   boost::bind( 
                                       &ViewLayer::clear,
                                       boost::bind( 
                                           &ViewEntry::getViewLayer,
                                           _1)));

                    mbClipSet = true;
                }
            }

            return EndUpdater(new LayerEndUpdate(shared_from_this()));
        }

        void Layer::endUpdate()
        {
            if( mbClipSet )
            {
                mbClipSet = false;

                basegfx::B2DPolyPolygon aEmptyClip;
                std::for_each( maViewEntries.begin(),
                               maViewEntries.end(),
                               boost::bind( 
                                   &ViewLayer::setClip,
                                   boost::bind( 
                                       &ViewEntry::getViewLayer,
                                       _1),
                                   boost::cref(aEmptyClip)));
            }

            clearUpdateRanges();
        }

        bool Layer::isInsideUpdateArea( ShapeSharedPtr const& rShape ) const
        {
            return maUpdateAreas.overlaps( rShape->getUpdateArea() );
        }

        LayerSharedPtr Layer::createBackgroundLayer( const basegfx::B2DRange& rMaxLayerBounds )
        {
            return LayerSharedPtr(new Layer( rMaxLayerBounds, 
                                             BackgroundLayer ));
        }

        LayerSharedPtr Layer::createLayer( const basegfx::B2DRange& rMaxLayerBounds )
        {
            return LayerSharedPtr( new Layer( rMaxLayerBounds ) );
        }

    }
}
