/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef INCLUDED_SLIDESHOW_ATTRIBUTABLESHAPE_HXX
#define INCLUDED_SLIDESHOW_ATTRIBUTABLESHAPE_HXX

#include <boost/shared_ptr.hpp>

#include "animatableshape.hxx"
#include "shapeattributelayer.hxx"
#include "doctreenodesupplier.hxx"

namespace slideshow
{
    namespace internal
    {
        // forward declaration necessary, because methods use AttributableShapeSharedPtr
        class AttributableShape;

        typedef ::boost::shared_ptr< AttributableShape > AttributableShapeSharedPtr;

        /** Represents an animatable shape, that can have its
            attributes changed.

            Over an animatable shape, this interface adds attribute
            modification methods. Furthermore, the shape can be
            queried for sub items, which in turn can be separated out
            into own AttributableShapes.
         */
        class AttributableShape : public AnimatableShape
        {
        public:
            // Attribute layer methods
            //------------------------------------------------------------------

            /** Create a new shape attribute layer.

                This method creates a new layer for shape attributes,
                which lies atop of all previous attribute layers. That
                is most typically used when a new SMIL animation
                starts (which according to the spec always lies atop
                of all previous animations). Thus, subsequent calls to
                this method generate a sandwich of attribute layers,
                which in total define the shape's attributes.

                Please note that the attribute layers do <em>not</em>
                contain the underlying XShape's attributes as
                default. Instead, attributes not explicitely set by
                animations remain in invalid state, allowing the
                shape's paint method to determine whether they have to
                override the underlying graphical shape
                representation. XShape attributes must be passed
                explicitely to animations which need them (e.g. 'by'
                animations).

                @return the new layer
             */
            virtual ShapeAttributeLayerSharedPtr createAttributeLayer() = 0;

            /** Revoke a previously generated attribute layer.

                This method revokes a previously generated attribute
                layer, and removes the effect of that layer from this
                shape. The layer need not be the current toplevel
                layer, it can also be revoked from in between.

                @param rLayer
                Layer to revoke. Must have been generated by
                createAttributeLayer() at the same Shape.

                @return true, if layer was successfully removed, false
                otherwise (e.g. if the given layer was not generated
                for this shape).
             */
            virtual bool revokeAttributeLayer( const ShapeAttributeLayerSharedPtr& rLayer ) = 0;

            /** Get the topmost shape attribute layer (if any).

                This method returns the topmost layer for shape
                attributes, i.e. the one which ultimately determines
                the shape's look.

                Please note that the attribute layers do <em>not</em>
                contain the underlying XShape's attributes as
                default. Instead, attributes not explicitely set by
                animations remain in invalid state, allowing the
                shape's paint method to determine whether they have to
                override the underlying graphical shape
                representation. XShape attributes must be passed
                explicitely to animations which need them (e.g. 'by'
                animations).

                @return the topmost layer
             */
            virtual ShapeAttributeLayerSharedPtr getTopmostAttributeLayer() const = 0;
            

            /** Change default shape visibility

                This method hides or unhides a shape. Note that every
                attribute layer generated for this shape is able to
                override the setting given here, until it is revoked.

                @param bVisible
                When true, shape will be visible, when false,
                invisible (modulo attribute layer overrides).
             */
            virtual void setVisibility( bool bVisible ) = 0;            
            
            // Sub-item handling
            //------------------------------------------------------------------

            /** Retrieve interface for DocTreeNode creation.

                This method provides the caller with a reference to
                the DocTreeNodeSupplier interface, which can be used
                to request specific tree nodes for this shape.
             */
            virtual const DocTreeNodeSupplier& getTreeNodeSupplier() const = 0;
            virtual DocTreeNodeSupplier& 	   getTreeNodeSupplier() = 0;

            /** Query the subset this shape displays.

                This method returns a tree node denoting the subset
                displayed by this shape. If this shape is not a subset
                shape, an empty tree node should be returned. If this
                shape is a subset, and itself has subsetted children,
                this method might return more than the shape is
                actually displaying (because a single DocTreeNode is
                not able to model holes in the range).
             */
            virtual DocTreeNode getSubsetNode() const = 0;

            /** Query a subset Shape, if already existent at this
                object

                This method returns a clone of this Shape, which
                renders only the selected subset of itself, but only
                if such a subset has been explicitely created before.

                @param rTreeNode
                A DocTreeNode instance queried from this Shape, which
                specifies the subset of the Shape to render.

                @return a NULL Shape pointer, if no subset exists for
                the given DocTreeNode.
            */
            virtual AttributableShapeSharedPtr getSubset( const DocTreeNode& rTreeNode ) const = 0;

            /** Create a subset Shape

                This method creates a clone of this Shape, which
                renders only the selected subset of itself. Multiple
                createSubset() calls for the same DocTreeNode will all
                share the same subset shape.

                The original shape (i.e. the one this method is called
                on) will cease to display the selected subset
                part. That is, together the shapes will display the
                original content, but the content of all subset shapes
                and their original shape will always be mutually
                disjunct.

                After deregistering the subset shape a matching number
                of times via revokeSubset(), the original shape will
                resume displaying the subsetted part.

                @attention To maintain view integrity, this method
                should only be called from the LayerManager
                
                @param o_rSubset
                The requested Shape

                @param rTreeNode
                A DocTreeNode instance queried from this Shape, which
                specifies the subset of the Shape to render

                @return true, if the shape was newly created, and
                false, if an already existing subset is returned.
            */
            virtual bool createSubset( AttributableShapeSharedPtr& 	o_rSubset, 
                                       const DocTreeNode& 			rTreeNode ) = 0;

            /** Revoke a previously generated shape subset.

                After revoking a subset shape, the corresponding
                subset part will become visible again on the original
                shape.

                @attention To maintain view integrity, this method
                should only be called from the LayerManager

                @param rShape
                The subset to revoke

                @return true, if the last client called
                revokeSubset().
             */
            virtual bool revokeSubset( const AttributableShapeSharedPtr& rShape ) = 0;
        };
    }
}

#endif /* INCLUDED_SLIDESHOW_ATTRIBUTABLESHAPE_HXX */

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
