/*
 *
 *  Copyright (C) 1999, Institute for MicroTherapy
 *
 *  This software and supporting documentation were developed by
 *
 *    University of Witten/Herdecke
 *    Department of Radiology and MicroTherapy
 *    Institute for MicroTherapy
 *    Medical computer science
 *
 *    Universitaetsstrasse 142
 *    44799 Bochum, Germany
 *
 *    http://www.microtherapy.de/go/cs
 *    mailto:computer.science@microtherapy.de
 *
 *  THIS SOFTWARE IS MADE AVAILABLE,  AS IS,  AND THE INSTITUTE MAKES  NO
 *  WARRANTY REGARDING THE SOFTWARE, ITS PERFORMANCE, ITS MERCHANTABILITY
 *  OR FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES
 *  OR ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY
 *  AND PERFORMANCE OF THE SOFTWARE IS WITH THE USER.
 *
 *  Author :      $Author: kleber $
 *  Last update : $Date: 2003/09/08 10:12:24 $
 *  Revision :    $Revision: 1.2 $
 *  State:        $State: Exp $
 */

package viewer.paint;

import java.awt.*;
import java.util.*;
import java.awt.geom.*;

/**
 * This class ist the superclass of all drawing objects. These objects consits of
 * a vector of point represention the outline and a shape containing the geographic form.
 * <br>
 * These objects can be display or image relative.
 * <br>
 * These objects can be a shutter.
 * <br>
 * These objects can be filled and unfilled.
 *
 *
 * @author Klaus Kleber
 * @since 30.04.1999
 * @see Circle2DObject
 * @see CurveObject
 * @see Ellipse2DObject
 * @see InterpolatedObject
 * @see Line2DObject
 * @see PolylineObject
 * @see Rectangle2DObject
 */
public abstract class  PaintObject extends Object {
    
    /**
     * if true the PaintObject is display relative if false the PaintObject ist imageRelative.
     *
     * @since 30.04.1999
     */
    public boolean isDisplayRelative;
    
    /**
     * True, if the PaintObject is a shutter.
     *
     * @since 30.04.1999
     */
    public boolean isShutter;
    /**
     * True, if the PaintObject is a shutter.
     *
     * @since 30.04.1999
     */
    public boolean isZoom;
    
    /**
     * The PaintObject is created.
     *
     * @since 30.04.1999
     */
    public static int STATUS_STOP = 8;
    
    /**
     * The  PaintObject is empty
     *
     * @since 30.04.1999
     */
    public static int STATUS_WORK = 4;
    
    /**
     * The  PaintObject is empty
     *
     * @since 30.04.1999
     */
    public static int STATUS_NULL = 0;
    
    /**
     * The  creation of the PaintObject has started.
     *
     * @since 30.04.1999
     */
    public static int STATUS_BEGIN = 2;
    
    
    /**
     * Specified if the PaintObject is filled.
     */
    public boolean filled = false;
    
    
    /**
     * Vector which contains the points of the PaintObject.
     */
    public Vector objectPoints;
    
    /**
     * Creation status of the PaintObject.
     */
    public int status = STATUS_NULL;
    
    /**
     * Constructs an empty PaintObject.
     *
     * @since 30.04.1999
     */
    public PaintObject() {
        objectPoints = new Vector();
        status =STATUS_NULL;
        //{{INIT_CONTROLS
        //}}
    }
    /**
     * Constructs a new  filled PaintObject .
     *
     * @param filled true if the PainObject should be filled
     * @since 30.04.1999
     */
    public PaintObject(boolean filled) {
        objectPoints = new Vector();
        status =STATUS_NULL;
        this.filled = filled;
    }
    
    /**
     * Returns true if the PaintObject is closed. A PaintObject is closed if the first Point in
     * objectPoints is equal the last Point and the Vector objectPoints contains more than 2 Points.
     *
     * @return ture if the PaintObject is closed
     * @since 30.04.1999
     */
    public boolean isClosed() {
        if (objectPoints.size() < 3) return false;
        else return getPoint(0).equals(getPoint(objectPoints.size()-1));
        
    }
    
    
    /**
     * Return the Point on the specified index in the objectPoints.
     *
     * @return The Point on the specified index in the objectPoints.
     * @since 30.04.1999
     */
    public Point2D.Float getPoint(int index) {
        if (index >= objectPoints.size()) return null;
        else {
            return (Point2D.Float) objectPoints.elementAt(index);
        }
    }
    
    /**
     * Return the type of the PaintObject. If type = 1 the PaintObject is display relative,
     * if type = 0 the PaintObject is image relative.
     *
     * @return The yype of the PaintObject.
     * @since 30.04.1999
     */
    public int getType() {
        if (isDisplayRelative) return 1;
        else return 0;
    }
    
