/*******************************************************************************
 * Copyright (c) 2011, 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
 *******************************************************************************/
package org.eclipse.sirius.diagram.ui.internal.refresh;

import java.io.File;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.Path;
import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.FigureUtilities;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PrecisionRectangle;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
import org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure;
import org.eclipse.gmf.runtime.notation.Bounds;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.LayoutConstraint;
import org.eclipse.gmf.runtime.notation.Location;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.RelativeBendpoints;
import org.eclipse.gmf.runtime.notation.Size;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.gmf.runtime.notation.datatype.RelativeBendpoint;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.sirius.common.tools.api.resource.FileProvider;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.common.ui.tools.api.util.EclipseUIUtil;
import org.eclipse.sirius.diagram.AbstractDNode;
import org.eclipse.sirius.diagram.ContainerStyle;
import org.eclipse.sirius.diagram.DDiagram;
import org.eclipse.sirius.diagram.DDiagramElement;
import org.eclipse.sirius.diagram.DDiagramElementContainer;
import org.eclipse.sirius.diagram.DNode;
import org.eclipse.sirius.diagram.DNodeContainer;
import org.eclipse.sirius.diagram.DNodeList;
import org.eclipse.sirius.diagram.WorkspaceImage;
import org.eclipse.sirius.diagram.business.api.query.DDiagramElementQuery;
import org.eclipse.sirius.diagram.business.internal.query.DDiagramElementContainerExperimentalQuery;
import org.eclipse.sirius.diagram.business.internal.query.DNodeContainerExperimentalQuery;
import org.eclipse.sirius.diagram.ui.business.api.query.NodeQuery;
import org.eclipse.sirius.diagram.ui.business.api.query.ViewQuery;
import org.eclipse.sirius.diagram.ui.business.internal.query.DNodeContainerQuery;
import org.eclipse.sirius.diagram.ui.business.internal.query.DNodeQuery;
import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramElementContainerEditPart;
import org.eclipse.sirius.diagram.ui.internal.edit.parts.AbstractDNodeContainerCompartmentEditPart;
import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeContainer2EditPart;
import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeList2EditPart;
import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeListEditPart;
import org.eclipse.sirius.diagram.ui.internal.refresh.borderednode.CanonicalDBorderItemLocator;
import org.eclipse.sirius.diagram.ui.part.SiriusVisualIDRegistry;
import org.eclipse.sirius.diagram.ui.provider.DiagramUIPlugin;
import org.eclipse.sirius.diagram.ui.provider.Messages;
import org.eclipse.sirius.diagram.ui.tools.api.layout.LayoutUtils;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;
import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.AlphaDropShadowBorder;
import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.IContainerLabelOffsets;
import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.LabelBorderStyleIds;
import org.eclipse.sirius.ui.business.api.dialect.DialectEditor;
import org.eclipse.sirius.ui.business.api.session.IEditingSession;
import org.eclipse.sirius.ui.business.api.session.SessionUIManager;
import org.eclipse.sirius.ui.tools.api.color.VisualBindingManager;
import org.eclipse.sirius.viewpoint.BasicLabelStyle;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;
import org.eclipse.sirius.viewpoint.description.style.LabelBorderStyleDescription;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.IEditorPart;

import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;

/**
 * GMF Helper.
 * 
 * @author edugueperoux
 */
public final class GMFHelper {

    /**
     * see org.eclipse.sirius.diagram.ui.internal.edit.parts. AbstractDNodeContainerCompartmentEditPart.DEFAULT_MARGIN
     * the Y value is the DEFAULT_MARGIN + the InvisibleResizableCompartmentFigure top Inset (1px)
     */
    private static Point CONTAINER_INSETS = new Point(AbstractDNodeContainerCompartmentEditPart.DEFAULT_MARGIN, IContainerLabelOffsets.LABEL_OFFSET);

    /**
     * The gap in pixels between the Label's icon and its text
     * (org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.SiriusWrapLabel.getIconTextGap()).
     */
    private static final int ICON_TEXT_GAP = 3;

    private GMFHelper() {
        // Helper to not instantiate
    }

    /**
     * Get the absolute location relative to the origin (Diagram).
     * 
     * @param node
     *            the GMF Node
     * 
     * @return the absolute location of the node relative to the origin (Diagram)
     */
    public static Point getAbsoluteLocation(Node node) {
        return getAbsoluteLocation(node, false);
    }

    /**
     * Get the absolute location relative to the origin (Diagram).
     * 
     * @param node
     *            the GMF Node
     * @param insetsAware
     *            true to consider the draw2D figures insets. <strong>Warning:</strong> Those insets are based on the
     *            current Sirius editParts and could become wrong if a developer customizes them.
     * 
     * @return the absolute location of the node relative to the origin (Diagram)
     */
    public static Point getAbsoluteLocation(Node node, boolean insetsAware) {
        Node currentNode = node;
        Point absoluteNodeLocation = getLocation(currentNode);
        if (currentNode.eContainer() instanceof Node) {
            currentNode = (Node) currentNode.eContainer();
            Point parentNodeLocation = getAbsoluteLocation(currentNode, insetsAware);
            absoluteNodeLocation.translate(parentNodeLocation);
            if (insetsAware) {
                translateWithInsets(absoluteNodeLocation, node);
            }
        }
        return absoluteNodeLocation;
    }

