/*

 ============================================================================
                   The Apache Software License, Version 1.1
 ============================================================================

 Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.

 Redistribution and use in source and binary forms, with or without modifica-
 tion, are permitted provided that the following conditions are met:

 1. Redistributions of  source code must  retain the above copyright  notice,
    this list of conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

 3. The end-user documentation included with the redistribution, if any, must
    include  the following  acknowledgment:  "This product includes  software
    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
    Alternately, this  acknowledgment may  appear in the software itself,  if
    and wherever such third-party acknowledgments normally appear.

 4. The names "Batik" and  "Apache Software Foundation" must  not  be
    used to  endorse or promote  products derived from  this software without
    prior written permission. For written permission, please contact
    apache@apache.org.

 5. Products  derived from this software may not  be called "Apache", nor may
    "Apache" appear  in their name,  without prior written permission  of the
    Apache Software Foundation.

 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
 APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
 INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
 DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
 OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
 ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
 (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 This software  consists of voluntary contributions made  by many individuals
 on  behalf of the Apache Software  Foundation. For more  information on the
 Apache Software Foundation, please see <http://www.apache.org/>.

*/

package org.apache.batik.gvt;

import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.lang.ref.WeakReference;
import java.util.Map;

import org.apache.batik.ext.awt.image.renderable.ClipRable;
import org.apache.batik.ext.awt.image.renderable.Filter;
import org.apache.batik.gvt.filter.Mask;

/**
 * The base class for all graphics nodes. A GraphicsNode encapsulates
 * graphical attributes and can perform atomic operations of a complex
 * rendering.
 *
 * @author <a href="mailto:Thierry.Kormann@sophia.inria.fr">Thierry Kormann</a>
 * @author <a href="mailto:etissandier@ilog.fr">Emmanuel Tissandier</a>
 * @version $Id: GraphicsNode.java,v 1.37 2003/08/08 11:39:14 vhardy Exp $
 */
public interface GraphicsNode {

    /**
     * Indicates that this graphics node can be the target for events when it
     * is visible and when the mouse is over the "painted" area.
     */
    public static final int VISIBLE_PAINTED = 0;

    /**
     * Indicates that this graphics node can be the target for events when it
     * is visible and when the mouse is over the filled area if any.
     */
    public static final int VISIBLE_FILL = 1;

    /**
     * Indicates that this graphics node can be the target for events when it
     * is visible and when the mouse is over the stroked area if any.
     */
    public static final int VISIBLE_STROKE = 2;

    /**
     * Indicates that this graphics node can be the target for events when it
     * is visible and whatever is the filled and stroked area.
     */
    public static final int VISIBLE = 3;

    /**
     * Indicates that this graphics node can be the target for events when the
     * mouse is over the painted area whatever or not it is the visible.
     */
    public static final int PAINTED = 4;

    /**
     * Indicates that this graphics node can be the target for events when the
     * mouse is over the filled area whatever or not it is the visible.
     */
    public static final int FILL = 5;

    /**
     * Indicates that this graphics node can be the target for events when the
     * mouse is over the stroked area whatever or not it is the visible.
     */
    public static final int STROKE = 6;

    /**
     * Indicates that this graphics node can be the target for events if any
     * cases.
     */
    public static final int ALL = 7;

    /**
     * Indicates that this graphics node can not be the target for events.
     */
    public static final int NONE = 8;

    /**
     * The identity affine transform matrix used to draw renderable images.
     */
    public static final AffineTransform IDENTITY = new AffineTransform();

    /**
     * Returns a canonical WeakReference to this GraphicsNode.
     * This is suitable for use as a key value in a hash map
     */
    WeakReference getWeakReference();

    //
    // Properties methods
    //

    /**
     * Returns the type that describes how this graphics node reacts to events.
     *
     * @return VISIBLE_PAINTED | VISIBLE_FILL | VISIBLE_STROKE | VISIBLE |
     * PAINTED | FILL | STROKE | ALL | NONE
     */
    int getPointerEventType();

    /**
     * Sets the type that describes how this graphics node reacts to events.
     *
     * @param pointerEventType VISIBLE_PAINTED | VISIBLE_FILL | VISIBLE_STROKE |
     * VISIBLE | PAINTED | FILL | STROKE | ALL | NONE
     */
    void setPointerEventType(int pointerEventType);

