/*******************************************************************************
 * Copyright (c) 2014, 2020 THALES GLOBAL SERVICES and others.
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Obeo - initial API and implementation
 *    IBM Corporation - The code from org.eclipse.gmf.runtime.draw2d.ui.internal.routers.RectilinearRouter
 *******************************************************************************/

package org.eclipse.sirius.diagram.ui.internal.operation;

import java.util.Iterator;
import java.util.List;
import java.util.Optional;

import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.ConnectionLayer;
import org.eclipse.draw2d.ConnectionRouter;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.PrecisionPoint;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.editparts.LayerManager;
import org.eclipse.gmf.runtime.common.ui.services.editor.EditorService;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
import org.eclipse.gmf.runtime.draw2d.ui.figures.BaseSlidableAnchor;
import org.eclipse.gmf.runtime.draw2d.ui.internal.figures.ConnectionLayerEx;
import org.eclipse.gmf.runtime.draw2d.ui.internal.routers.RectilinearRouter;
import org.eclipse.gmf.runtime.notation.Anchor;
import org.eclipse.gmf.runtime.notation.Bendpoints;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.IdentityAnchor;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.NotationFactory;
import org.eclipse.gmf.runtime.notation.RelativeBendpoints;
import org.eclipse.gmf.runtime.notation.Routing;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.sirius.common.ui.tools.api.util.EclipseUIUtil;
import org.eclipse.sirius.diagram.DEdge;
import org.eclipse.sirius.diagram.EdgeStyle;
import org.eclipse.sirius.diagram.description.CenteringStyle;
import org.eclipse.sirius.diagram.ui.business.api.query.ConnectionQuery;
import org.eclipse.sirius.diagram.ui.business.api.query.EdgeQuery;
import org.eclipse.sirius.diagram.ui.business.internal.operation.AbstractModelChangeOperation;
import org.eclipse.sirius.diagram.ui.graphical.figures.CanonicalRectilinearRouter;
import org.eclipse.sirius.diagram.ui.internal.edit.parts.DEdgeEditPart;
import org.eclipse.sirius.diagram.ui.internal.refresh.GMFHelper;
import org.eclipse.sirius.diagram.ui.tools.internal.routers.RectilinearEdgeUtil;
import org.eclipse.sirius.diagram.ui.tools.internal.util.GMFNotationUtilities;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;
import org.eclipse.sirius.ext.gmf.runtime.editparts.GraphicalHelper;
import org.eclipse.ui.IEditorPart;

/**
 * A Model Change Operation to center the edge source and/or target. The
 * operation will compute the edge anchor and bendpoints according to the
 * {@link EdgeStyle#isSourceCentered()} and {@link EdgeStyle#isTargetCentered()}
 * values.
 * 
 * @author Florian Barbin
 * 
 */
@SuppressWarnings("restriction")
public class CenterEdgeEndModelChangeOperation extends AbstractModelChangeOperation<Void> {

    private Edge edge;

    private PrecisionPoint existingSourceAnchorAbsoluteLocation;

    private PrecisionPoint existingTargetAnchorAbsoluteLocation;

    private PrecisionPoint newTargetAnchorAbsoluteLocation;

    private PrecisionPoint newSourceAnchorAbsoluteLocation;

    private ConnectionEditPart connectionEditPart;

    private Connection connection;

    private boolean useFigure = true;

    private Dimension sourceFigureSize;

    private Dimension targetFigureSize;

    private static final String CENTERED_ANCHOR = GMFNotationUtilities.getTerminalString(0.5d, 0.5d);

    /**
     * Constructor to use the connectionEditPart to compute the new edge
     * bendpoints.
     * 
     * @param connectionEditPart
     *            the edge connectionEditPart.
     * @param edge
     *            the GMF edge.
     */
    public CenterEdgeEndModelChangeOperation(ConnectionEditPart connectionEditPart, Edge edge) {
        this(edge);
        this.connectionEditPart = connectionEditPart;
        this.connection = (Connection) connectionEditPart.getFigure();
    }