    /**
     * Return the top-left insets of the container of this <code>node</code>. The insets also considers its border.
     * 
     * @param node
     *            The current node
     * @param searchFirstParentContainer
     *            true to call recursively until finding a Node container, {@link NodeQuery#isContainer()}, false
     *            otherwise
     * @return the top-left insets of the container of this <code>node</code>
     */
    public static Dimension getContainerTopLeftInsets(Node node, boolean searchFirstParentContainer) {
        Dimension result = new Dimension(0, 0);
        EObject nodeContainer = node.eContainer();
        if (nodeContainer instanceof Node) {
            Node parentNode = (Node) nodeContainer;
            NodeQuery nodeQuery = new NodeQuery(parentNode);
            if (nodeQuery.isContainer()) {
                EObject element = parentNode.getElement();
                if (element instanceof DDiagramElementContainer) {
                    DDiagramElementContainer ddec = (DDiagramElementContainer) element;
                    // RegionContainer do not have containers insets
                    if (ddec instanceof DNodeContainer) {
                        if (new DNodeContainerExperimentalQuery((DNodeContainer) ddec).isRegionContainer() || hasFullLabelBorder(ddec)) {
                            result.setHeight(CONTAINER_INSETS.y + getLabelSize(parentNode) + AbstractDiagramElementContainerEditPart.DEFAULT_SPACING);
                        } else {
                            result.setWidth(CONTAINER_INSETS.x);
                            result.setHeight(CONTAINER_INSETS.y);
                        }
                    }
                    Dimension borderSize = getBorderSize(ddec);
                    result.setWidth(result.width() + borderSize.width());
                    result.setHeight(result.height() + borderSize.height());
                }
            } else if (searchFirstParentContainer) {
                result = getContainerTopLeftInsets(parentNode, searchFirstParentContainer);
            }
        }
        return result;
    }

    /**
     * Return the top-left insets of the container of this <code>node</code> that is after the label. The insets also
     * considers its border.
     * 
     * @param node
     *            The current node
     * @param searchFirstParentContainer
     *            true to call recursively until finding a Node container, {@link NodeQuery#isContainer()}, false
     *            otherwise
     * @return the top-left insets of the container of this <code>node</code>
     */
    public static Dimension getContainerTopLeftInsetsAfterLabel(Node node, boolean searchFirstParentContainer) {
        Dimension result = new Dimension(0, 0);
        EObject nodeContainer = node.eContainer();
        if (nodeContainer instanceof Node) {
            Node parentNode = (Node) nodeContainer;
            NodeQuery nodeQuery = new NodeQuery(parentNode);
            if (nodeQuery.isContainer()) {
                EObject element = parentNode.getElement();
                if (element instanceof DDiagramElementContainer) {
                    result.setWidth(CONTAINER_INSETS.x);
                    result.setHeight(CONTAINER_INSETS.y);

                    Dimension borderSize = getBorderSize((DDiagramElementContainer) element);
                    result.setWidth(result.width() + borderSize.width());
                    result.setHeight(result.height() + borderSize.height());
                }
            } else if (searchFirstParentContainer) {
                result = getContainerTopLeftInsets(parentNode, searchFirstParentContainer);
            }
        }
        return result;
    }

    /**
     * Get the border size of the <code>ddec</code> ({@link DDiagramElementContainer}).
     * 
     * @param ddec
     *            The {@link DDiagramElementContainer}
     * @return the border size of the diagram element container.
     */
    public static Dimension getBorderSize(DDiagramElementContainer ddec) {
        Dimension result = new Dimension(0, 0);
        ContainerStyle containerStyle = ddec.getOwnedStyle();
        int borderSize = containerStyle.getBorderSize().intValue();
        DDiagramElementContainerExperimentalQuery regionQuery = new DDiagramElementContainerExperimentalQuery(ddec);
        if (regionQuery.isRegionInHorizontalStack()) {
            result.setWidth(isFirstRegion(ddec) ? 0 : borderSize);
            result.setHeight(1);
        } else if (regionQuery.isRegionInVerticalStack()) {
            result.setWidth(1);
            result.setHeight(isFirstRegion(ddec) ? 1 : borderSize);
        } else {
            result.setWidth(borderSize);
            result.setHeight(borderSize);
        }
        return result;
    }

    /**
     * Shift the current node absolute location by the container insets.
     * 
     * @param locationToTranslate
     *            the current computed location that will be translated by the container insets.
     * @param currentNode
     *            the current node for which we translate location. We do not change the currentNode bounds.
     */
    private static void translateWithInsets(Point locationToTranslate, Node currentNode) {
        NodeQuery nodeQuery = new NodeQuery(currentNode);
        // bordered node are not concerned by those insets.
        if (!nodeQuery.isBorderedNode()) {
            locationToTranslate.translate(getContainerTopLeftInsets(currentNode, false));
        }
    }