    /**
     * Sets the transform of this node.
     *
     * @param newTransform the new transform of this node
     */
    void setTransform(AffineTransform newTransform);

    /**
     * Returns the transform of this node or null if any.
     */
    AffineTransform getTransform();

    /**
     * Returns the inverse transform for this node.
     */
    AffineTransform getInverseTransform();

    /**
     * Returns the concatenated transform of this node. i.e., this
     * node's transform preconcatenated with it's parent's transforms.
     */
    AffineTransform getGlobalTransform();

    /**
     * Sets the composite of this node.
     *
     * @param composite the composite of this node
     */
    void setComposite(Composite newComposite);

    /**
     * Returns the composite of this node or null if any.
     */
    Composite getComposite();

    /**
     * Sets if this node is visible or not depending on the specified value.
     *
     * @param isVisible If true this node is visible
     */
    void setVisible(boolean isVisible);

    /**
     * Returns true if this node is visible, false otherwise.
     */
    boolean isVisible();

    /**
     * Sets the clipping filter of this node.
     *
     * @param newClipper the new clipping filter of this node
     */
    void setClip(ClipRable newClipper);

    /**
     * Returns the clipping filter of this node or null if any.
     */
    ClipRable getClip();

    /**
     * Maps the specified key to the specified value in the rendering hints of
     * this node.
     *
     * @param key the key of the hint to be set
     * @param value the value indicating preferences for the specified
     * hint category.
     */
    void setRenderingHint(RenderingHints.Key key, Object value);

    /**
     * Copies all of the mappings from the specified Map to the
     * rendering hints of this node.
     *
     * @param hints the rendering hints to be set
     */
    void setRenderingHints(Map hints);

    /**
     * Sets the rendering hints of this node.
     *
     * @param newHints the new rendering hints of this node
     */
    void setRenderingHints(RenderingHints newHints);

    /**
     * Returns the rendering hints of this node or null if any.
     */
    RenderingHints getRenderingHints();

    /**
     * Sets the mask of this node.
     *
     * @param newMask the new mask of this node
     */
    void setMask(Mask newMask);

    /**
     * Returns the mask of this node or null if any.
     */
    Mask getMask();

    /**
     * Sets the filter of this node.
     *
     * @param newFilter the new filter of this node
     */
    void setFilter(Filter newFilter);

    /**
     * Returns the filter of this node or null if any.
     */
    Filter getFilter();

    /**
     * Returns the GraphicsNodeRable for this node.  This
     * GraphicsNodeRable is the Renderable (Filter) before any of the
     * filter operations have been applied.  
     */
    Filter getGraphicsNodeRable(boolean createIfNeeded);

    /**
     * Returns the GraphicsNodeRable for this node.  This
     * GraphicsNodeRable is the Renderable (Filter) after all of the
     * filter operations have been applied.  
     */
    Filter getEnableBackgroundGraphicsNodeRable(boolean createIfNeeded);

    //
    // Drawing methods
    //

    /**
     * Paints this node.
     *
     * @param g2d the Graphics2D to use
     */
    void paint(Graphics2D g2d);

    /**
     * Paints this node without applying Filter, Mask, Composite, and clip.
     *
     * @param g2d the Graphics2D to use
     */
    void primitivePaint(Graphics2D g2d);

    //
    // Event support methods
    //

    /**
     * Dispatches the specified event to the interested registered listeners.
     * @param evt the event to dispatch
     */
    // void dispatchEvent(GraphicsNodeEvent evt);

    /**
     * Adds the specified graphics node mouse listener to receive graphics node
     * mouse events from this node.
     *
     * @param l the graphics node mouse listener to add
     */
    // void addGraphicsNodeMouseListener(GraphicsNodeMouseListener l);

    /**
     * Removes the specified graphics node mouse listener so that it no longer
     * receives graphics node mouse events from this node.
     *
     * @param l the graphics node mouse listener to remove
     */
    // void removeGraphicsNodeMouseListener(GraphicsNodeMouseListener l);

    /**
     * Adds the specified graphics node key listener to receive graphics node
     * key events from this node.
     *
     * @param l the graphics node key listener to add
     */
    // void addGraphicsNodeKeyListener(GraphicsNodeKeyListener l);

