/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.ide.eclipse.adt.internal.editors.layout.gle2;

import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_ID;
import static com.android.SdkConstants.FQCN_SPACE;
import static com.android.SdkConstants.FQCN_SPACE_V7;
import static com.android.SdkConstants.NEW_ID_PREFIX;
import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.SelectionHandle.PIXEL_MARGIN;
import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.SelectionHandle.PIXEL_RADIUS;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.api.INode;
import com.android.ide.common.api.RuleAction;
import com.android.ide.common.layout.BaseViewRule;
import com.android.ide.common.layout.GridLayoutRule;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.layout.gre.NodeFactory;
import com.android.ide.eclipse.adt.internal.editors.layout.gre.NodeProxy;
import com.android.ide.eclipse.adt.internal.editors.layout.gre.RulesEngine;
import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.refactorings.core.RenameResourceWizard;
import com.android.ide.eclipse.adt.internal.refactorings.core.RenameResult;
import com.android.ide.eclipse.adt.internal.resources.ResourceNameValidator;
import com.android.resources.ResourceType;
import com.android.utils.Pair;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MenuDetectEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IWorkbenchPartSite;
import org.w3c.dom.Node;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;

/**
 * The {@link SelectionManager} manages the selection in the canvas editor.
 * It holds (and can be asked about) the set of selected items, and it also has
 * operations for manipulating the selection - such as toggling items, copying
 * the selection to the clipboard, etc.
 * <p/>
 * This class implements {@link ISelectionProvider} so that it can delegate
 * the selection provider from the {@link LayoutCanvasViewer}.
 * <p/>
 * Note that {@link LayoutCanvasViewer} sets a selection change listener on this
 * manager so that it can invoke its own fireSelectionChanged when the canvas'
 * selection changes.
 */
public class SelectionManager implements ISelectionProvider {

    private LayoutCanvas mCanvas;

    /** The current selection list. The list is never null, however it can be empty. */
    private final LinkedList<SelectionItem> mSelections = new LinkedList<SelectionItem>();

    /** An unmodifiable view of {@link #mSelections}. */
    private final List<SelectionItem> mUnmodifiableSelection =
        Collections.unmodifiableList(mSelections);

    /** Barrier set when updating the selection to prevent from recursively
     * invoking ourselves. */
    private boolean mInsideUpdateSelection;

    /**
     * The <em>current</em> alternate selection, if any, which changes when the Alt key is
     * used during a selection. Can be null.
     */
    private CanvasAlternateSelection mAltSelection;

    /** List of clients listening to selection changes. */
    private final ListenerList mSelectionListeners = new ListenerList();

    /**
     * Constructs a new {@link SelectionManager} associated with the given layout canvas.
     *
     * @param layoutCanvas The layout canvas to create a {@link SelectionManager} for.
     */
    public SelectionManager(LayoutCanvas layoutCanvas) {
        mCanvas = layoutCanvas;
    }

    @Override
    public void addSelectionChangedListener(ISelectionChangedListener listener) {
        mSelectionListeners.add(listener);
    }

    @Override
    public void removeSelectionChangedListener(ISelectionChangedListener listener) {
        mSelectionListeners.remove(listener);
    }

    /**
     * Returns the native {@link SelectionItem} list.
     *
     * @return An immutable list of {@link SelectionItem}. Can be empty but not null.
     */
    @NonNull
    List<SelectionItem> getSelections() {
        return mUnmodifiableSelection;
    }

    /**
     * Return a snapshot/copy of the selection. Useful for clipboards etc where we
     * don't want the returned copy to be affected by future edits to the selection.
     *
     * @return A copy of the current selection. Never null.
     */
    @NonNull
    public List<SelectionItem> getSnapshot() {
        if (mSelectionListeners.isEmpty()) {
            return Collections.emptyList();
        }

        return new ArrayList<SelectionItem>(mSelections);
    }

    /**
     * Returns a {@link TreeSelection} where each {@link TreePath} item is
     * actually a {@link CanvasViewInfo}.
     */
    @Override
    public ISelection getSelection() {
        if (mSelections.isEmpty()) {
            return TreeSelection.EMPTY;
        }

        ArrayList<TreePath> paths = new ArrayList<TreePath>();

        for (SelectionItem cs : mSelections) {
            CanvasViewInfo vi = cs.getViewInfo();
            if (vi != null) {
                paths.add(getTreePath(vi));
            }
        }

        return new TreeSelection(paths.toArray(new TreePath[paths.size()]));
    }

    /**
     * Create a {@link TreePath} from the given view info
     *
     * @param viewInfo the view info to look up a tree path for
     * @return a {@link TreePath} for the given view info
     */
    public static TreePath getTreePath(CanvasViewInfo viewInfo) {
        ArrayList<Object> segments = new ArrayList<Object>();
        while (viewInfo != null) {
            segments.add(0, viewInfo);
            viewInfo = viewInfo.getParent();
        }

        return new TreePath(segments.toArray());
    }

