/**
 *  Licensed under GPL. For more information, see
 *    http://jaxodraw.sourceforge.net/license.html
 *  or the LICENSE file in the jaxodraw distribution.
 */
package net.sf.jaxodraw.object;

import java.awt.Color;
import java.awt.Rectangle;

import java.util.Collection;
import java.util.List;

import net.sf.jaxodraw.util.graphics.JaxoGraphics2D;

/**
 * A List that can only contain JaxoObjects.
 * Adds some methods to the List interface to manipulate JaxoObjects.
 *
 * @param <E> the object elements of this List.
 * @since 2.0
 */
public interface JaxoList<E extends JaxoObject> extends List<E> {

    /**
     * Returns a copy of this JaxoList, i.e., a new JaxoList with
     * copies of equal JaxoObjects at equal positions.
     *
     * @return A copy of this JaxoList.
     */
    JaxoList<E> copyOf();

    /**
     * Determines if this JaxoList is a copy of the specified one.
     *
     * @param list The JaxoList to compare against.
     * @return True if the JaxoLists contain identical JaxoObjects at equal positions.
     */
    boolean isCopy(JaxoList<E> list);

      //
     // Methods to manipulate the JaxoObjects
    //

    /**
     * Displaces all JaxoObjects by the same amount.
     *
     * @param deltaX The displacement in x direction
     * @param deltaY The displacement in y direction
     */
    void moveAllObjects(int deltaX, int deltaY);

    /**
     * Sets the color of all JaxoObjects in this list.
     *
     * @param c The color to set.
     */
    void setColor(Color c);

      //
     // Methods to manipulate the order of JaxoObjects
    //

    /**
     * Move the object at 'index' to 'newIndex', leaving all
     * other elements in order.
     *
     * @param index The index of the object to move.
     * @param newIndex The new index of the object.
     */
    void move(int index, int newIndex);

    /**
     * Moves the specified JaxoObject to the last position in this list.
     *
     * @param object The JaxoObject to move.
     * @return True if the object was already in the last position,
     * i.e., the JaxoList has not been modified.
     */
    boolean toEnd(E object);

    /**
     * Moves the specified JaxoObject to the first position in this list.
     *
     * @param object The JaxoObject to move.
     * @return True if the JaxoObject was already in the first position,
     * i.e., the JaxoList has not been modified.
     */
    boolean toFront(E object);

    /**
     * Removes all marked JaxoObjects from this list.
     *
     * @return True if the list was modified by this operation,
     * i.e., there were marked objects in the list.
     */
    boolean removeMarkedObjects();

      //
     // Bounding box methods
    //

    /**
     * Returns the smallest bounding box that contains all the JaxoObjects
     * of this JaxoList.
     *
     * @return A Rectangle holding the bounds of this JaxoList,
     * or null if the List is empty (ie contains no objects).
     */
    Rectangle getBounds();

    /**
     * Returns the smallest bounding box that contains all the JaxoObjects
     * of this JaxoList except the ones contained in 'except'.
     *
     * @param excludes objects to exclude, may be null.
     * @return A Rectangle holding the bounds of the current JaxoList,
     * or null if the List is empty (ie contains no objects).
     */
    Rectangle getBoundsExcept(Collection<? extends E> excludes);

    /**
     * Intersection of the bounding box of this JaxoList with the given Rectangle.
     * This returns null if either any of the two rectangles are null,
     * or if they do not intersect.
     *
     * @param inside The Rectangle to intersect with.
     * @return The intersection, or null if either any
     * of the two rectangles are null, or if they do not intersect.
     * @see #getBounds()
     */
    Rectangle intersection(Rectangle inside);

      //
     // Painting methods
    //

    /**
     * Call paint(g) on all elements of JaxoObjects.
     *
     * @param g The graphics context to paint to.
     * @see net.sf.jaxodraw.object.JaxoObject#paint(JaxoGraphics2D)
     */
    void paint(JaxoGraphics2D g);

    /**
     * Call paint on all elements of JaxoObjects if they intersect
     * the current clipping area of the given graphics context.
     *
     * @param g The graphics context to paint to.
     * @see net.sf.jaxodraw.object.JaxoObject#paint(JaxoGraphics2D)
     * @see java.awt.Graphics#hitClip(int,int,int,int)
     */
    void paintClipped(JaxoGraphics2D g);

    /**
     * Call paint on all elements of JaxoObjects that
     * are not contained in 'excludes'.
     *
     * @param excludes The JaxoObjects to exlude.
     * @param g The graphics context to paint to.
     * @see net.sf.jaxodraw.object.JaxoObject#paint(JaxoGraphics2D)
     */
    void paintExcept(Collection<? extends E> excludes, JaxoGraphics2D g);

    /**
     * Call paint on all elements of JaxoObjects that are not contained in
     * 'excludes' and that intersect the current clipping area of the given
     * graphics context.
     *
     * @param excludes The JaxoObjects to exlude.
     * @param g The graphics context to paint to.
     * @see net.sf.jaxodraw.object.JaxoObject#paint(JaxoGraphics2D)
     * @see java.awt.Graphics#hitClip(int,int,int,int)
     */
    void paintClippedExcept(Collection<? extends E> excludes, JaxoGraphics2D g);
}