    /**
     * Default constructor to center the given gmf edge ends (if needed). This
     * operation will try to retrieve the corresponding figure (if possible) to
     * compute the new bendpoints.
     * 
     * @param edge
     *            the GMF edge to center ends.
     */
    public CenterEdgeEndModelChangeOperation(Edge edge) {
        this.edge = edge;
    }

    /**
     * Constructor to explicitly specify whether this operation should try to
     * retrieve the edge figure to compute the new bendpoints.
     * 
     * @param edge
     *            the GMF edge.
     * @param useFigure
     *            true if this operation should use the corresponding draw2D
     *            figure, false otherwise.
     */
    public CenterEdgeEndModelChangeOperation(Edge edge, boolean useFigure) {
        this(edge);
        this.useFigure = useFigure;
    }

    /**
     * Set the source and target figure size. Those size will be used instead of
     * compute them.
     * 
     * @param sourceFigureSize
     *            the edge source figure size. If null, the size will be
     *            computed.
     * @param targetFigureSize
     *            the edge target figure size. If null, the size will be
     *            computed.
     */
    public void setSourceAndTargetSize(Dimension sourceFigureSize, Dimension targetFigureSize) {
        this.sourceFigureSize = sourceFigureSize;
        this.targetFigureSize = targetFigureSize;
    }

    @Override
    public Void execute() {
        Routing routingValue = getRoutingValue();

        // we do not handle Tree routing style
        if (!Routing.TREE_LITERAL.equals(routingValue)) {
            if (isEdgeSourceCentered() && isEdgeTargetCentered()) {

                centerEdgeEnds(CenteringStyle.BOTH, routingValue);
            } else if (isEdgeSourceCentered()) {
                centerEdgeEnds(CenteringStyle.SOURCE, routingValue);
            }

            else if (isEdgeTargetCentered()) {
                centerEdgeEnds(CenteringStyle.TARGET, routingValue);
            }
        }

        return null;
    }

    private Routing getRoutingValue() {
        Routing routingValue = Routing.MANUAL_LITERAL;
        EdgeQuery edgeQuery = new EdgeQuery(edge);
        if (edgeQuery.isEdgeWithTreeRoutingStyle()) {
            routingValue = Routing.TREE_LITERAL;
        } else if (edgeQuery.isEdgeWithRectilinearRoutingStyle()) {
            routingValue = Routing.RECTILINEAR_LITERAL;
        }
        return routingValue;
    }

    /**
     * Center the connection end (Source, Target or Both) according to the
     * center value.
     * 
     * @param center
     *            the {@link CenteringStyle} value.
     */
    private void centerEdgeEnds(CenteringStyle center, Routing routingValue) {
        Bendpoints bendpoints = edge.getBendpoints();

        if (bendpoints instanceof RelativeBendpoints) {
            View edgeSourceView = edge.getSource();
            View edgeTargetView = edge.getTarget();

            if (edgeSourceView instanceof Node && edgeTargetView instanceof Node) {

                setConnectionIfNull();

                // We get the edge source and target nodes absolute bounds to
                // compute absolute anchors coordinates
                Option<Rectangle> sourceBounds = getAbsoluteSourceBounds(edgeSourceView);
                Option<Rectangle> targetBounds = getAbsoluteTargetBounds(edgeTargetView);

                if (sourceBounds.some() && targetBounds.some()) {

                    // Calculate the existing anchors absolute location
                    retrieveAndSetExistingAnchorsAbsoluteLocation(sourceBounds.get(), targetBounds.get());

                    // Compute the new anchors absolute coordinates according to
                    // the center value.
                    computeAndSetNewAnchorsAbsoluteCoordinates(sourceBounds.get(), targetBounds.get(), center);

                    PointList newPointList = new PointList();
                    // Compute the existing bendpoints absolute location
                    newPointList = new ConnectionQuery(connection).getAbsolutePointList((RelativeBendpoints) bendpoints, existingSourceAnchorAbsoluteLocation, existingTargetAnchorAbsoluteLocation);
                    if (!(Routing.RECTILINEAR_LITERAL.getLiteral().equals(routingValue.getLiteral()))) {
                        // The default case of straight edge:
                        handleStraightCase(center, sourceBounds.get(), targetBounds.get(), newPointList);
                    } else {
                        // the rectilinear case
                        handleRectilinearCase(center, sourceBounds.get(), targetBounds.get(), newPointList);
                    }

                    GMFNotationUtilities.setGMFBendpoints(edge, newPointList, newSourceAnchorAbsoluteLocation, newTargetAnchorAbsoluteLocation);
                }
            }
        }

    }