    /**
     * Sets the selection. It must be an {@link ITreeSelection} where each segment
     * of the tree path is a {@link CanvasViewInfo}. A null selection is considered
     * as an empty selection.
     * <p/>
     * This method is invoked by {@link LayoutCanvasViewer#setSelection(ISelection)}
     * in response to an <em>outside</em> selection (compatible with ours) that has
     * changed. Typically it means the outline selection has changed and we're
     * synchronizing ours to match.
     */
    @Override
    public void setSelection(ISelection selection) {
        if (mInsideUpdateSelection) {
            return;
        }

        boolean changed = false;
        try {
            mInsideUpdateSelection = true;

            if (selection == null) {
                selection = TreeSelection.EMPTY;
            }

            if (selection instanceof ITreeSelection) {
                ITreeSelection treeSel = (ITreeSelection) selection;

                if (treeSel.isEmpty()) {
                    // Clear existing selection, if any
                    if (!mSelections.isEmpty()) {
                        mSelections.clear();
                        mAltSelection = null;
                        updateActionsFromSelection();
                        redraw();
                    }
                    return;
                }

                boolean redoLayout = false;

                // Create a list of all currently selected view infos
                Set<CanvasViewInfo> oldSelected = new HashSet<CanvasViewInfo>();
                for (SelectionItem cs : mSelections) {
                    oldSelected.add(cs.getViewInfo());
                }

                // Go thru new selection and take care of selecting new items
                // or marking those which are the same as in the current selection
                for (TreePath path : treeSel.getPaths()) {
                    Object seg = path.getLastSegment();
                    if (seg instanceof CanvasViewInfo) {
                        CanvasViewInfo newVi = (CanvasViewInfo) seg;
                        if (oldSelected.contains(newVi)) {
                            // This view info is already selected. Remove it from the
                            // oldSelected list so that we don't deselect it later.
                            oldSelected.remove(newVi);
                        } else {
                            // This view info is not already selected. Select it now.

                            // reset alternate selection if any
                            mAltSelection = null;
                            // otherwise add it.
                            mSelections.add(createSelection(newVi));
                            changed = true;
                        }
                        if (newVi.isInvisible()) {
                            redoLayout = true;
                        }
                    } else {
                        // Unrelated selection (e.g. user clicked in the Project Explorer
                        // or something) -- just ignore these
                        return;
                    }
                }

                // Deselect old selected items that are not in the new one
                for (CanvasViewInfo vi : oldSelected) {
                    if (vi.isExploded()) {
                        redoLayout = true;
                    }
                    deselect(vi);
                    changed = true;
                }

                if (redoLayout) {
                    mCanvas.getEditorDelegate().recomputeLayout();
                }
            }
        } finally {
            mInsideUpdateSelection = false;
        }

        if (changed) {
            redraw();
            fireSelectionChanged();
            updateActionsFromSelection();
        }
    }

    /**
     * The menu has been activated; ensure that the menu click is over the existing
     * selection, and if not, update the selection.
     *
     * @param e the {@link MenuDetectEvent} which triggered the menu
     */
    public void menuClick(MenuDetectEvent e) {
        LayoutPoint p = ControlPoint.create(mCanvas, e).toLayout();

        // Right click button is used to display a context menu.
        // If there's an existing selection and the click is anywhere in this selection
        // and there are no modifiers being used, we don't want to change the selection.
        // Otherwise we select the item under the cursor.

        for (SelectionItem cs : mSelections) {
            if (cs.isRoot()) {
                continue;
            }
            if (cs.getRect().contains(p.x, p.y)) {
                // The cursor is inside the selection. Don't change anything.
                return;
            }
        }

        CanvasViewInfo vi = mCanvas.getViewHierarchy().findViewInfoAt(p);
        selectSingle(vi);
    }