    /**
     * Removes the specified graphics node key listener so that it no longer
     * receives graphics node key events from this node.
     *
     * @param l the graphics node key listener to remove
     */
    // void removeGraphicsNodeKeyListener(GraphicsNodeKeyListener l);

    /**
     * Dispatches a graphics node mouse event to this node or one of its child.
     *
     * @param evt the evt to dispatch
     */
    // void processMouseEvent(GraphicsNodeMouseEvent evt);

    /**
     * Dispatches a graphics node key event to this node or one of its child.
     *
     * @param evt the evt to dispatch
     */
    // void processKeyEvent(GraphicsNodeKeyEvent evt);

    /**
     * Returns an array of listeners that were added to this node and of the
     * specified type.
     *
     * @param listenerType the type of the listeners to return
     */
    // EventListener [] getListeners(Class listenerType);

    //
    // Structural methods
    //

    /**
     * Returns the parent of this node or null if any.
     */
    CompositeGraphicsNode getParent();

    /**
     * Returns the root of the GVT tree or null if the node is not part of a GVT
     * tree.
     */
    RootGraphicsNode getRoot();

    //
    // Geometric methods
    //

    /**
     * Returns the bounds of this node in user space. This includes primitive
     * paint, filtering, clipping and masking.
     */
    Rectangle2D getBounds();

    /**
     * Returns the bounds of this node after applying the input transform
     * (if any), concatenated with this node's transform (if any).
     *
     * @param txf the affine transform with which this node's transform should
     *        be concatenated. Should not be null.
     */
    Rectangle2D getTransformedBounds(AffineTransform txf);

    /**
     * Returns the bounds of the area covered by this node's primitive
     * paint.  This is the painted region of fill and stroke but does
     * not account for clipping, masking or filtering.
     */
    Rectangle2D getPrimitiveBounds();

    /**
     * Returns the bounds of this node's primitivePaint after applying
     * the input transform (if any), concatenated with this node's
     * transform (if any).
     *
     * @param txf the affine transform with which this node's transform should
     *        be concatenated. Should not be null.
     */
    Rectangle2D getTransformedPrimitiveBounds(AffineTransform txf);

    /**
     * Returns the bounds of the area covered by this node, without
     * taking any of its rendering attribute into account. i.e.,
     * exclusive of any clipping, masking, filtering or stroking, for
     * example.
     */
    Rectangle2D getGeometryBounds();

    /**
     * Returns the bounds of the area covered by this node, without
     * taking any of its rendering attribute into accoun. i.e.,
     * exclusive of any clipping, masking, filtering or stroking, for
     * example. The returned value is transformed by the concatenation
     * of the input transform and this node's transform.
     *
     * @param txf the affine transform with which this node's transform should
     *        be concatenated. Should not be null.
     */
    Rectangle2D getTransformedGeometryBounds(AffineTransform txf);

    /**
     * Returns the bounds of the sensitive area covered by this node,
     * This includes the stroked area but does not include the effects
     * of clipping, masking or filtering.
     */
    Rectangle2D getSensitiveBounds();

    /**
     * Returns the bounds of the sensitive area covered by this node,
     * This includes the stroked area but does not include the effects
     * of clipping, masking or filtering. The returned value is
     * transformed by the concatenation of the input transform and
     * this node's transform.
     *
     * @param txf the affine transform with which this node's
     * transform should be concatenated. Should not be null.
     */
    Rectangle2D getTransformedSensitiveBounds(AffineTransform txf);

    /**
     * Returns true if the specified Point2D is inside the boundary of this
     * node, false otherwise.
     *
     * @param p the specified Point2D in the user space
     */
    boolean contains(Point2D p);

    /**
     * Returns true if the interior of this node intersects the interior of a
     * specified Rectangle2D, false otherwise.
     *
     * @param r the specified Rectangle2D in the user node space
     */
    boolean intersects(Rectangle2D r);

    /**
     * Returns the GraphicsNode containing point p if this node or one of its
     * children is sensitive to mouse events at p.
     *
     * @param p the specified Point2D in the user space
     */
    GraphicsNode nodeHitAt(Point2D p);

    /**
     * Returns the outline of this node.
     */
    Shape getOutline();
}