    private static boolean hasFullLabelBorder(DDiagramElementContainer ddec) {
        Option<LabelBorderStyleDescription> labelBorderStyle = new DDiagramElementContainerExperimentalQuery(ddec).getLabelBorderStyle();
        return labelBorderStyle.some() && LabelBorderStyleIds.LABEL_FULL_BORDER_STYLE_FOR_CONTAINER_ID.equals(labelBorderStyle.get().getId());
    }

    private static int getLabelSize(Node parentNode) {
        int labelSize = 0;
        for (Node child : Iterables.filter(parentNode.getVisibleChildren(), Node.class)) {
            if (new ViewQuery(child).isForNameEditPart()) {
                // TODO Compute the real label height
                // It depends on the font size
                // It might require to set the layout constraint of the label
                // GMF node which will not be used by the
                // ConstrainedToolbarLayout to locate the label but might be
                // usefull to store the value in the model.
                labelSize = 16;
                break;
            }
        }
        return labelSize;
    }

    private static boolean isFirstRegion(DDiagramElementContainer ddec) {
        EObject potentialRegionContainer = ddec.eContainer();
        if (potentialRegionContainer instanceof DNodeContainer) {
            Iterable<DDiagramElementContainer> regions = Iterables.filter(((DNodeContainer) potentialRegionContainer).getOwnedDiagramElements(), DDiagramElementContainer.class);
            return !Iterables.isEmpty(regions) && ddec == Iterables.getFirst(regions, null);
        }
        return false;
    }

    /**
     * Shift the current node absolute bounds location by the container insets.
     * 
     * @param boundsToTranslate
     *            the current computed bounds that will be translated by the container insets.
     * @param currentNode
     *            the current node for which we translate bounds. We do not change the currentNode bounds.
     */
    private static void translateWithInsets(Rectangle boundsToTranslate, Node currentNode) {
        Point location = boundsToTranslate.getLocation();
        translateWithInsets(location, currentNode);
        boundsToTranslate.setLocation(location);
    }

    /**
     * Compute the location of a GMF node.
     * 
     * @param node
     *            the node whose location to compute.
     * @return the location of the node.
     */
    public static Point getLocation(Node node) {
        Point location = new Point(0, 0);
        LayoutConstraint layoutConstraint = node.getLayoutConstraint();
        if (layoutConstraint instanceof Bounds) {
            Bounds gmfBounds = (Bounds) layoutConstraint;
            location.x = gmfBounds.getX();
            location.y = gmfBounds.getY();
            // manage location of bordered node with closest side
            if (node.getElement() instanceof DNode && node.getElement().eContainer() instanceof AbstractDNode) {
                DNode dNode = (DNode) node.getElement();
                AbstractDNode parentAbstractDNode = (AbstractDNode) dNode.eContainer();
                if (parentAbstractDNode.getOwnedBorderedNodes().contains(dNode)) {
                    Node parentNode = (Node) node.eContainer();
                    LayoutConstraint parentLayoutConstraint = parentNode.getLayoutConstraint();
                    if (parentLayoutConstraint instanceof Bounds) {
                        Bounds parentBounds = (Bounds) parentLayoutConstraint;
                        int position = CanonicalDBorderItemLocator.findClosestSideOfParent(new Rectangle(gmfBounds.getX(), gmfBounds.getY(), gmfBounds.getWidth(), gmfBounds.getHeight()),
                                new Rectangle(parentBounds.getX(), parentBounds.getY(), parentBounds.getWidth(), parentBounds.getHeight()));
                        updateLocation(location, position, parentBounds, gmfBounds);
                    }
                }
            }
        }
        return location;
    }

    private static void updateLocation(Point location, int position, Bounds parentBounds, Bounds gmfBounds) {
        switch (position) {
        case PositionConstants.NORTH:
        case PositionConstants.SOUTH:
            if (location.x == 0) {
                location.x += (parentBounds.getWidth() - gmfBounds.getWidth()) / 2;
            }
            break;
        case PositionConstants.WEST:
        case PositionConstants.EAST:
            if (location.y == 0) {
                location.y += (parentBounds.getHeight() - gmfBounds.getHeight()) / 2;
            }
            break;
        default:
            break;
        }
    }

    /**
     * Get the absolute bounds relative to the origin (Diagram).
     * 
     * @param node
     *            the GMF Node
     * 
     * @return the absolute bounds of the node relative to the origin (Diagram)
     */
    public static Rectangle getAbsoluteBounds(Node node) {
        return getAbsoluteBounds(node, false, false);
    }

    /**
     * Get the absolute bounds relative to the origin (Diagram).
     * 
     * @param node
     *            the GMF Node
     * @param insetsAware
     *            true to consider the draw2D figures insets. <strong>Warning:</strong> Those insets are based on the
     *            current Sirius editParts and could become wrong if a developer customizes them.
     * 
     * @return the absolute bounds of the node relative to the origin (Diagram)
     */
    public static Rectangle getAbsoluteBounds(Node node, boolean insetsAware) {
        return getAbsoluteBounds(node, false, false);
    }