    /**
     * Performs selection for a mouse event.
     * <p/>
     * Shift key (or Command on the Mac) is used to toggle in multi-selection.
     * Alt key is used to cycle selection through objects at the same level than
     * the one pointed at (i.e. click on an object then alt-click to cycle).
     *
     * @param e The mouse event which triggered the selection. Cannot be null.
     *            The modifier key mask will be used to determine whether this
     *            is a plain select or a toggle, etc.
     */
    public void select(MouseEvent e) {
        boolean isMultiClick = (e.stateMask & SWT.SHIFT) != 0 ||
            // On Mac, the Command key is the normal toggle accelerator
            ((SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN) &&
                    (e.stateMask & SWT.COMMAND) != 0);
        boolean isCycleClick   = (e.stateMask & SWT.ALT)   != 0;

        LayoutPoint p = ControlPoint.create(mCanvas, e).toLayout();

        if (e.button == 3) {
            // Right click button is used to display a context menu.
            // If there's an existing selection and the click is anywhere in this selection
            // and there are no modifiers being used, we don't want to change the selection.
            // Otherwise we select the item under the cursor.

            if (!isCycleClick && !isMultiClick) {
                for (SelectionItem cs : mSelections) {
                    if (cs.getRect().contains(p.x, p.y)) {
                        // The cursor is inside the selection. Don't change anything.
                        return;
                    }
                }
            }

        } else if (e.button != 1) {
            // Click was done with something else than the left button for normal selection
            // or the right button for context menu.
            // We don't use mouse button 2 yet (middle mouse, or scroll wheel?) for
            // anything, so let's not change the selection.
            return;
        }

        CanvasViewInfo vi = mCanvas.getViewHierarchy().findViewInfoAt(p);

        if (vi != null && vi.isHidden()) {
            vi = vi.getParent();
        }

        if (isMultiClick && !isCycleClick) {
            // Case where shift is pressed: pointed object is toggled.

            // reset alternate selection if any
            mAltSelection = null;

            // If nothing has been found at the cursor, assume it might be a user error
            // and avoid clearing the existing selection.

            if (vi != null) {
                // toggle this selection on-off: remove it if already selected
                if (deselect(vi)) {
                    if (vi.isExploded()) {
                        mCanvas.getEditorDelegate().recomputeLayout();
                    }

                    redraw();
                    return;
                }

                // otherwise add it.
                mSelections.add(createSelection(vi));
                fireSelectionChanged();
                redraw();
            }

        } else if (isCycleClick) {
            // Case where alt is pressed: select or cycle the object pointed at.

            // Note: if shift and alt are pressed, shift is ignored. The alternate selection
            // mechanism does not reset the current multiple selection unless they intersect.

            // We need to remember the "origin" of the alternate selection, to be
            // able to continue cycling through it later. If there's no alternate selection,
            // create one. If there's one but not for the same origin object, create a new
            // one too.
            if (mAltSelection == null || mAltSelection.getOriginatingView() != vi) {
                mAltSelection = new CanvasAlternateSelection(
                        vi, mCanvas.getViewHierarchy().findAltViewInfoAt(p));

                // deselect them all, in case they were partially selected
                deselectAll(mAltSelection.getAltViews());

                // select the current one
                CanvasViewInfo vi2 = mAltSelection.getCurrent();
                if (vi2 != null) {
                    mSelections.addFirst(createSelection(vi2));
                    fireSelectionChanged();
                }
            } else {
                // We're trying to cycle through the current alternate selection.
                // First remove the current object.
                CanvasViewInfo vi2 = mAltSelection.getCurrent();
                deselect(vi2);

                // Now select the next one.
                vi2 = mAltSelection.getNext();
                if (vi2 != null) {
                    mSelections.addFirst(createSelection(vi2));
                    fireSelectionChanged();
                }
            }
            redraw();

        } else {
            // Case where no modifier is pressed: either select or reset the selection.
            selectSingle(vi);
        }
    }

    /**
     * Removes all the currently selected item and only select the given item.
     * Issues a redraw() if the selection changes.
     *
     * @param vi The new selected item if non-null. Selection becomes empty if null.
     * @return the item selected, or null if the selection was cleared (e.g. vi was null)
     */
    @Nullable
    SelectionItem selectSingle(CanvasViewInfo vi) {
        SelectionItem item = null;

        // reset alternate selection if any
        mAltSelection = null;

        if (vi == null) {
            // The user clicked outside the bounds of the root element; in that case, just
            // select the root element.
            vi = mCanvas.getViewHierarchy().getRoot();
        }

        boolean redoLayout = hasExplodedItems();

        // reset (multi)selection if any
        if (!mSelections.isEmpty()) {
            if (mSelections.size() == 1 && mSelections.getFirst().getViewInfo() == vi) {
                // CanvasSelection remains the same, don't touch it.
                return mSelections.getFirst();
            }
            mSelections.clear();
        }

        if (vi != null) {
            item = createSelection(vi);
            mSelections.add(item);
            if (vi.isInvisible()) {
                redoLayout = true;
            }
        }
        fireSelectionChanged();

        if (redoLayout) {
            mCanvas.getEditorDelegate().recomputeLayout();
        }

        redraw();

        return item;
    }

    /** Returns true if the view hierarchy is showing exploded items. */
    private boolean hasExplodedItems() {
        for (SelectionItem item : mSelections) {
            if (item.getViewInfo().isExploded()) {
                return true;
            }
        }

        return false;
    }