    /**
     * Because of the difference between the GMF absolute bounds computation and
     * the draw2D absolute bounds, we will compute these bounds from draw2D if
     * we have access to the figure, or from GMF if we work in "pure" GMF
     * context.
     * 
     * @param gmfView
     *            the GMFView to compute the absolute bounds.
     * @param isSource
     *            true if it represents the edge source, false otherwise.
     * @return the absolute bounds.
     */
    private Option<Rectangle> getAbsoluteBounds(View gmfView, boolean isSource) {
        if (connectionEditPart != null) {
            EditPart editPart = null;
            if (isSource) {
                editPart = connectionEditPart.getSource();
            } else {
                editPart = connectionEditPart.getTarget();
            }
            if (editPart instanceof GraphicalEditPart) {
                return Options.newSome(GraphicalHelper.getAbsoluteBoundsIn100Percent((GraphicalEditPart) editPart));
            }
        }
        return GMFHelper.getAbsoluteBounds(gmfView, true, true);
    }

    private Option<Rectangle> getAbsoluteSourceBounds(View edgeSourceView) {
        Option<Rectangle> option = getAbsoluteBounds(edgeSourceView, true);
        if (sourceFigureSize != null && option.some()) {
            Rectangle rectangle = option.get();
            rectangle.setSize(sourceFigureSize);
        }
        return option;
    }

    private Option<Rectangle> getAbsoluteTargetBounds(View edgeTargetView) {
        Option<Rectangle> option = getAbsoluteBounds(edgeTargetView, false);
        if (targetFigureSize != null && option.some()) {
            Rectangle rectangle = option.get();
            rectangle.setSize(targetFigureSize);
        }
        return option;
    }

    /**
     * Deal with the straight edge case.
     * 
     * @param center
     *            the {@link Center} value: {@link Center#SOURCE}
     *            {@link Center#TARGET} or {@link Center#BOTH}.
     * @param sourceBounds
     *            the source figure bounds.
     * @param targetBounds
     *            the target figure bounds.
     * @param existingPointList
     *            the existing point list before centering any connection end.
     */
    private void handleStraightCase(CenteringStyle center, Rectangle sourceBounds, Rectangle targetBounds, PointList existingPointList) {
        Point sourceLineOrigin = newTargetAnchorAbsoluteLocation;
        Point targetLineOrigin = newSourceAnchorAbsoluteLocation;
        Point sourceLineTerminus = newSourceAnchorAbsoluteLocation;
        Point targetLineTerminus = newTargetAnchorAbsoluteLocation;

        // In case of edge with more than 2 bendpoints, we just
        // compute the last segment coordinates.
        if (existingPointList.size() > 2) {
            sourceLineOrigin = existingPointList.getPoint(1);
            targetLineOrigin = existingPointList.getPoint(existingPointList.size() - 2);
        }
        // In some particular cases, we could have a bendpoint list with less
        // than 2 elements. In this case we create a new point list that will
        // contain the two bendpoints computed from the intersection points.
        else if (existingPointList.size() < 2) {
            existingPointList = new PointList(new int[] { 0, 0, 0, 0 });
        }
        Optional<Point> sourceConnectionPoint = Optional.empty();
        Optional<Point> targetConnectionPoint = Optional.empty();

        if (center == CenteringStyle.BOTH || center == CenteringStyle.SOURCE) {
            sourceConnectionPoint = GraphicalHelper.getIntersection(sourceLineOrigin, sourceLineTerminus, sourceBounds, false);
        }
        if (center == CenteringStyle.BOTH || center == CenteringStyle.TARGET) {
            targetConnectionPoint = GraphicalHelper.getIntersection(targetLineOrigin, targetLineTerminus, targetBounds, false);
        }

        if (sourceConnectionPoint.isPresent() || targetConnectionPoint.isPresent()) {

            if (sourceConnectionPoint.isPresent()) {
                existingPointList.setPoint(sourceConnectionPoint.get(), 0);
                centerSourceAnchor();
            }

            if (targetConnectionPoint.isPresent()) {
                existingPointList.setPoint(targetConnectionPoint.get(), existingPointList.size() - 1);
                centerTargetAnchor();
            }
        }
    }