    /**
     * Get the absolute bounds relative to the origin (Diagram).
     * 
     * @param node
     *            the GMF Node
     * @param insetsAware
     *            true to consider the draw2D figures insets. <strong>Warning:</strong> Those insets are based on the
     *            current Sirius editParts and could become wrong if a developer customizes them.
     * @param boxForConnection
     *            true if we want to have the bounds used to compute connection anchor from source or target, false
     *            otherwise
     * @return the absolute bounds of the node relative to the origin (Diagram)
     */
    public static Rectangle getAbsoluteBounds(Node node, boolean insetsAware, boolean boxForConnection) {
        Node currentNode = node;
        Rectangle absoluteNodeBounds = getBounds(currentNode, false, false, boxForConnection);
        if (currentNode.eContainer() instanceof Node) {
            currentNode = (Node) currentNode.eContainer();
            Point parentNodeLocation = getAbsoluteLocation(currentNode, insetsAware);
            absoluteNodeBounds = absoluteNodeBounds.getTranslated(parentNodeLocation);
            if (insetsAware) {
                translateWithInsets(absoluteNodeBounds, node);
            }
        }
        return absoluteNodeBounds;
    }

    /**
     * Get the absolute bounds relative to the origin (Diagram).
     * 
     * @param edge
     *            the GMF Node
     * 
     * @return the absolute bounds of the edge relative to the origin (Diagram)
     */
    public static Option<Rectangle> getAbsoluteBounds(Edge edge) {
        return getAbsoluteBounds(edge, false, false);
    }

    /**
     * Get the absolute bounds relative to the origin (Diagram).
     * 
     * @param edge
     *            the GMF Node
     * @param insetsAware
     *            true to consider the draw2D figures insets. <strong>Warning:</strong> Those insets are based on the
     *            current Sirius editParts and could become wrong if a developer customizes them.
     * @param boxForConnection
     *            true if we want to have the bounds used to compute connection anchor from source or target, false
     *            otherwise
     * 
     * @return the absolute bounds of the edge relative to the origin (Diagram)
     */
    public static Option<Rectangle> getAbsoluteBounds(Edge edge, boolean insetsAware, boolean boxForConnection) {
        // Workaround for canonical refresh about edge on edge
        Option<Rectangle> optionalSourceBounds = getAbsoluteBounds(edge.getSource(), insetsAware);
        Option<Rectangle> optionalTargetBounds = getAbsoluteBounds(edge.getTarget(), insetsAware);
        if (optionalSourceBounds.some() && optionalTargetBounds.some()) {
            return Options.newSome(optionalSourceBounds.get().union(optionalTargetBounds.get()));
        }
        return Options.newNone();
    }

    /**
     * Get the absolute bounds relative to the origin (Diagram).
     * 
     * @param view
     *            the GMF Node or Edge
     * 
     * @return an optional absolute bounds of the node or edge relative to the origin (Diagram)
     */
    public static Option<Rectangle> getAbsoluteBounds(View view) {
        return getAbsoluteBounds(view, false);
    }

    /**
     * Get the absolute bounds relative to the origin (Diagram).
     * 
     * @param view
     *            the GMF Node or Edge
     * @param insetsAware
     *            true to consider the draw2D figures insets. <strong>Warning:</strong> Those insets are based on the
     *            current Sirius editParts and could become wrong if a developer customizes them.
     * 
     * @return an optional absolute bounds of the node or edge relative to the origin (Diagram)
     */
    public static Option<Rectangle> getAbsoluteBounds(View view, boolean insetsAware) {
        return getAbsoluteBounds(view, insetsAware, false);
    }

    /**
     * Get the absolute bounds relative to the origin (Diagram).
     * 
     * @param view
     *            the GMF Node or Edge
     * @param insetsAware
     *            true to consider the draw2D figures insets. <strong>Warning:</strong> Those insets are based on the
     *            current Sirius editParts and could become wrong if a developer customizes them.
     * @param boxForConnection
     *            true if we want to have the bounds used to compute connection anchor from source or target, false
     *            otherwise
     * 
     * @return an optional absolute bounds of the node or edge relative to the origin (Diagram)
     */
    public static Option<Rectangle> getAbsoluteBounds(View view, boolean insetsAware, boolean boxForConnection) {
        Option<Rectangle> result = Options.newNone();
        if (view instanceof Node) {
            result = Options.newSome(getAbsoluteBounds((Node) view, insetsAware, boxForConnection));
        } else if (view instanceof Edge) {
            result = getAbsoluteBounds((Edge) view, insetsAware, boxForConnection);
        }
        return result;
    }

    /**
     * Compute the bounds of a GMF node.
     * 
     * @param node
     *            the node whose bounds to compute.
     * @return the bounds of the node.
     */
    public static Rectangle getBounds(Node node) {
        return getBounds(node, false);
    }