    /**
     * Selects the given set of {@link CanvasViewInfo}s. This is similar to
     * {@link #selectSingle} but allows you to make a multi-selection. Issues a
     * {@link #redraw()}.
     *
     * @param viewInfos A collection of {@link CanvasViewInfo} objects to be
     *            selected, or null or empty to clear the selection.
     */
    /* package */ void selectMultiple(Collection<CanvasViewInfo> viewInfos) {
        // reset alternate selection if any
        mAltSelection = null;

        boolean redoLayout = hasExplodedItems();

        mSelections.clear();
        if (viewInfos != null) {
            for (CanvasViewInfo viewInfo : viewInfos) {
                mSelections.add(createSelection(viewInfo));
                if (viewInfo.isInvisible()) {
                    redoLayout = true;
                }
            }
        }

        fireSelectionChanged();

        if (redoLayout) {
            mCanvas.getEditorDelegate().recomputeLayout();
        }

        redraw();
    }

    public void select(Collection<INode> nodes) {
        List<CanvasViewInfo> infos = new ArrayList<CanvasViewInfo>(nodes.size());
        for (INode node : nodes) {
            CanvasViewInfo info = mCanvas.getViewHierarchy().findViewInfoFor(node);
            if (info != null) {
                infos.add(info);
            }
        }
        selectMultiple(infos);
    }

    /**
     * Selects the visual element corresponding to the given XML node
     * @param xmlNode The Node whose element we want to select.
     */
    /* package */ void select(Node xmlNode) {
        if (xmlNode == null) {
            return;
        } else if (xmlNode.getNodeType() == Node.TEXT_NODE) {
            xmlNode = xmlNode.getParentNode();
        }

        CanvasViewInfo vi = mCanvas.getViewHierarchy().findViewInfoFor(xmlNode);
        if (vi != null && !vi.isRoot()) {
            selectSingle(vi);
        }
    }

    /**
     * Selects any views that overlap the given selection rectangle.
     *
     * @param topLeft The top left corner defining the selection rectangle.
     * @param bottomRight The bottom right corner defining the selection
     *            rectangle.
     * @param toggled A set of {@link CanvasViewInfo}s that should be toggled
     *            rather than just added.
     */
    public void selectWithin(LayoutPoint topLeft, LayoutPoint bottomRight,
            Collection<CanvasViewInfo> toggled) {
        // reset alternate selection if any
        mAltSelection = null;

        ViewHierarchy viewHierarchy = mCanvas.getViewHierarchy();
        Collection<CanvasViewInfo> viewInfos = viewHierarchy.findWithin(topLeft, bottomRight);

        if (toggled.size() > 0) {
            // Copy; we're not allowed to touch the passed in collection
            Set<CanvasViewInfo> result = new HashSet<CanvasViewInfo>(toggled);
            for (CanvasViewInfo viewInfo : viewInfos) {
                if (toggled.contains(viewInfo)) {
                    result.remove(viewInfo);
                } else {
                    result.add(viewInfo);
                }
            }
            viewInfos = result;
        }

        mSelections.clear();
        for (CanvasViewInfo viewInfo : viewInfos) {
            if (viewInfo.isHidden()) {
                continue;
            }
            mSelections.add(createSelection(viewInfo));
        }

        fireSelectionChanged();
        redraw();
    }

    /**
     * Clears the selection and then selects everything (all views and all their
     * children).
     */
    public void selectAll() {
        // First clear the current selection, if any.
        mSelections.clear();
        mAltSelection = null;

        // Now select everything if there's a valid layout
        for (CanvasViewInfo vi : mCanvas.getViewHierarchy().findAllViewInfos(false)) {
            mSelections.add(createSelection(vi));
        }

        fireSelectionChanged();
        redraw();
    }

    /** Clears the selection */
    public void selectNone() {
        mSelections.clear();
        mAltSelection = null;
        fireSelectionChanged();
        redraw();
    }

    /** Selects the parent of the current selection */
    public void selectParent() {
        if (mSelections.size() == 1) {
            CanvasViewInfo parent = mSelections.get(0).getViewInfo().getParent();
            if (parent != null) {
                selectSingle(parent);
            }
        }
    }

    /** Finds all widgets in the layout that have the same type as the primary */
    public void selectSameType() {
        // Find all
        if (mSelections.size() == 1) {
            CanvasViewInfo viewInfo = mSelections.get(0).getViewInfo();
            ElementDescriptor descriptor = viewInfo.getUiViewNode().getDescriptor();
            mSelections.clear();
            mAltSelection = null;
            addSameType(mCanvas.getViewHierarchy().getRoot(), descriptor);
            fireSelectionChanged();
            redraw();
        }
    }

    /** Helper for {@link #selectSameType} */
    private void addSameType(CanvasViewInfo root, ElementDescriptor descriptor) {
        if (root.getUiViewNode().getDescriptor() == descriptor) {
            mSelections.add(createSelection(root));
        }

        for (CanvasViewInfo child : root.getChildren()) {
            addSameType(child, descriptor);
        }
    }

