/*
 * @(#)MutatablePaintable.java    1.0  20 October 2003
 *
 * Copyright 2004
 * College of Computer and Information Science
 * Northeastern University
 * Boston, MA  02115
 *
 * The Java Power Tools software may be used for educational
 * purposes as long as this copyright notice is retained intact
 * at the top of all source files.
 *
 * To discuss possible commercial use of this software, 
 * contact Richard Rasala at Northeastern University, 
 * College of Computer and Information Science,
 * 617-373-2462 or rasala@ccs.neu.edu.
 *
 * The Java Power Tools software has been designed and built
 * in collaboration with Viera Proulx and Jeff Raab.
 *
 * Should this software be modified, the words "Modified from 
 * Original" must be included as a comment below this notice.
 *
 * All publication rights are retained.  This software or its 
 * documentation may not be published in any media either
 * in whole or in part without explicit permission.
 *
 * This software was created with support from Northeastern 
 * University and from NSF grant DUE-9950829.
 */

package edu.neu.ccs.gui;

import java.awt.*;
import java.awt.geom.*;

/**
 * <P><CODE>MutatablePaintable</CODE> describes a <CODE>Paintable</CODE>
 * that may be mutated using an invertible <CODE>AffineTransform</CODE>.
 * The <CODE>MutatablePaintable</CODE> object must maintain its current
 * mutator so that additional mutations may be performed.</P>
 *
 * <P>By convention, the information supplied by the methods in the
 * interface <CODE>Paintable</CODE> apply to the object after mutation.</P>
 *
 * <P>To obtain the corresponding information for the object before
 * mutation, use the methods with the keyword <CODE>Original</CODE>.</P>
 *
 * @author  Richard Rasala
 * @version 2.3
 * @since   2.3
 */
public interface MutatablePaintable
    extends Paintable
{

    /**
     * Returns a copy of the 2-dimensional bounds of the paint region
     * before mutation.
     *
     * @return a copy of the 2-dimensional bounds of the paint region
     */
    Rectangle2D getOriginalBounds2D();
    
    
    /**
     * Returns a copy of the center of the paint region before mutation.
     *
     * @return a copy of the center of the paint region before mutation
     */
    Point2D getOriginalCenter();
    
    
    /**
     * Sets the mutator transform to the given transform provided that the
     * given transform is invertible.
     *
     * @param M the invertible affine transform to set as the mutator
     */
    void setMutator(AffineTransform M);
    
    
    /**
     * <P>Composes the existing mutator on the right with the given transform
     * provided that the given transform is invertible.</P>
     *
     * <P>The action of the new mutator will be to apply the given transform
     * and then to apply the old mutator.</P>
     *
     * <P>This method should be equivalent to:</P>
     *
     * <P><CODE>setMutator(TransformFactory.compose(getMutator(), M))</CODE></P>
     *
     * @param M the invertible affine transform to compose on the right with
     *        the existing mutator
     */
    void addPreMutation(AffineTransform M);
    
    
    /**
     * <P>Applies a <CODE>Mutator.Strategy</CODE> object to the paintable by
     * composition on the right. The specific manner is which this is done
     * will depend on the particular object.</P>
     *
     * @param strategy the mutator strategy to apply
     */
    void addPreMutation(Mutator.Strategy strategy);
    
    
    /**
     * <P>Composes the existing mutator on the left with the given transform
     * provided that the given transform is invertible.</P>
     *
     * <P>The action of the new mutator will be to apply the old mutator and
     * then to apply the given transform.</P>
     *
     * <P>This method should be equivalent to:</P>
     *
     * <P><CODE>setMutator(TransformFactory.compose(M, getMutator()))</CODE></P>
     *
     * @param M the invertible affine transform to compose on the left with
     *        the existing mutator
     */
    void addPostMutation(AffineTransform M);
    
    
    /**
     * <P>Applies a <CODE>Mutator.Strategy</CODE> object to the paintable by
     * composition on the left. The specific manner is which this is done
     * will depend on the particular object.</P>
     *
     * @param strategy the mutator strategy to apply
     */
    void addPostMutation(Mutator.Strategy strategy);
    
    
    /**
     * Returns a copy of the existing mutator transform.
     *
     * @return a copy of the existing mutator transform
     */
    AffineTransform getMutator();
    
    
    /**
     * Returns a copy of the existing mutator inverse transform.
     *
     * @return a copy of the existing mutator inverse transform
     */
    AffineTransform getMutatorInverse();
    
    
    /**
     * <P>Moves the mutatable by a translation using the data in the point
     * specified by coordinates.</P>
     *
     * <P>This method should act as a convenience method that performs an
     * <CODE>addPostMutation</CODE> operation using a translation defined
     * by the given point.</P>
     *
     * @param x the x-coordinate of the point
     * @param y the y-coordinate of the point
     */
    void move(double x, double y);
    
    
    /**
     * <P>Moves the mutatable by a translation using the data in the point.
     *
     * <P>This method should act as a convenience method that performs an
     * <CODE>addPostMutation</CODE> operation using a translation defined
     * by the given point.</P>
     *
     * <P>If the point is <CODE>null</CODE>, this method should do nothing.
     *
     * @param p a specified <CODE>Point2D</CODE>
     */
    void move(Point2D p);
    
}