    /**
     * Deal with the rectilinear edge case.
     * 
     * @param center
     *            the {@link CenteringStyle} value:
     *            {@link CenteringStyle#SOURCE} {@link CenteringStyle#TARGET} or
     *            {@link CenteringStyle#BOTH}.
     * @param sourceBounds
     *            the source figure bounds.
     * @param targetBounds
     *            the target figure bounds.
     * @param existingPointList
     *            the existing point list before centering any connection end.
     */
    private void handleRectilinearCase(CenteringStyle center, Rectangle sourceBounds, Rectangle targetBounds, PointList existingPointList) {

        PointList rectilinear = null;

        // If the connection is available (the edge already exist) we retrieve
        // the rectilinear bendpoints.
        if (connection != null) {
            rectilinear = getRectilinearPointListFromConnection();

        } else {
            rectilinear = existingPointList.getCopy();

            // GMF bendpoints are not reliable: in some cases they are
            // completely far away from what draw2D is really displaying. If
            // there is only two GMF bendpoints, we can compute them with the
            // information we know. We also could have a point list with less
            // than two elements.
            if (rectilinear.size() <= 2) {
                computePointListByIntersections(rectilinear, sourceBounds, targetBounds);
            }
            if (rectilinear.size() >= 2) {
                CanonicalRectilinearRouter rectilinearRouter = new CanonicalRectilinearRouter();
                rectilinearRouter.routeLine(edge, 0, rectilinear, sourceBounds, targetBounds);
            }
        }
        if (rectilinear.size() >= 2) {
            RectilinearEdgeUtil.centerEdgeEnds(rectilinear, newSourceAnchorAbsoluteLocation, newTargetAnchorAbsoluteLocation, center);

            if (center == CenteringStyle.BOTH || center == CenteringStyle.SOURCE) {
                centerSourceAnchor();
            }
            if (center == CenteringStyle.BOTH || center == CenteringStyle.TARGET) {
                centerTargetAnchor();
            }

            existingPointList.removeAllPoints();
            existingPointList.addAll(rectilinear);
        }
    }

    private void computePointListByIntersections(PointList rectilinear, Rectangle sourceBounds, Rectangle targetBounds) {
        Optional<Point> sourceConnectionPoint = GraphicalHelper.getIntersection(existingSourceAnchorAbsoluteLocation, existingTargetAnchorAbsoluteLocation, sourceBounds, false);
        Optional<Point> targetConnectionPoint = GraphicalHelper.getIntersection(existingSourceAnchorAbsoluteLocation, existingTargetAnchorAbsoluteLocation, targetBounds, false);
        if (sourceConnectionPoint.isPresent() && targetConnectionPoint.isPresent()) {
            rectilinear.removeAllPoints();
            rectilinear.addPoint(sourceConnectionPoint.get());
            rectilinear.addPoint(targetConnectionPoint.get());
        }
    }