    /** Selects the siblings of the primary */
    public void selectSiblings() {
        // Find all
        if (mSelections.size() == 1) {
            CanvasViewInfo vi = mSelections.get(0).getViewInfo();
            mSelections.clear();
            mAltSelection = null;
            CanvasViewInfo parent = vi.getParent();
            if (parent == null) {
                selectNone();
            } else {
                for (CanvasViewInfo child : parent.getChildren()) {
                    mSelections.add(createSelection(child));
                }
                fireSelectionChanged();
                redraw();
            }
        }
    }

    /**
     * Returns true if and only if there is currently more than one selected
     * item.
     *
     * @return True if more than one item is selected
     */
    public boolean hasMultiSelection() {
        return mSelections.size() > 1;
    }

    /**
     * Deselects a view info. Returns true if the object was actually selected.
     * Callers are responsible for calling redraw() and updateOulineSelection()
     * after.
     * @param canvasViewInfo The item to deselect.
     * @return  True if the object was successfully removed from the selection.
     */
    public boolean deselect(CanvasViewInfo canvasViewInfo) {
        if (canvasViewInfo == null) {
            return false;
        }

        for (ListIterator<SelectionItem> it = mSelections.listIterator(); it.hasNext(); ) {
            SelectionItem s = it.next();
            if (canvasViewInfo == s.getViewInfo()) {
                it.remove();
                return true;
            }
        }

        return false;
    }

    /**
     * Deselects multiple view infos.
     * Callers are responsible for calling redraw() and updateOulineSelection() after.
     */
    private void deselectAll(List<CanvasViewInfo> canvasViewInfos) {
        for (ListIterator<SelectionItem> it = mSelections.listIterator(); it.hasNext(); ) {
            SelectionItem s = it.next();
            if (canvasViewInfos.contains(s.getViewInfo())) {
                it.remove();
            }
        }
    }

    /** Sync the selection with an updated view info tree */
    void sync() {
        // Check if the selection is still the same (based on the object keys)
        // and eventually recompute their bounds.
        for (ListIterator<SelectionItem> it = mSelections.listIterator(); it.hasNext(); ) {
            SelectionItem s = it.next();

            // Check if the selected object still exists
            ViewHierarchy viewHierarchy = mCanvas.getViewHierarchy();
            UiViewElementNode key = s.getViewInfo().getUiViewNode();
            CanvasViewInfo vi = viewHierarchy.findViewInfoFor(key);

            // Remove the previous selection -- if the selected object still exists
            // we need to recompute its bounds in case it moved so we'll insert a new one
            // at the same place.
            it.remove();
            if (vi == null) {
                vi = findCorresponding(s.getViewInfo(), viewHierarchy.getRoot());
            }
            if (vi != null) {
                it.add(createSelection(vi));
            }
        }
        fireSelectionChanged();

        // remove the current alternate selection views
        mAltSelection = null;
    }

    /** Finds the corresponding {@link CanvasViewInfo} in the new hierarchy */
    private CanvasViewInfo findCorresponding(CanvasViewInfo old, CanvasViewInfo newRoot) {
        CanvasViewInfo oldParent = old.getParent();
        if (oldParent != null) {
            CanvasViewInfo newParent = findCorresponding(oldParent, newRoot);
            if (newParent == null) {
                return null;
            }

            List<CanvasViewInfo> oldSiblings = oldParent.getChildren();
            List<CanvasViewInfo> newSiblings = newParent.getChildren();
            Iterator<CanvasViewInfo> oldIterator = oldSiblings.iterator();
            Iterator<CanvasViewInfo> newIterator = newSiblings.iterator();
            while (oldIterator.hasNext() && newIterator.hasNext()) {
                CanvasViewInfo oldSibling = oldIterator.next();
                CanvasViewInfo newSibling = newIterator.next();

                if (oldSibling.getName().equals(newSibling.getName())) {
                    // Structure has changed: can't do a proper search
                    return null;
                }

                if (oldSibling == old) {
                    return newSibling;
                }
            }
        } else {
            return newRoot;
        }

        return null;
    }