    /**
     * Compute the bounds of a GMF node.
     * 
     * @param node
     *            the node whose bounds to compute.
     * @param useFigureForAutoSizeConstraint
     *            true to use figure for auto size constraint
     * @return the bounds of the node.
     */
    public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstraint) {
        return getBounds(node, useFigureForAutoSizeConstraint, false);
    }

    /**
     * Compute the bounds of a GMF node.
     * 
     * @param node
     *            the node whose bounds to compute.
     * @param useFigureForAutoSizeConstraint
     *            true to use figure for auto size constraint
     * @param forceFigureAutoSize
     *            if useFigureForAutoSizeConstraint and if the found edit part supports it, force auto size and validate
     *            the parent to get the auto-sized dimension (during auto-size for example)
     * @return the bounds of the node.
     */
    public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstraint, boolean forceFigureAutoSize) {
        return getBounds(node, useFigureForAutoSizeConstraint, false, false);
    }

    /**
     * Compute the bounds of a GMF node.
     * 
     * @param node
     *            the node whose bounds to compute.
     * @param useFigureForAutoSizeConstraint
     *            true to use figure for auto size constraint
     * @param forceFigureAutoSize
     *            if useFigureForAutoSizeConstraint and if the found edit part supports it, force auto size and validate
     *            the parent to get the auto-sized dimension (during auto-size for example)
     * @param boxForConnection
     *            true if we want to have the bounds used to compute connection anchor from source or target, false
     *            otherwise
     * @return the bounds of the node.
     */
    public static Rectangle getBounds(Node node, boolean useFigureForAutoSizeConstraint, boolean forceFigureAutoSize, boolean boxForConnection) {
        PrecisionRectangle bounds = new PrecisionRectangle(0, 0, 0, 0);
        LayoutConstraint layoutConstraint = node.getLayoutConstraint();
        EObject element = node.getElement();
        if (element instanceof AbstractDNode) {
            AbstractDNode abstractDNode = (AbstractDNode) element;
            if (layoutConstraint instanceof Location) {
                bounds.x = ((Location) layoutConstraint).getX();
                bounds.y = ((Location) layoutConstraint).getY();
            }
            if (layoutConstraint instanceof Size) {
                bounds.width = ((Size) layoutConstraint).getWidth();
                bounds.height = ((Size) layoutConstraint).getHeight();
            } else {
                bounds.width = -1;
                bounds.height = -1;
            }

            if (new ViewQuery(node).isForNameEditPart()) {
                if (abstractDNode.getName() == null || abstractDNode.getName().length() == 0) {
                    if (bounds.width == -1) {
                        bounds.width = 0;
                    }
                    if (bounds.height == -1) {
                        bounds.height = 0;
                    }
                } else {

                    // Make a default size for label (this size is purely an average estimate)
                    replaceAutoSize(node, bounds, useFigureForAutoSizeConstraint, getLabelDimension(node, new Dimension(50, 20)));
                }
            } else {
                replaceAutoSize(node, bounds, useFigureForAutoSizeConstraint, null);
            }

            if (boxForConnection) {
                // Remove the shadow border size (as it is done in SlidableAnchor.getBox() that calls
                // HandleBounds.getHandleBounds() (for example
                // org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure.getHandleBounds())
                // This insets corresponds to insets of {@link
                // org.eclipse.sirius.diagram.ui.tools.api.figure.AlphaDropShadowBorder#getTransparentInsets()}.
                double shadowBorderSize = getShadowBorderSize(node);
                bounds.width -= shadowBorderSize;
                bounds.height -= shadowBorderSize;
            }
        }
        return bounds;
    }

    /**
     * If the editPart is a container and is not a workspace image or a regions, the default shadow border size is
     * returned. Otherwise, 0 is returned. See
     * {@link AbstractDiagramElementContainerEditPart#addDropShadow(NodeFigure,IFigure)}.
     * 
     * @param editPart
     *            an edit part
     * @return The shadow border size of the edit part
     */
    public static double getShadowBorderSize(Node node) {
        double shadowBorderSize = 0;
        if (isShadowBorderNeeded(node)) {
            shadowBorderSize = AlphaDropShadowBorder.getDefaultShadowSize();
        }
        return shadowBorderSize;
    }

    /**
     * Shadow border is needed for all container except for regions or workspace image styles. These can have a
     * non-rectangular contour and transparent zones which should be kept as is.
     * 
     * @return false for regions and workspace images, true otherwise.
     */
    public static boolean isShadowBorderNeeded(Node node) {
        boolean needShadowBorder = false;
        EObject element = node.getElement();
        if (element instanceof DDiagramElementContainer) {
            DDiagramElementContainer ddec = (DDiagramElementContainer) element;
            needShadowBorder = !(new DDiagramElementContainerExperimentalQuery(ddec).isRegion() || ddec.getOwnedStyle() instanceof WorkspaceImage);
        }
        return needShadowBorder;
    }

    /**
     * This method replace the -1x-1 size with a more realistic size. This size is probably not exactly the same as in
     * draw2d but much closer that -1x-1.
     * 
     * @param node
     *            The GMF node with the auto-size
     * @param bounds
     *            The bounds with auto-size to replace.
     * @param useFigureForAutoSizeConstraint
     *            true to use draw2d figure to get size
     * @param providedDefaultSize
     *            The size used for creation for this kind of <code>node</code>. It is the minimum size.
     */
    private static void replaceAutoSize(Node node, Rectangle bounds, boolean useFigureForAutoSizeConstraint, Dimension providedDefaultSize) {
        if (bounds.width == -1 || bounds.height == -1) {
            Dimension defaultSize = providedDefaultSize;
            if (providedDefaultSize == null) {
                // if there is no default size, we compute it from the given
                // node.
                EObject element = node.getElement();
                if (element instanceof AbstractDNode) {
                    defaultSize = getDefaultSize((AbstractDNode) element);
                }
            }
            if (useFigureForAutoSizeConstraint) {
                // Use the figure (if founded) to set width and height
                // instead of (-1, -1)
                Option<GraphicalEditPart> optionalTargetEditPart = getGraphicalEditPart(node);
                // CHECKSTYLE:OFF
                if (optionalTargetEditPart.some()) {
                    GraphicalEditPart graphicalEditPart = optionalTargetEditPart.get();
                    if (graphicalEditPart instanceof AbstractDiagramElementContainerEditPart) {
                        ((AbstractDiagramElementContainerEditPart) graphicalEditPart).forceFigureAutosize();
                        ((GraphicalEditPart) graphicalEditPart.getParent()).getFigure().validate();
                    }

                    Rectangle figureBounds = graphicalEditPart.getFigure().getBounds();
                    if (bounds.width == -1) {
                        bounds.width = figureBounds.width;
                    }
                    if (bounds.height == -1) {
                        bounds.height = figureBounds.height;
                    }
                } else {
                    // Diagram editor might be initializing and there is no edit
                    // part yet. For regions we might retrieve the previous
                    // known constraints in the GMF model by looking into the
                    // GMF location of the next region as they were computed
                    // from the location and size of the current region.
                    lookForNextRegionLocation(bounds, node);
                }
                // CHECKSTYLE:ON
            } else {
                // Compute the bounds of all children and use the lowest
                // one (y+height) for height and the rightmost one
                // (x+width) for width.
                Point bottomRight = getBottomRight(node);
                if (bounds.width == -1) {
                    if (bottomRight.x > defaultSize.width) {
                        bounds.width = bottomRight.x;
                    } else {
                        bounds.width = defaultSize.width;
                    }
                }
                if (bounds.height == -1) {
                    if (bottomRight.y > defaultSize.height) {
                        bounds.height = bottomRight.y;
                    } else {
                        bounds.height = defaultSize.height;
                    }
                }
            }

            if (bounds.width == -1) {
                bounds.width = defaultSize.width;
            }
            if (bounds.height == -1) {
                bounds.height = defaultSize.height;
            }
        }
    }

    private static void lookForNextRegionLocation(Rectangle bounds, Node node) {
        EObject element = node.getElement();
        if (element instanceof DDiagramElementContainer && node.eContainer() instanceof Node) {
            DDiagramElementContainer ddec = (DDiagramElementContainer) element;
            DDiagramElementContainerExperimentalQuery query = new DDiagramElementContainerExperimentalQuery(ddec);
            boolean isRegion = query.isRegion();
            EList children = ((Node) node.eContainer()).getChildren();
            int currentIndex = children.indexOf(node);
            if (!(currentIndex != 0 && bounds.equals(new Rectangle(0, 0, -1, -1)))) {
                // We are not in the case of a new region insertion (in this
                // case, we use the default size)
                int nextIndex = currentIndex + 1;
                if (isRegion && nextIndex != 0 && nextIndex < children.size() && children.get(nextIndex) instanceof Node) {
                    Node nextNode = (Node) children.get(nextIndex);
                    int visualID = SiriusVisualIDRegistry.getVisualID(nextNode.getType());
                    if (DNodeContainer2EditPart.VISUAL_ID == visualID || DNodeListEditPart.VISUAL_ID == visualID || DNodeList2EditPart.VISUAL_ID == visualID) {
                        // DNodeContainerEditPart.VISUAL_ID == visualID is not
                        // checked as a region cannot be a
                        // DNodeContainerEditPart as it is directly contained by
                        // the diagram part.
                        LayoutConstraint layoutConstraint = nextNode.getLayoutConstraint();
                        if (layoutConstraint instanceof Location) {
                            Location nextLocation = (Location) layoutConstraint;
                            // Update only the parent stack direction if some
                            // layout has already been done.
                            if (bounds.width == -1 && query.isRegionInHorizontalStack() && nextLocation.getX() != 0) {
                                bounds.width = nextLocation.getX() - bounds.x;
                            }
                            if (bounds.height == -1 && query.isRegionInVerticalStack() && nextLocation.getY() != 0) {
                                bounds.height = nextLocation.getY() - bounds.y;
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * Returns a new Point representing the bottom right point of all bounds of children of this Node. Useful for Node
     * with size of -1x-1 to be more accurate (but it is still not necessarily the same size that draw2d).
     * 
     * @param node
     *            the node whose bottom right corner is to compute.
     * 
     * @return Point at the bottom right of the rectangle
     */
    public static Point getBottomRight(Node node) {
        int right = 0;
        int bottom = 0;
        for (Iterator<Node> children = Iterators.filter(node.getChildren().iterator(), Node.class); children.hasNext(); /* */) {
            Node child = children.next();
            // The bordered nodes is ignored
            if (!(new NodeQuery(node).isBorderedNode())) {
                Rectangle bounds = getBounds(child);
                Point bottomRight = bounds.getBottomRight();
                if (bottomRight.x > right) {
                    right = bottomRight.x;
                }
                if (bottomRight.y > bottom) {
                    bottom = bottomRight.y;
                }
            }
        }
        return new Point(right, bottom);
    }

    private static Dimension getDefaultSize(AbstractDNode abstractDNode) {
        Dimension defaultSize = new Dimension(-1, -1);
        if (abstractDNode instanceof DNode) {
            defaultSize = new DNodeQuery((DNode) abstractDNode).getDefaultDimension();
        } else if (abstractDNode instanceof DNodeContainer) {
            defaultSize = new DNodeContainerQuery((DNodeContainer) abstractDNode).getDefaultDimension();
        } else if (abstractDNode instanceof DNodeList) {
            defaultSize = LayoutUtils.NEW_DEFAULT_CONTAINER_DIMENSION;
        }
        return defaultSize;
    }

    /**
     * Return an option with the editPart corresponding to the <code>view</code> in the current diagram or an empty
     * Option if there is no corresponding editPart.
     * 
     * @param view
     *            The view element that is searched
     * @return The optional corresponding edit part.
     */
    public static Option<GraphicalEditPart> getGraphicalEditPart(View view) {
        if (view != null) {
            Diagram gmfDiagram = view.getDiagram();
            // Try the active editor first (most likely case in practice)
            IEditorPart editor = EclipseUIUtil.getActiveEditor();
            if (isEditorFor(editor, gmfDiagram)) {
                return getGraphicalEditPart(view, (DiagramEditor) editor);
            } else if (gmfDiagram.getElement() instanceof DDiagram) {
                // Otherwise check all active Sirius editors
                for (IEditingSession uiSession : SessionUIManager.INSTANCE.getUISessions()) {
                    DialectEditor dialectEditor = uiSession.getEditor((DDiagram) gmfDiagram.getElement());
                    if (isEditorFor(dialectEditor, gmfDiagram)) {
                        return getGraphicalEditPart(view, (DiagramEditor) dialectEditor);
                    }
                }
            }
        }
        return Options.<GraphicalEditPart> newNone();
    }

    private static boolean isEditorFor(IEditorPart editor, Diagram diagram) {
        return editor instanceof DiagramEditor && ((DiagramEditor) editor).getDiagram() == diagram;
    }

    /**
     * Return an option with the editPart corresponding to the <code>view</code> in the current diagram or an empty
     * Option if there is no corresponding editPart.
     * 
     * @param view
     *            The view element that is searched
     * @param editor
     *            the editor where looking for the edit part.
     * @return The optional corresponding edit part.
     */
    public static Option<GraphicalEditPart> getGraphicalEditPart(View view, DiagramEditor editor) {
        Option<GraphicalEditPart> result = Options.newNone();
        final Map<?, ?> editPartRegistry = editor.getDiagramGraphicalViewer().getEditPartRegistry();
        final EditPart targetEditPart = (EditPart) editPartRegistry.get(view);
        if (targetEditPart instanceof GraphicalEditPart) {
            result = Options.newSome((GraphicalEditPart) targetEditPart);
        }
        return result;
    }

    /**
     * Get the points list computed from GMF bendpoints according to source side for the <code>edgeEditPart</code>.
     * 
     * @param edgeEditPart
     *            The concerned edge edit part.
     * @return Points list
     * @throws IllegalArgumentException
     *             when the edgeEditPart is not as expected
     */
    public static List<Point> getPointsFromSource(ConnectionEditPart edgeEditPart) throws IllegalArgumentException {
        if (edgeEditPart.getModel() instanceof Edge && edgeEditPart.getFigure() instanceof Connection) {
            List<Point> result = new ArrayList<>();
            Edge gmfEdge = (Edge) edgeEditPart.getModel();
            Connection connectionFigure = (Connection) edgeEditPart.getFigure();
            Point srcAnchorLoc = connectionFigure.getSourceAnchor().getReferencePoint();
            connectionFigure.translateToRelative(srcAnchorLoc);

            RelativeBendpoints bp = (RelativeBendpoints) gmfEdge.getBendpoints();
            for (int i = 0; i < bp.getPoints().size(); i++) {
                RelativeBendpoint rbp = (RelativeBendpoint) bp.getPoints().get(i);
                Point fromSrc = srcAnchorLoc.getTranslated(rbp.getSourceX(), rbp.getSourceY());
                result.add(fromSrc);
            }
            return result;
        }
        throw new IllegalArgumentException(Messages.GMFHelper_invalidEdgeModelAndFigure);
    }

    /**
     * Get the points list computed from GMF bendpoints according to target side for the <code>edgeEditPart</code>.
     * 
     * @param edgeEditPart
     *            The concerned edge edit part.
     * @return Points list
     * @throws IllegalArgumentException
     *             when the edgeEditPart is not as expected
     */
    public static List<Point> getPointsFromTarget(ConnectionEditPart edgeEditPart) throws IllegalArgumentException {
        if (edgeEditPart.getModel() instanceof Edge && edgeEditPart.getFigure() instanceof Connection) {
            List<Point> result = new ArrayList<>();
            Edge gmfEdge = (Edge) edgeEditPart.getModel();
            Connection connectionFigure = (Connection) edgeEditPart.getFigure();
            Point tgtAnchorLoc = connectionFigure.getTargetAnchor().getReferencePoint();
            connectionFigure.translateToRelative(tgtAnchorLoc);

            RelativeBendpoints bp = (RelativeBendpoints) gmfEdge.getBendpoints();
            for (int i = 0; i < bp.getPoints().size(); i++) {
                RelativeBendpoint rbp = (RelativeBendpoint) bp.getPoints().get(i);
                Point fromTgt = tgtAnchorLoc.getTranslated(rbp.getTargetX(), rbp.getTargetY());
                result.add(fromTgt);
            }
            return result;
        }
        throw new IllegalArgumentException(Messages.GMFHelper_invalidEdgeModelAndFigure);
    }

    /**
     * Compute the size of a label. This method uses "UI data" to retrieve the label size. It must be called in UI
     * thread to have right result, otherwise <code>defaultDimension</code> will be used.
     * 
     * @param node
     *            the node, corresponding to a DNodeNameEditPart, whose size to compute.
     * @param defaultDimension
     *            the default dimension to use if it is not possible to get a "real" size
     * @return the size of the label.
     */
    public static Dimension getLabelDimension(Node node, Dimension defaultDimension) {
        Dimension labelSize = defaultDimension;
        ViewQuery viewQuery = new ViewQuery(node);
        EObject element = node.getElement();
        if (element instanceof DDiagramElement) {
            DDiagramElement dDiagramElement = (DDiagramElement) element;
            org.eclipse.sirius.viewpoint.Style siriusStyle = dDiagramElement.getStyle();
            if (!new DDiagramElementQuery(dDiagramElement).isLabelHidden()) {
                if (siriusStyle instanceof BasicLabelStyle) {
                    BasicLabelStyle bls = (BasicLabelStyle) siriusStyle;
                    Font defaultFont = VisualBindingManager.getDefault().getFontFromLabelStyle(bls, (String) viewQuery.getDefaultValue(NotationPackage.Literals.FONT_STYLE__FONT_NAME));
                    try {
                        labelSize = FigureUtilities.getStringExtents(dDiagramElement.getName(), defaultFont);
                        if (bls.isShowIcon()) {
                            // Also consider the icon size
                            Dimension iconDimension = getIconDimension(dDiagramElement, bls);
                            labelSize.setHeight(Math.max(labelSize.height(), iconDimension.height));
                            labelSize.setWidth(labelSize.width() + ICON_TEXT_GAP + iconDimension.width);
                        }
                    } catch (SWTException e) {
                        // Probably an "Invalid thread access" (FigureUtilities
                        // creates a new Shell to compute the label size). So in
                        // this case, we use the default size.
                    }
                }
            }
        }
        return labelSize;
    }

    private static Dimension getIconDimension(DSemanticDecorator dSemanticDecorator, BasicLabelStyle bls) {
        ImageDescriptor descriptor = null;
        EObject target = dSemanticDecorator.getTarget();
        if (!StringUtil.isEmpty(bls.getIconPath())) {
            String iconPath = bls.getIconPath();
            final File imageFile = FileProvider.getDefault().getFile(new Path(iconPath));
            if (imageFile != null && imageFile.exists() && imageFile.canRead()) {
                try {
                    descriptor = DiagramUIPlugin.Implementation.findImageDescriptor(imageFile.toURI().toURL());
                } catch (MalformedURLException e) {
                    // Do nothing here
                }
            }
        } else if (target != null) {
            final IItemLabelProvider labelProvider = (IItemLabelProvider) DiagramUIPlugin.getPlugin().getItemProvidersAdapterFactory().adapt(target, IItemLabelProvider.class);
            if (labelProvider != null) {
                descriptor = ExtendedImageRegistry.getInstance().getImageDescriptor(labelProvider.getImage(target));
            }
        }

        if (descriptor == null) {
            descriptor = ImageDescriptor.getMissingImageDescriptor();
        }
        Image icon = DiagramUIPlugin.getPlugin().getImage(descriptor);
        return new Dimension(icon.getBounds().width, icon.getBounds().height);
    }
}
