package de.renew.tablet.tools;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseEvent;

import CH.ifa.draw.figures.AttributeFigure;
import CH.ifa.draw.standard.CreationTool;
import de.renew.draw.storables.ontology.Drawing;
import de.renew.draw.storables.ontology.Figure;
import de.renew.draw.storables.ontology.FigureEnumeration;
import de.renew.draw.ui.ontology.DrawingEditor;
import de.renew.gui.ArcConnection;
import de.renew.gui.CPNDrawingHelper;
import de.renew.gui.PlaceFigure;
import de.renew.gui.TransitionFigure;


/**
 * A more efficient version of the generic creation
 * tool that is not based on cloning.
 *
 * @author Lawrence Cabac
 */
public class PTToggleCreationTool extends CreationTool {
    private boolean _toggle = true;
    private Figure _lastCreated;
    private Figure _target = null;

    /**
     * Constructs a tool for the given view.
     *
     * @param editor the current view
     */
    public PTToggleCreationTool(DrawingEditor editor) {
        super(editor);
    }

    /**
     * Checks if the created figure is null.
     * Adjusts the extent of the created figure
     *
     * @param e the mouse event
     * @param x x-coordinate
     * @param y y-coordinate
     */
    @Override
    public void mouseDrag(MouseEvent e, int x, int y) {
        if (_target == null) {
            super.mouseDrag(e, x, y);
        }
    }

    /**
     * Deactivates the tool. This method is called whenever the user
     * switches to another tool.
     */
    @Override
    public void deactivate() {
        _lastCreated = null;
        super.deactivate();
    }

    /**
     * Checks if the last created figure has a possible connection target.
     * Creates a new figure if the target is null.
     *
     * @param e the mouse event
     * @param x x-coordinate
     * @param y y-coordinate
     */
    @Override
    public void mouseDown(MouseEvent e, int x, int y) {
        _target = findConnectionTarget(new ArcConnection(), _lastCreated, x, y, view().drawing());
        if (_target == null) {
            super.mouseDown(e, x, y);
        }
    }


    /**
    * Creates a new TransitionFigure.
    */
    @Override
    protected Figure createFigure() {
        if (_toggle) {
            _toggle = (!_toggle);
            return new PlaceFigure();
        }
        _toggle = (!_toggle);
        return new TransitionFigure();
    }

    /**
     * Changes the figure (alternately transitions and places) with the dimensions
     * depending on the given coordinates.
     * If the current dimensions are smaller than 10x10 the default dimension is used.
     * Creates an arc to the last created figure if it exists.
     *
     * @param e the mouse event
     * @param x x-coordinate
     * @param y y-coordinate
     */
    @Override
    public void mouseUp(MouseEvent e, int x, int y) {
        Figure created = null;
        if (_target != null) {
            created = _target;
            _target = null;
            _toggle = (!_toggle);
        } else {
            created = createdFigure();

            if ((created.displayBox().width < 10) || (created.displayBox().height < 10)) {
                Point loc = created.displayBox().getLocation();
                Dimension d;
                if (_toggle) {
                    d = TransitionFigure.defaultDimension();
                } else {
                    d = PlaceFigure.defaultDimension();
                }
                int w2 = d.width / 2;
                int h2 = d.height / 2;
                created.displayBox(
                    new Point(loc.x - w2, loc.y - h2),
                    new Point(loc.x - w2 + d.width, loc.y - h2 + d.height));
            }
        }

        //super.mouseUp(e, x, y);
        //System.out.println(lastCreated+ " "+ created);
        if (_lastCreated != null) {
            //System.out.println("lastCreated is not null");
            ArcConnection arc = new CPNDrawingHelper()
                .createArcConnection((AttributeFigure) _lastCreated, (AttributeFigure) created, 1);
            view().add(arc);
            view().checkDamage();
        }
        _lastCreated = created;
    }

    /**
     * Activates the tool and sets the cross hair cursor.
     * This method is called whenever the user switches to this tool.
     */
    @Override
    public void activate() {
        _toggle = true; //start tool with PlaceFigures
        _target = null;
        super.activate();
    }

    /**
     * Finds a connection end figure.
     *
     * @param arc       the arc figure
     * @param owner     the origin figure
     * @param x         x-coordinate
     * @param y         y-coordinate
     * @param drawing   the current drawing
     *
     * @return the found target or null
     */
    protected Figure findConnectionTarget(
        ArcConnection arc, Figure owner, int x, int y, Drawing drawing)
    {
        Figure target = findConnectableFigure(arc, x, y, drawing);
        if (owner == null) {
            if (target instanceof TransitionFigure) {
                _toggle = (!_toggle);
            }
            return target;
        }
        if ((target != null) && target.canConnect() && !target.includes(owner)
            && arc.canConnect(owner, target)) {
            return target;
        }
        return null;
    }

    /**
     *  Searches for a figure which is located at the given coordinates.
     *
     * @param arc       the arc figure
     * @param x         x-coordinate
     * @param y         y-coordinate
     * @param drawing   the current drawing
     *
     * @return the found target or null
     */
    protected Figure findConnectableFigure(ArcConnection arc, int x, int y, Drawing drawing) {
        FigureEnumeration k = drawing.figuresReverse();
        while (k.hasMoreElements()) {
            Figure figure = k.nextFigure();
            if (!figure.includes(arc) && figure.canConnect()) {
                if (figure.containsPoint(x, y)) {
                    return figure;
                }
            }
        }
        return null;
    }
}