/*PLEASE DO NOT EDIT THIS CODE*/
/*This code was generated using the Java Umplificator!*/

namespace org.jhotdraw.draw ;

class TriangleFigure 
{
depend org.jhotdraw.draw.connector.ChopTriangleConnector;
depend org.jhotdraw.draw.handle.OrientationHandle;
depend org.jhotdraw.draw.handle.Handle;
depend org.jhotdraw.draw.connector.Connector;
depend java.awt.*;
depend java.awt.geom.*;
depend java.util.*;
depend org.jhotdraw.draw.AttributeKeys.*;
depend org.jhotdraw.geom.*;
  isA AbstractAttributedFigure;

  /**
     * The bounds of the triangle figure.
     */
    private Rectangle2D.Double rectangle;
// DRAWING
    // SHAPE AND BOUNDS
    // ATTRIBUTES
    // EDITING
    // CONNECTING
    /**
     * Returns the Figures connector for the specified location.
     * By default a {@link org.jhotdraw.draw.connector.ChopTriangleConnector} is returned.
     */
    @Override
    public Connector findConnector(Point2D.Double p, ConnectionFigure prototype) {
        return new ChopTriangleConnector(this);
    }
/**
     * Returns a compatible connector.
     * By default a {@link org.jhotdraw.draw.connector.ChopTriangleConnector} is returned.
     */
    @Override
    public Connector findCompatibleConnector(Connector c, boolean isStartConnector) {
        return new ChopTriangleConnector(this);
    }
// COMPOSITE FIGURES
    // CLONING
    // EVENT HANDLING
    @Override
    public Rectangle2D.Double getBounds() {
        Rectangle2D.Double bounds = (Rectangle2D.Double) rectangle.clone();
        return bounds;
    }
@Override
    protected void drawFill(Graphics2D g) {
        Shape triangle = getBezierPath();
        double grow = AttributeKeys.getPerpendicularFillGrowth(this);
        if (grow != 0d) {
            GrowStroke gs = new GrowStroke((float) grow,
                    (float) (AttributeKeys.getStrokeTotalWidth(this) *
                    get(STROKE_MITER_LIMIT))
                    );
            triangle = gs.createStrokedShape(triangle);
        }
        
        g.fill(triangle);
    }
@Override
    protected void drawStroke(Graphics2D g) {
        Shape triangle = getBezierPath();
        
        double grow = AttributeKeys.getPerpendicularDrawGrowth(this);
        if (grow != 0d) {
            GrowStroke gs = new GrowStroke((float) grow,
                    (float) (AttributeKeys.getStrokeTotalWidth(this) *
                    get(STROKE_MITER_LIMIT))
                    );
            triangle = gs.createStrokedShape(triangle);
        }
        
        g.draw(triangle);
    }
@Override
    public Collection<Handle> createHandles(int detailLevel) {
        LinkedList<Handle> handles = (LinkedList<Handle>) super.createHandles(detailLevel);
        if (detailLevel == 0) {
            handles.add(new OrientationHandle(this));
        }
        return handles;
    }
public BezierPath getBezierPath() {
        Rectangle2D.Double r = (Rectangle2D.Double) rectangle.clone();
        
        BezierPath triangle = new BezierPath();
        switch (get(ORIENTATION)) {
            case NORTH :
            default :
                triangle.moveTo((float) (r.x + r.width / 2), (float) r.y);
                triangle.lineTo((float) (r.x + r.width), (float) (r.y + r.height));
                triangle.lineTo((float) r.x, (float) (r.y + r.height));
                break;
            case NORTH_EAST :
                triangle.moveTo((float) (r.x), (float) r.y);
                triangle.lineTo((float) (r.x + r.width), (float) (r.y));
                triangle.lineTo((float) (r.x + r.width), (float) (r.y + r.height));
                break;
            case EAST :
                triangle.moveTo((float) (r.x), (float) (r.y));
                triangle.lineTo((float) (r.x  + r.width), (float) (r.y + r.height / 2d));
                triangle.lineTo((float) r.x, (float) (r.y + r.height));
                break;
            case SOUTH_EAST :
                triangle.moveTo((float) (r.x + r.width), (float) (r.y));
                triangle.lineTo((float) (r.x + r.width), (float) (r.y + r.height));
                triangle.lineTo((float) (r.x), (float) (r.y + r.height));
                break;
            case SOUTH :
                triangle.moveTo((float) (r.x + r.width / 2), (float) (r.y + r.height));
                triangle.lineTo((float) r.x, (float) r.y);
                triangle.lineTo((float) (r.x + r.width), (float) r.y);
                break;
            case SOUTH_WEST :
                triangle.moveTo((float) (r.x + r.width), (float) (r.y + r.height));
                triangle.lineTo((float) (r.x), (float) (r.y + r.height));
                triangle.lineTo((float) (r.x), (float) (r.y));
                break;
            case WEST :
                triangle.moveTo((float) (r.x), (float) (r.y + r.height / 2));
                triangle.lineTo((float) (r.x + r.width), (float) (r.y ));
                triangle.lineTo((float) (r.x + r.width), (float) (r.y + r.height));
                break;
            case NORTH_WEST :
                triangle.moveTo((float) (r.x), (float) (r.y + r.height));
                triangle.lineTo((float) (r.x), (float) (r.y));
                triangle.lineTo((float) (r.x + r.width), (float) (r.y));
                break;
        }
        triangle.setClosed(true);
        return triangle;
    }
/**
     * Checks if a Point2D.Double is inside the figure.
     */
    @Override
    public boolean contains(Point2D.Double p) {
        Shape triangle = getBezierPath();
        
        double grow = AttributeKeys.getPerpendicularHitGrowth(this);
        if (grow != 0d) {
            GrowStroke gs = new GrowStroke((float) grow,
                    (float) (AttributeKeys.getStrokeTotalWidth(this) *
                    get(STROKE_MITER_LIMIT))
                    );
            triangle =gs.createStrokedShape(triangle);
        }
        return triangle.contains(p);
    }
@Override
    public void setBounds(Point2D.Double anchor, Point2D.Double lead) {
        rectangle.x = Math.min(anchor.x, lead.x);
        rectangle.y = Math.min(anchor.y , lead.y);
        rectangle.width = Math.max(0.1, Math.abs(lead.x - anchor.x));
        rectangle.height = Math.max(0.1, Math.abs(lead.y - anchor.y));
    }
@Override
    public Rectangle2D.Double getDrawingArea() {
        double totalStrokeWidth = AttributeKeys.getStrokeTotalWidth(this);
        double width = 0d;
        if (get(STROKE_COLOR) != null) {
            switch (get(STROKE_PLACEMENT)) {
                case INSIDE :
                    width = 0d;
                    break;
                case OUTSIDE :
                    if (get(STROKE_JOIN) == BasicStroke.JOIN_MITER) {
                        width = totalStrokeWidth * get(STROKE_MITER_LIMIT);
                    } else {
                        width = totalStrokeWidth;
                    }
                    break;
                case CENTER :
                    if (get(STROKE_JOIN) == BasicStroke.JOIN_MITER) {
                        width = totalStrokeWidth / 2d * get(STROKE_MITER_LIMIT);
                    } else {
                        width = totalStrokeWidth / 2d;
                    }
                    break;
            }
        }
        width++;
        Rectangle2D.Double r = getBounds();
        
        Geom.grow(r, width, width);
        return r;
    }
public Point2D.Double chop(Point2D.Double p) {
        Shape triangle = getBezierPath();
        
        double grow = AttributeKeys.getPerpendicularHitGrowth(this);
        if (grow != 0d) {
            GrowStroke gs = new GrowStroke((float) grow,
                    (float) (AttributeKeys.getStrokeTotalWidth(this) *
                    get(STROKE_MITER_LIMIT))
                    );
            triangle =gs.createStrokedShape(triangle);
        }
        return Geom.chop(triangle, p);
    }
/**
     * Moves the Figure to a new location.
     * @param tx the transformation matrix.
     */
    @Override
    public void transform(AffineTransform tx) {
        Point2D.Double anchor = getStartPoint();
        Point2D.Double lead = getEndPoint();
        setBounds(
                (Point2D.Double) tx.transform(anchor, anchor),
                (Point2D.Double) tx.transform(lead, lead)
                );
    }
@Override
    public TriangleFigure clone() {
        TriangleFigure that = (TriangleFigure) super.clone();
        that.rectangle = (Rectangle2D.Double) this.rectangle.clone();
        return that;
    }
@Override
    public void restoreTransformTo(Object geometry) {
        Rectangle2D.Double r = (Rectangle2D.Double) geometry;
        rectangle.x = r.x;
        rectangle.y = r.y;
        rectangle.width = r.width;
        rectangle.height = r.height;
    }
@Override
    public Object getTransformRestoreData() {
        return rectangle.clone();
    }

}