    /**
     * Returns the Shape of the PaintObject build form the Points in the PaintObject
     *
     * @return The Point on the specified index in the objectPoints.
     * @since 30.04.1999
     */
    public abstract Shape getShape();
    
    /**
     * Returns a real copy of the PaintObject.
     *
     * @return a real copy of this PaintObject.
     * @since 30.04.1999
     */
    public abstract PaintObject copy();
    
    /**
     * Tests if the specified Point is inside the boundary of the Shape.
     *
     * @return true if the specified Point is inside the boundary of the Shape.
     * @since 30.04.1999
     */
    public  boolean contains(Point2D.Float p) {
        return getShape().getBounds2D().contains(p);
    }
    
    
    /**
     * Insert a new Point to the PaintObject.
     *
     * @param newPoint The new Point for the PaintObject.
     * @since 30.04.1999
     */
    public abstract void setNewPoint(Point2D.Float newPoint);
    
    
    /**
     * Gets a copy of  the Point at the specified index.
     *
     * @param index The point at the specified index.
     * @return A copy of the Point at the specified index.
     * @since 30.04.1999
     */
    public  Point2D.Float getCopyPointAt(int index) {
        Point2D.Float returnPoint = null;
        if (index >= objectPoints.size()) return returnPoint; {
            returnPoint = new Point2D.Float(((Point2D.Float) objectPoints.elementAt(index)).x,
            ((Point2D.Float) objectPoints.elementAt(index)).y);
            return returnPoint;
        }
    }
    
    /**
     * Gets the  status of the PaintObject.
     *
     * @return The status of the PaintObject.
     * @since 30.04.1999
     */
    public int getStatus() {
        return status;
    }
    
    /**
     * Sets the  status of the PaintObject.
     *
     * @param status The new status of the PaintObject.
     * @since 30.04.1999
     */
    public void setStatus(int status) {
        this.status = status;
    }
    
    
    /**
     * Gets the ObjectPoints .
     *
     * @return The ObjectPoints.
     * @since 30.04.1999
     */
    public Vector getObjectPoints() {
        return objectPoints;
    }
    
    /**
     * Returns a String representing this PaintObject
     *
     * @return A String representing this PaintObject
     * @since 30.04.1999
     */
    public String getInfo() {
        String returnString = null;
        if (getShape()!= null)returnString = new String("        " + getShape().toString()+ "\n");
        for (int i = 0; i < objectPoints.size(); i++) {
            returnString = returnString.concat("Index: " + i + " " + objectPoints.elementAt(i).toString()+"\n");
        }
        return returnString;
    }//getInfo
    
    /**
     * Fills/Unfills the PaintObject
     *
     * @param filled true - the PaintObject should be filled.
     * @since 30.04.1999
     */
    public void setFilled(boolean filled) {
        this.filled = filled;
    }
    
    /**
     * Draws the Shape of the PaintObject  in the specified Graphics context.
     *
     * @param g The Graphics context iin which the Shape should be drawn.
     * @since 30.04.1999
     */
    abstract void drawShape(Graphics2D g);
    
    /**
     * Draws the Shape of the PaintObject with the specified transformations in the specified Graphics context.
     *
     * @param g The Graphics context iin which the Shape should be drawn.
     * @param aff Contains the transformation appling to the Shpae before drawing.
     * @since 30.04.1999
     */
    public  void drawTransformedShape(Graphics2D g,AffineTransform aff) {
        g.setTransform(aff);
        drawShape(g);
    }
    
    /**
     * Returns new PaintObject with the  same properties as the current object.
     *
     * @return A new PaintObject with the same properties.
     * @since 30.04.1999
     */
    public abstract PaintObject getNewPaintObject();
    
    
    /**
     * Returns the part of the PaintObject which should be redraw if the PaintObejct will be creating.
     * For example if you create a PolylineObject you have to add points. The points will be connect wiht a line.
     * If you add a new Point with the mouse, the last point of the PolylineObject will be connected with
     * the Point of the mouse cursor. These line you have to dedraw many times. These Method should give you these part of the
     * PaintObject which should be redraw in such cases.
     *
     * @param nextPoint The next drawing Point.
     * @return The part of the PaintObject which should be redraw.
     * @since 30.04.1999
     */
    public abstract PaintObject getMovePaintObject(Point2D.Float nextPoint);
    
    //{{DECLARE_CONTROLS
    //}}
}

/*
 *  CVS Log
 *  $Log: PaintObject.java,v $
 *  Revision 1.2  2003/09/08 10:12:24  kleber
 *  Reformate Code
 *
 *  Revision 1.1.1.1  2001/06/06 10:32:30  kleber
 *  Init commit for DICOMscope 3.5
 *  Create new CVS
 *
 */
