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

package CH.ifa.draw.figures;

import java.awt.Point;
import java.awt.Rectangle;
import java.io.Serial;
import java.util.Vector;

import CH.ifa.draw.standard.ChangeConnectionEndHandle;
import CH.ifa.draw.standard.ChangeConnectionStartHandle;
import CH.ifa.draw.standard.NullHandle;
import CH.ifa.draw.util.Geom;
import de.renew.draw.storables.ontology.Figure;
import de.renew.draw.storables.ontology.Locator;
import de.renew.draw.ui.ontology.FigureHandle;

/**
 * A LineConnection that constrains a connection to
 * orthogonal lines.
 */
public class ElbowConnection extends LineConnection {
    /*
     * Serialization support.
     */
    @Serial
    private static final long serialVersionUID = 2193968743082078559L;

    /**
     * Unused serial version number.
     */
    @SuppressWarnings("unused")
    private final int _elbowConnectionSerializedDataVersion = 1;

    /**
     * Constructs a new ElbowConnection.
     */
    public ElbowConnection() {
        super();
    }

    @Override
    public void updateConnection() {
        super.updateConnection();
        updatePoints();
    }

    @Override
    public void layoutConnection() {}

    /**
     * Gets the handles of the figure.
     */
    @Override
    public Vector<FigureHandle> handles() {
        Vector<FigureHandle> handles = new Vector<>(fPoints.size() * 2);
        handles.addElement(new ChangeConnectionStartHandle(this));
        for (int i = 1; i < fPoints.size() - 1; i++) {
            handles.addElement(new NullHandle(this, locator(i)));
        }
        handles.addElement(new ChangeConnectionEndHandle(this));
        for (int i = 0; i < fPoints.size() - 1; i++) {
            handles.addElement(new ElbowHandle(this, i));
        }
        return handles;
    }

    @Override
    public Locator connectedTextLocator(Figure f) {
        return new ElbowTextLocator();
    }

    /**
     * Method to update the points that form the ElbowConnection between the
     * owner objects. The Connection consists out of 2 points, if start and end are identical.
     * In any other case, four Points are used to create the double elbow shape.
     */
    protected void updatePoints() {
        willChange();
        Point start = startPoint();
        Point end = endPoint();
        fPoints.removeAllElements();
        fPoints.addElement(start);

        if (start.x == end.x || start.y == end.y) {
            fPoints.addElement(end);
        } else {
            Rectangle r1 = start().owner().displayBox();
            Rectangle r2 = end().owner().displayBox();

            int dir = Geom.direction(
                r1.x + r1.width / 2, r1.y + r1.height / 2, r2.x + r2.width / 2,
                r2.y + r2.height / 2);
            if (dir == Geom.NORTH || dir == Geom.SOUTH) {
                fPoints.addElement(new Point(start.x, (start.y + end.y) / 2));
                fPoints.addElement(new Point(end.x, (start.y + end.y) / 2));
            } else {
                fPoints.addElement(new Point((start.x + end.x) / 2, start.y));
                fPoints.addElement(new Point((start.x + end.x) / 2, end.y));
            }
            fPoints.addElement(end);
        }
        changed();
    }
}