    /**
     * Notifies listeners that the selection has changed.
     */
    private void fireSelectionChanged() {
        if (mInsideUpdateSelection) {
            return;
        }
        try {
            mInsideUpdateSelection = true;

            final SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());

            SafeRunnable.run(new SafeRunnable() {
                @Override
                public void run() {
                    for (Object listener : mSelectionListeners.getListeners()) {
                        ((ISelectionChangedListener) listener).selectionChanged(event);
                    }
                }
            });

            updateActionsFromSelection();
        } finally {
            mInsideUpdateSelection = false;
        }
    }

    /**
     * Updates menu actions and the layout action bar after a selection change - these are
     * actions that depend on the selection
     */
    private void updateActionsFromSelection() {
        LayoutEditorDelegate editor = mCanvas.getEditorDelegate();
        if (editor != null) {
            // Update menu actions that depend on the selection
            mCanvas.updateMenuActionState();

            // Update the layout actions bar
            LayoutActionBar layoutActionBar = editor.getGraphicalEditor().getLayoutActionBar();
            layoutActionBar.updateSelection();
        }
    }

    /**
     * Sanitizes the selection for a copy/cut or drag operation.
     * <p/>
     * Sanitizes the list to make sure all elements have a valid XML attached to it,
     * that is remove element that have no XML to avoid having to make repeated such
     * checks in various places after.
     * <p/>
     * In case of multiple selection, we also need to remove all children when their
     * parent is already selected since parents will always be added with all their
     * children.
     * <p/>
     *
     * @param selection The selection list to be sanitized <b>in-place</b>.
     *      The <code>selection</code> argument should not be {@link #mSelections} -- the
     *      given list is going to be altered and we should never alter the user-made selection.
     *      Instead the caller should provide its own copy.
     */
    /* package */ static void sanitize(List<SelectionItem> selection) {
        if (selection.isEmpty()) {
            return;
        }

        for (Iterator<SelectionItem> it = selection.iterator(); it.hasNext(); ) {
            SelectionItem cs = it.next();
            CanvasViewInfo vi = cs.getViewInfo();
            UiViewElementNode key = vi == null ? null : vi.getUiViewNode();
            Node node = key == null ? null : key.getXmlNode();
            if (node == null) {
                // Missing ViewInfo or view key or XML, discard this.
                it.remove();
                continue;
            }

            if (vi != null) {
                for (Iterator<SelectionItem> it2 = selection.iterator();
                     it2.hasNext(); ) {
                    SelectionItem cs2 = it2.next();
                    if (cs != cs2) {
                        CanvasViewInfo vi2 = cs2.getViewInfo();
                        if (vi.isParent(vi2)) {
                            // vi2 is a parent for vi. Remove vi.
                            it.remove();
                            break;
                        }
                    }
                }
            }
        }
    }

    /**
     * Selects the given list of nodes in the canvas, and returns true iff the
     * attempt to select was successful.
     *
     * @param nodes The collection of nodes to be selected
     * @param indices A list of indices within the parent for each node, or null
     * @return True if and only if all nodes were successfully selected
     */
    public boolean selectDropped(List<INode> nodes, List<Integer> indices) {
        assert indices == null || nodes.size() == indices.size();

        ViewHierarchy viewHierarchy = mCanvas.getViewHierarchy();

        // Look up a list of view infos which correspond to the nodes.
        final Collection<CanvasViewInfo> newChildren = new ArrayList<CanvasViewInfo>();
        for (int i = 0, n = nodes.size(); i < n; i++) {
            INode node = nodes.get(i);

            CanvasViewInfo viewInfo = viewHierarchy.findViewInfoFor(node);

            // There are two scenarios where looking up a view info fails.
            // The first one is that the node was just added and the render has not yet
            // happened, so the ViewHierarchy has no record of the node. In this case
            // there is nothing we can do, and the method will return false (which the
            // caller will use to schedule a second attempt later).
            // The second scenario is where the nodes *change identity*. This isn't
            // common, but when a drop handler makes a lot of changes to its children,
            // for example when dropping into a GridLayout where attributes are adjusted
            // on nearly all the other children to update row or column attributes
            // etc, then in some cases Eclipse's DOM model changes the identities of
            // the nodes when applying all the edits, so the new Node we created (as
            // well as possibly other nodes) are no longer the children we observe
            // after the edit, and there are new copies there instead. In this case
            // the UiViewModel also fails to map the nodes. To work around this,
            // we track the *indices* (within the parent) during a drop, such that we
            // know which children (according to their positions) the given nodes
            // are supposed to map to, and then we use these view infos instead.
            if (viewInfo == null && node instanceof NodeProxy && indices != null) {
                INode parent = node.getParent();
                CanvasViewInfo parentViewInfo = viewHierarchy.findViewInfoFor(parent);
                if (parentViewInfo != null) {
                    UiViewElementNode parentUiNode = parentViewInfo.getUiViewNode();
                    if (parentUiNode != null) {
                        List<UiElementNode> children = parentUiNode.getUiChildren();
                        int index = indices.get(i);
                        if (index >= 0 && index < children.size()) {
                            UiElementNode replacedNode = children.get(index);
                            viewInfo = viewHierarchy.findViewInfoFor(replacedNode);
                        }
                    }
                }
            }

            if (viewInfo != null) {
                if (nodes.size() > 1 && viewInfo.isHidden()) {
                    // Skip spacers - unless you're dropping just one
                    continue;
                }
                if (GridLayoutRule.sDebugGridLayout && (viewInfo.getName().equals(FQCN_SPACE)
                        || viewInfo.getName().equals(FQCN_SPACE_V7))) {
                    // In debug mode they might not be marked as hidden but we never never
                    // want to select these guys
                    continue;
                }
                newChildren.add(viewInfo);
            }
        }
        boolean found = nodes.size() == newChildren.size();

        if (found || newChildren.size() > 0) {
            mCanvas.getSelectionManager().selectMultiple(newChildren);
        }

        return found;
    }

    /**
     * Update the outline selection to select the given nodes, asynchronously.
     * @param nodes The nodes to be selected
     */
    public void setOutlineSelection(final List<INode> nodes) {
        Display.getDefault().asyncExec(new Runnable() {
            @Override
            public void run() {
                selectDropped(nodes, null /* indices */);
                syncOutlineSelection();
            }
        });
    }

    /**
     * Syncs the current selection to the outline, synchronously.
     */
    public void syncOutlineSelection() {
        OutlinePage outlinePage = mCanvas.getOutlinePage();
        IWorkbenchPartSite site = outlinePage.getEditor().getSite();
        ISelectionProvider selectionProvider = site.getSelectionProvider();
        ISelection selection = selectionProvider.getSelection();
        if (selection != null) {
            outlinePage.setSelection(selection);
        }
    }

    private void redraw() {
        mCanvas.redraw();
    }

    SelectionItem createSelection(CanvasViewInfo vi) {
        return new SelectionItem(mCanvas, vi);
    }

    /**
     * Returns true if there is nothing selected
     *
     * @return true if there is nothing selected
     */
    public boolean isEmpty() {
        return mSelections.size() == 0;
    }

    /**
     * "Select" context menu which lists various menu options related to selection:
     * <ul>
     * <li> Select All
     * <li> Select Parent
     * <li> Select None
     * <li> Select Siblings
     * <li> Select Same Type
     * </ul>
     * etc.
     */
    public static class SelectionMenu extends SubmenuAction {
        private final GraphicalEditorPart mEditor;

        public SelectionMenu(GraphicalEditorPart editor) {
            super("Select");
            mEditor = editor;
        }

        @Override
        public String getId() {
            return "-selectionmenu"; //$NON-NLS-1$
        }

        @Override
        protected void addMenuItems(Menu menu) {
            LayoutCanvas canvas = mEditor.getCanvasControl();
            SelectionManager selectionManager = canvas.getSelectionManager();
            List<SelectionItem> selections = selectionManager.getSelections();
            boolean selectedOne = selections.size() == 1;
            boolean notRoot = selectedOne && !selections.get(0).isRoot();
            boolean haveSelection = selections.size() > 0;

            Action a;
            a = selectionManager.new SelectAction("Select Parent\tEsc", SELECT_PARENT);
            new ActionContributionItem(a).fill(menu, -1);
            a.setEnabled(notRoot);
            a.setAccelerator(SWT.ESC);

            a = selectionManager.new SelectAction("Select Siblings", SELECT_SIBLINGS);
            new ActionContributionItem(a).fill(menu, -1);
            a.setEnabled(notRoot);

            a = selectionManager.new SelectAction("Select Same Type", SELECT_SAME_TYPE);
            new ActionContributionItem(a).fill(menu, -1);
            a.setEnabled(selectedOne);

            new Separator().fill(menu, -1);

            // Special case for Select All: Use global action
            a = canvas.getSelectAllAction();
            new ActionContributionItem(a).fill(menu, -1);
            a.setEnabled(true);

            a = selectionManager.new SelectAction("Deselect All", SELECT_NONE);
            new ActionContributionItem(a).fill(menu, -1);
            a.setEnabled(haveSelection);
        }
    }

    private static final int SELECT_PARENT = 1;
    private static final int SELECT_SIBLINGS = 2;
    private static final int SELECT_SAME_TYPE = 3;
    private static final int SELECT_NONE = 4; // SELECT_ALL is handled separately

    private class SelectAction extends Action {
        private final int mType;

        public SelectAction(String title, int type) {
            super(title, IAction.AS_PUSH_BUTTON);
            mType = type;
        }

        @Override
        public void run() {
            switch (mType) {
                case SELECT_NONE:
                    selectNone();
                    break;
                case SELECT_PARENT:
                    selectParent();
                    break;
                case SELECT_SAME_TYPE:
                    selectSameType();
                    break;
                case SELECT_SIBLINGS:
                    selectSiblings();
                    break;
            }

            List<INode> nodes = new ArrayList<INode>();
            for (SelectionItem item : getSelections()) {
                nodes.add(item.getNode());
            }
            setOutlineSelection(nodes);
        }
    }

    public Pair<SelectionItem, SelectionHandle> findHandle(ControlPoint controlPoint) {
        if (!isEmpty()) {
            LayoutPoint layoutPoint = controlPoint.toLayout();
            int distance = (int) ((PIXEL_MARGIN + PIXEL_RADIUS) / mCanvas.getScale());

            for (SelectionItem item : getSelections()) {
                SelectionHandles handles = item.getSelectionHandles();
                // See if it's over the selection handles
                SelectionHandle handle = handles.findHandle(layoutPoint, distance);
                if (handle != null) {
                    return Pair.of(item, handle);
                }
            }

        }
        return null;
    }

    /** Performs the default action provided by the currently selected view */
    public void performDefaultAction() {
        final List<SelectionItem> selections = getSelections();
        if (selections.size() > 0) {
            NodeProxy primary = selections.get(0).getNode();
            if (primary != null) {
                RulesEngine rulesEngine = mCanvas.getRulesEngine();
                final String id = rulesEngine.callGetDefaultActionId(primary);
                if (id == null) {
                    return;
                }
                final List<RuleAction> actions = rulesEngine.callGetContextMenu(primary);
                if (actions == null) {
                    return;
                }
                RuleAction matching = null;
                for (RuleAction a : actions) {
                    if (id.equals(a.getId())) {
                        matching = a;
                        break;
                    }
                }
                if (matching == null) {
                    return;
                }
                final List<INode> selectedNodes = new ArrayList<INode>();
                for (SelectionItem item : selections) {
                    NodeProxy n = item.getNode();
                    if (n != null) {
                        selectedNodes.add(n);
                    }
                }
                final RuleAction action = matching;
                mCanvas.getEditorDelegate().getEditor().wrapUndoEditXmlModel(action.getTitle(),
                    new Runnable() {
                        @Override
                        public void run() {
                            action.getCallback().action(action, selectedNodes,
                                    action.getId(), null);
                            LayoutCanvas canvas = mCanvas;
                            CanvasViewInfo root = canvas.getViewHierarchy().getRoot();
                            if (root != null) {
                                UiViewElementNode uiViewNode = root.getUiViewNode();
                                NodeFactory nodeFactory = canvas.getNodeFactory();
                                NodeProxy rootNode = nodeFactory.create(uiViewNode);
                                if (rootNode != null) {
                                    rootNode.applyPendingChanges();
                                }
                            }
                        }
                });
            }
        }
    }

    /** Performs renaming the selected views */
    public void performRename() {
        final List<SelectionItem> selections = getSelections();
        if (selections.size() > 0) {
            NodeProxy primary = selections.get(0).getNode();
            if (primary != null) {
                performRename(primary, selections);
            }
        }
    }

    /**
     * Performs renaming the given node.
     *
     * @param primary the node to be renamed, or the primary node (to get the
     *            current value from if more than one node should be renamed)
     * @param selections if not null, a list of nodes to apply the setting to
     *            (which should include the primary)
     * @return the result of the renaming operation
     */
    @NonNull
    public RenameResult performRename(
            final @NonNull INode primary,
            final @Nullable List<SelectionItem> selections) {
        String id = primary.getStringAttr(ANDROID_URI, ATTR_ID);
        if (id != null && !id.isEmpty()) {
            RenameResult result = RenameResourceWizard.renameResource(
                    mCanvas.getShell(),
                    mCanvas.getEditorDelegate().getGraphicalEditor().getProject(),
                    ResourceType.ID, BaseViewRule.stripIdPrefix(id), null, true /*canClear*/);
            if (result.isCanceled()) {
                return result;
            } else if (!result.isUnavailable()) {
                return result;
            }
        }
        String currentId = primary.getStringAttr(ANDROID_URI, ATTR_ID);
        currentId = BaseViewRule.stripIdPrefix(currentId);
        InputDialog d = new InputDialog(
                    AdtPlugin.getDisplay().getActiveShell(),
                    "Set ID",
                    "New ID:",
                    currentId,
                    ResourceNameValidator.create(false, (IProject) null, ResourceType.ID));
        if (d.open() == Window.OK) {
            final String s = d.getValue();
            mCanvas.getEditorDelegate().getEditor().wrapUndoEditXmlModel("Set ID",
                    new Runnable() {
                @Override
                public void run() {
                    String newId = s;
                    newId = NEW_ID_PREFIX + BaseViewRule.stripIdPrefix(s);
                    if (selections != null) {
                        for (SelectionItem item : selections) {
                            NodeProxy node = item.getNode();
                            if (node != null) {
                                node.setAttribute(ANDROID_URI, ATTR_ID, newId);
                            }
                        }
                    } else {
                        primary.setAttribute(ANDROID_URI, ATTR_ID, newId);
                    }

                    LayoutCanvas canvas = mCanvas;
                    CanvasViewInfo root = canvas.getViewHierarchy().getRoot();
                    if (root != null) {
                        UiViewElementNode uiViewNode = root.getUiViewNode();
                        NodeFactory nodeFactory = canvas.getNodeFactory();
                        NodeProxy rootNode = nodeFactory.create(uiViewNode);
                        if (rootNode != null) {
                            rootNode.applyPendingChanges();
                        }
                    }
                }
            });
            return RenameResult.name(BaseViewRule.stripIdPrefix(s));
        } else {
            return RenameResult.canceled();
        }
    }
}
