/*
 * @(#)CreationTool.java 5.1
 *
 */

package CH.ifa.draw.standard;

import java.awt.Component;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.event.MouseEvent;

import CH.ifa.draw.figures.AttributeFigure;
import CH.ifa.draw.framework.HJDError;
import de.renew.draw.storables.ontology.Figure;
import de.renew.draw.ui.ontology.DrawingEditor;


/**
 * A tool to create new figures. The figure to be
 * created is specified by a prototype.
 *
 * <hr>
 * <b>Design Patterns</b><P>
 * <img src="images/red-ball-small.gif" width=6 height=6 alt=" o ">
 * <b><a href=../pattlets/sld029.htm>Prototype</a></b><br>
 * CreationTool creates new figures by cloning a prototype.
 * <hr>
 * @see Figure
 * @see Object#clone
 */
public class CreationTool extends UndoableTool {

    /**
     * the anchor point of the interaction
     */
    private Point _anchorpoint;

    /**
     * the currently created figure
     */
    private Figure _createdfigure;

    /**
     * the prototypical figure that is used to create new figures.
     */
    private final Figure _prototype;

    /**
     * Initializes a CreationTool with the given prototype.
     */
    public CreationTool(DrawingEditor editor, Figure prototype) {
        super(editor);
        _prototype = prototype;
    }

    /**
     * Constructs a CreationTool without a prototype.
     * This is for subclasses overriding createFigure.
     */
    protected CreationTool(DrawingEditor editor) {
        super(editor);
        _prototype = null;
    }

    protected Figure getPrototype() {
        return _prototype;
    }

    /**
     * Sets the cross-hair cursor.
     */
    @Override
    public void activate() {
        super.activate();
        view().setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
        _anchorpoint = null;
        _createdfigure = null;
    }

    /**
     * Creates a new figure by cloning the prototype.
     */
    @Override
    public void mouseDown(MouseEvent e, int x, int y) {
        _createdfigure = createFigure();
        if (e.isControlDown()) {
            _anchorpoint =
                new Point(x, x - _createdfigure.displayBox().x + _createdfigure.displayBox().y);
        } else {
            _anchorpoint = new Point(x, y);
        }
        _createdfigure.displayBox(_anchorpoint, _anchorpoint);
        view().add(_createdfigure);
        changesMade();
    }

    /**
     * Creates a new figure by cloning the prototype.
     */
    protected Figure createFigure() {
        if (_prototype == null) {
            throw new HJDError("No prototype defined");
        }
        return (Figure) _prototype.clone();
    }

    /**
     * Adjusts the extent of the created figure
     */
    @Override
    public void mouseDrag(MouseEvent e, int x, int y) {
        if (e.isControlDown()) {
            _createdfigure.displayBox(
                _anchorpoint,
                new Point(x, x - _createdfigure.displayBox().x + _createdfigure.displayBox().y));
        } else {
            _createdfigure.displayBox(_anchorpoint, new Point(x, y));
        }
    }

    /**
     * Checks if the created figure is empty. If it is, the figure
     * is removed from the drawing.
     * @see Figure#isEmpty
     */
    @Override
    public void mouseUp(MouseEvent e, int x, int y) {
        if (_createdfigure.isEmpty()) {
            drawing().remove(_createdfigure);
            noChangesMade();
        }
        _createdfigure = null;
        editor().toolDone();
    }

    /**
     * Gets the currently created figure
     */
    protected Figure createdFigure() {
        return _createdfigure;
    }

    /**
     * If the created figure is an {@link AttributeFigure}, creates a menu for editing the initial attributes.
     *
     * @return
     */
    public Component initialAttributesMenu() {
        if (_prototype instanceof AttributeFigure) {
            return new InitialAttributesMenu((AttributeFigure) _prototype);
        }
        return null;
    }
}