    private void computeAndSetNewAnchorsAbsoluteCoordinates(Rectangle sourceBounds, Rectangle targetBounds, CenteringStyle center) {

        newSourceAnchorAbsoluteLocation = existingSourceAnchorAbsoluteLocation;
        newTargetAnchorAbsoluteLocation = existingTargetAnchorAbsoluteLocation;

        // if the source is centered, we compute the new anchor coordinates
        // source anchor
        if (center == CenteringStyle.BOTH || center == CenteringStyle.SOURCE) {
            PrecisionPoint newSourceAnchor = new PrecisionPoint(0.5, 0.5);
            newSourceAnchorAbsoluteLocation = getAbsoluteAnchorCoordinates(sourceBounds, newSourceAnchor);
        }

        // if the target is centered, we compute the new anchor coordinates
        if (center == CenteringStyle.BOTH || center == CenteringStyle.TARGET) {

            PrecisionPoint newTargetAnchor = new PrecisionPoint(0.5, 0.5);
            newTargetAnchorAbsoluteLocation = getAbsoluteAnchorCoordinates(targetBounds, newTargetAnchor);
        }

    }

    private void retrieveAndSetExistingAnchorsAbsoluteLocation(Rectangle sourceBounds, Rectangle targetBounds) {
        existingSourceAnchorAbsoluteLocation = getAbsoluteAnchorCoordinates(sourceBounds, getAnchorId(edge.getSourceAnchor()));
        existingTargetAnchorAbsoluteLocation = getAbsoluteAnchorCoordinates(targetBounds, getAnchorId(edge.getTargetAnchor()));
    }

    private PrecisionPoint getAnchorId(Anchor anchor) {
        PrecisionPoint anchorId = new PrecisionPoint(0.5, 0.5);
        if (anchor instanceof IdentityAnchor) {
            anchorId = BaseSlidableAnchor.parseTerminalString(((IdentityAnchor) anchor).getId());
        }
        return anchorId;
    }

    /**
     * Set the source anchor at (0.5, 0.5).
     */
    private void centerSourceAnchor() {
        Anchor currentAnchor = edge.getSourceAnchor();
        IdentityAnchor newAnchor = setOrCreateNewAnchorIfNeeded(currentAnchor);
        if (newAnchor != currentAnchor) {
            edge.setSourceAnchor(newAnchor);
        }

    }

    /**
     * Set the target anchor at (0.5, 0.5).
     */
    private void centerTargetAnchor() {
        Anchor currentAnchor = edge.getTargetAnchor();
        IdentityAnchor newAnchor = setOrCreateNewAnchorIfNeeded(currentAnchor);
        if (newAnchor != currentAnchor) {
            edge.setTargetAnchor(newAnchor);
        }
    }

    private IdentityAnchor setOrCreateNewAnchorIfNeeded(Anchor anchor) {
        if (anchor instanceof IdentityAnchor) {
            if (!((IdentityAnchor) anchor).getId().equals(CENTERED_ANCHOR)) {
                ((IdentityAnchor) anchor).setId(CENTERED_ANCHOR);
            }
            return (IdentityAnchor) anchor;
        } else {
            IdentityAnchor a = NotationFactory.eINSTANCE.createIdentityAnchor();
            a.setId(CENTERED_ANCHOR);
            return a;
        }
    }

    /**
     * Compute the anchor absolute coordinates following the figure bounds and
     * the anchor location.
     * 
     * @param absoluteBounds
     *            the figure absolute bounds.
     * @param precisionPoint
     *            the anchor location.
     * @return the anchor absolute location.
     */
    private PrecisionPoint getAbsoluteAnchorCoordinates(Rectangle absoluteBounds, PrecisionPoint precisionPoint) {
        return new PrecisionPoint(absoluteBounds.x() + (absoluteBounds.width() * precisionPoint.preciseX()), absoluteBounds.y() + (absoluteBounds.height() * precisionPoint.preciseY()));

    }

    private boolean isEdgeSourceCentered() {
        return isCentered(true);
    }

    private boolean isEdgeTargetCentered() {
        return isCentered(false);
    }

    private boolean isCentered(boolean source) {
        boolean centered = false;
        EObject element = edge.getElement();
        if (element instanceof DEdge) {
            EdgeStyle edgeStyle = ((DEdge) element).getOwnedStyle();
            CenteringStyle centeringStyle = edgeStyle.getCentered();
            if (source) {
                centered = centeringStyle == CenteringStyle.BOTH || centeringStyle == CenteringStyle.SOURCE;
            } else {
                centered = centeringStyle == CenteringStyle.BOTH || centeringStyle == CenteringStyle.TARGET;
            }
        }
        return centered;
    }

    /**
     * We try to retrieve the edge connection figure.
     */
    @SuppressWarnings("rawtypes")
    private void setConnectionIfNull() {
        if (connection != null || !useFigure) {
            return;
        }
        Option<GraphicalEditPart> option = Options.newNone();
        final IEditorPart editorPart = EclipseUIUtil.getActiveEditor();
        if (editorPart instanceof DiagramEditor) {
            option = GMFHelper.getGraphicalEditPart(edge, (DiagramEditor) editorPart);

        }
        // If the active editor is not a DiagramEditor, that means the focus is
        // on a VSM or an other editor that triggered this operation
        else {

            List diagramEditors = EditorService.getInstance().getRegisteredEditorParts();
            for (Iterator it = diagramEditors.iterator(); it.hasNext();) {
                Object object = it.next();
                if (object instanceof DiagramEditor) {
                    option = GMFHelper.getGraphicalEditPart(edge, (DiagramEditor) object);
                }
                if (option.some()) {
                    break;
                }
            }

        }

        if (option.some()) {
            GraphicalEditPart editPart = option.get();
            if (editPart instanceof DEdgeEditPart) {
                connectionEditPart = (DEdgeEditPart) editPart;
                connection = ((DEdgeEditPart) editPart).getConnectionFigure();
            }
        }
    }

    /**
     * In the case of an existing edge that was oblique and is now transformed
     * to rectilinear, we need to anticipate the future rectilinear bendpoints
     * to next center the source or target connection ends.
     * 
     * <strong>We suppose the connection attribute is not null</strong>
     * 
     * @return a rectilinear PointList.
     */
    private PointList getRectilinearPointListFromConnection() {
        ConnectionRouter oldConnectionRouter = connection.getConnectionRouter();
        boolean needToRetrieveOldRouter = false;

        // If the router is already a rectilinear one, we don't need to change
        // it.
        if (!(oldConnectionRouter instanceof RectilinearRouter)) {
            ConnectionRouter connectionRouter = null;
            LayerManager layerManager = LayerManager.Helper.find(connectionEditPart);
            if (layerManager != null) {
                ConnectionLayer cLayer = (ConnectionLayer) layerManager.getLayer(LayerConstants.CONNECTION_LAYER);
                if (cLayer instanceof ConnectionLayerEx) {
                    connectionRouter = ((ConnectionLayerEx) cLayer).getRectilinearRouter();
                }
            }
            if (connectionRouter == null) {
                connectionRouter = new RectilinearRouter();
            }

            connection.setConnectionRouter(connectionRouter);
            needToRetrieveOldRouter = true;
        }

        connection.getConnectionRouter().route(connection);
        PointList pointList = connection.getPoints().getCopy();

        // We restore the old router once we got the rectilinear point
        // list.
        if (needToRetrieveOldRouter) {
            connection.setConnectionRouter(oldConnectionRouter);
            connection.getConnectionRouter().route(connection);
        }

        return pointList;
    }
}
