/*
 * Copyright (C) 2011 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.refactoring;

import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_BACKGROUND;
import static com.android.SdkConstants.ATTR_BASELINE_ALIGNED;
import static com.android.SdkConstants.ATTR_LAYOUT_ABOVE;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_BASELINE;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_BOTTOM;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_LEFT;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_PARENT_BOTTOM;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_PARENT_LEFT;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_PARENT_RIGHT;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_PARENT_TOP;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_RIGHT;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_TOP;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_WITH_PARENT_MISSING;
import static com.android.SdkConstants.ATTR_LAYOUT_BELOW;
import static com.android.SdkConstants.ATTR_LAYOUT_CENTER_HORIZONTAL;
import static com.android.SdkConstants.ATTR_LAYOUT_CENTER_VERTICAL;
import static com.android.SdkConstants.ATTR_LAYOUT_HEIGHT;
import static com.android.SdkConstants.ATTR_LAYOUT_MARGIN_LEFT;
import static com.android.SdkConstants.ATTR_LAYOUT_MARGIN_TOP;
import static com.android.SdkConstants.ATTR_LAYOUT_RESOURCE_PREFIX;
import static com.android.SdkConstants.ATTR_LAYOUT_TO_LEFT_OF;
import static com.android.SdkConstants.ATTR_LAYOUT_TO_RIGHT_OF;
import static com.android.SdkConstants.ATTR_LAYOUT_WEIGHT;
import static com.android.SdkConstants.ATTR_LAYOUT_WIDTH;
import static com.android.SdkConstants.ATTR_ORIENTATION;
import static com.android.SdkConstants.ID_PREFIX;
import static com.android.SdkConstants.LINEAR_LAYOUT;
import static com.android.SdkConstants.NEW_ID_PREFIX;
import static com.android.SdkConstants.RELATIVE_LAYOUT;
import static com.android.SdkConstants.VALUE_FALSE;
import static com.android.SdkConstants.VALUE_N_DP;
import static com.android.SdkConstants.VALUE_TRUE;
import static com.android.SdkConstants.VALUE_VERTICAL;
import static com.android.SdkConstants.VALUE_WRAP_CONTENT;
import static com.android.ide.common.layout.GravityHelper.GRAVITY_BOTTOM;
import static com.android.ide.common.layout.GravityHelper.GRAVITY_CENTER_HORIZ;
import static com.android.ide.common.layout.GravityHelper.GRAVITY_CENTER_VERT;
import static com.android.ide.common.layout.GravityHelper.GRAVITY_FILL_HORIZ;
import static com.android.ide.common.layout.GravityHelper.GRAVITY_FILL_VERT;
import static com.android.ide.common.layout.GravityHelper.GRAVITY_LEFT;
import static com.android.ide.common.layout.GravityHelper.GRAVITY_RIGHT;
import static com.android.ide.common.layout.GravityHelper.GRAVITY_TOP;
import static com.android.ide.common.layout.GravityHelper.GRAVITY_VERT_MASK;

import com.android.ide.common.layout.GravityHelper;
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.gle2.CanvasViewInfo;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.utils.Pair;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.text.edits.MultiTextEdit;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Helper class which performs the bulk of the layout conversion to relative layout
 * <p>
 * Future enhancements:
 * <ul>
 * <li>Render the layout at multiple screen sizes and analyze how the widgets move and
 * stretch and use that to add in additional constraints
 * <li> Adapt the LinearLayout analysis code to work with TableLayouts and TableRows as well
 * (just need to tweak the "isVertical" interpretation to account for the different defaults,
 * and perhaps do something about column size properties.
 * <li> We need to take into account existing margins and clear/update them
 * </ul>
 */
class RelativeLayoutConversionHelper {
    private final MultiTextEdit mRootEdit;
    private final boolean mFlatten;
    private final Element mLayout;
    private final ChangeLayoutRefactoring mRefactoring;
    private final CanvasViewInfo mRootView;
    private List<Element> mDeletedElements;

    RelativeLayoutConversionHelper(ChangeLayoutRefactoring refactoring,
            Element layout, boolean flatten, MultiTextEdit rootEdit, CanvasViewInfo rootView) {
        mRefactoring = refactoring;
        mLayout = layout;
        mFlatten = flatten;
        mRootEdit = rootEdit;
        mRootView = rootView;
    }

    /** Performs conversion from any layout to a RelativeLayout */
    public void convertToRelative() {
        if (mRootView == null) {
            return;
        }

        // Locate the view for the layout
        CanvasViewInfo layoutView = findViewForElement(mRootView, mLayout);
        if (layoutView == null || layoutView.getChildren().size() == 0) {
            // No children. THAT was an easy conversion!
            return;
        }

        // Study the layout and get information about how to place individual elements
        List<View> views = analyzeLayout(layoutView);

        // Create/update relative layout constraints
        createAttachments(views);
    }

    /** Returns the elements that were deleted, or null */
    List<Element> getDeletedElements() {
        return mDeletedElements;
    }

    /**
     * Analyzes the given view hierarchy and produces a list of {@link View} objects which
     * contain placement information for each element
     */
    private List<View> analyzeLayout(CanvasViewInfo layoutView) {
        EdgeList edgeList = new EdgeList(layoutView);
        mDeletedElements = edgeList.getDeletedElements();
        deleteRemovedElements(mDeletedElements);

        List<Integer> columnOffsets = edgeList.getColumnOffsets();
        List<Integer> rowOffsets = edgeList.getRowOffsets();

        // Compute x/y offsets for each row/column index
        int[] left = new int[columnOffsets.size()];
        int[] top = new int[rowOffsets.size()];

        Map<Integer, Integer> xToCol = new HashMap<Integer, Integer>();
        int columnIndex = 0;
        for (Integer offset : columnOffsets) {
            left[columnIndex] = offset;
            xToCol.put(offset, columnIndex++);
        }
        Map<Integer, Integer> yToRow = new HashMap<Integer, Integer>();
        int rowIndex = 0;
        for (Integer offset : rowOffsets) {
            top[rowIndex] = offset;
            yToRow.put(offset, rowIndex++);
        }

        // Create a complete list of view objects
        List<View> views = createViews(edgeList, columnOffsets);
        initializeSpans(edgeList, columnOffsets, rowOffsets, xToCol, yToRow);

        // Sanity check
        for (View view : views) {
            assert view.getLeftEdge() == left[view.mCol];
            assert view.getTopEdge() == top[view.mRow];
            assert view.getRightEdge() == left[view.mCol+view.mColSpan];
            assert view.getBottomEdge() == top[view.mRow+view.mRowSpan];
        }

        // Ensure that every view has a proper id such that it can be referred to
        // with a constraint
        initializeIds(edgeList, views);

        // Attempt to lay the views out in a grid with constraints (though not that widgets
        // can overlap as well)
        Grid grid = new Grid(views, left, top);
        computeKnownConstraints(views, edgeList);
        computeHorizontalConstraints(grid);
        computeVerticalConstraints(grid);

        return views;
    }

    /** Produces a list of {@link View} objects from an {@link EdgeList} */
    private List<View> createViews(EdgeList edgeList, List<Integer> columnOffsets) {
        List<View> views = new ArrayList<View>();
        for (Integer offset : columnOffsets) {
            List<View> leftEdgeViews = edgeList.getLeftEdgeViews(offset);
            if (leftEdgeViews == null) {
                // must have been a right edge
                continue;
            }
            for (View view : leftEdgeViews) {
                views.add(view);
            }
        }
        return views;
    }

    /** Removes any elements targeted for deletion */
    private void deleteRemovedElements(List<Element> delete) {
        if (mFlatten && delete.size() > 0) {
            for (Element element : delete) {
                mRefactoring.removeElementTags(mRootEdit, element, delete,
                        !AdtPrefs.getPrefs().getFormatGuiXml() /*changeIndentation*/);
            }
        }
    }

    /** Ensures that every element has an id such that it can be referenced from a constraint */
    private void initializeIds(EdgeList edgeList, List<View> views) {
        // Ensure that all views have a valid id
        for (View view : views) {
            String id = mRefactoring.ensureHasId(mRootEdit, view.mElement, null);
            edgeList.setIdAttributeValue(view, id);
        }
    }

    /**
     * Initializes the column and row indices, as well as any column span and row span
     * values
     */
    private void initializeSpans(EdgeList edgeList, List<Integer> columnOffsets,
            List<Integer> rowOffsets, Map<Integer, Integer> xToCol, Map<Integer, Integer> yToRow) {
        // Now initialize table view row, column and spans
        for (Integer offset : columnOffsets) {
            List<View> leftEdgeViews = edgeList.getLeftEdgeViews(offset);
            if (leftEdgeViews == null) {
                // must have been a right edge
                continue;
            }
            for (View view : leftEdgeViews) {
                Integer col = xToCol.get(view.getLeftEdge());
                assert col != null;
                Integer end = xToCol.get(view.getRightEdge());
                assert end != null;

                view.mCol = col;
                view.mColSpan = end - col;
            }
        }

        for (Integer offset : rowOffsets) {
            List<View> topEdgeViews = edgeList.getTopEdgeViews(offset);
            if (topEdgeViews == null) {
                // must have been a bottom edge
                continue;
            }
            for (View view : topEdgeViews) {
                Integer row = yToRow.get(view.getTopEdge());
                assert row != null;
                Integer end = yToRow.get(view.getBottomEdge());
                assert end != null;

                view.mRow = row;
                view.mRowSpan = end - row;
            }
        }
    }

    /**
     * Creates refactoring edits which adds or updates constraints for the given list of
     * views
     */
    private void createAttachments(List<View> views) {
        // Make the attachments
        String namespace = mRefactoring.getAndroidNamespacePrefix();
        for (View view : views) {
            for (Pair<String, String> constraint : view.getHorizConstraints()) {
                mRefactoring.setAttribute(mRootEdit, view.mElement, ANDROID_URI,
                        namespace, constraint.getFirst(), constraint.getSecond());
            }
            for (Pair<String, String> constraint : view.getVerticalConstraints()) {
                mRefactoring.setAttribute(mRootEdit, view.mElement, ANDROID_URI,
                        namespace, constraint.getFirst(), constraint.getSecond());
            }
        }
    }

    /**
     * Analyzes the existing layouts and layout parameter objects in the document to infer
     * constraints for layout types that we know about - such as LinearLayout baseline
     * alignment, weights, gravity, etc.
     */
    private void computeKnownConstraints(List<View> views, EdgeList edgeList) {
        // List of parent layout elements we've already processed. We iterate through all
        // the -children-, and we ask each for its element parent (which won't have a view)
        // and we look at the parent's layout attributes and its children layout constraints,
        // and then we stash away constraints that we can infer. This means that we will
        // encounter the same parent for every sibling, so that's why there's a map to
        // prevent duplicate work.
        Set<Node> seen = new HashSet<Node>();

        for (View view : views) {
            Element element = view.getElement();
            Node parent = element.getParentNode();
            if (seen.contains(parent)) {
                continue;
            }
            seen.add(parent);

            if (parent.getNodeType() != Node.ELEMENT_NODE) {
                continue;
            }
            Element layout = (Element) parent;
            String layoutName = layout.getTagName();

            if (LINEAR_LAYOUT.equals(layoutName)) {
                analyzeLinearLayout(edgeList, layout);
            } else if (RELATIVE_LAYOUT.equals(layoutName)) {
                analyzeRelativeLayout(edgeList, layout);
            } else {
                // Some other layout -- add more conditional handling here
                // for framelayout, tables, etc.
            }
        }
    }

    /**
     * Returns the layout weight of of the given child of a LinearLayout, or 0.0 if it
     * does not define a weight
     */
    private float getWeight(Element linearLayoutChild) {
        String weight = linearLayoutChild.getAttributeNS(ANDROID_URI, ATTR_LAYOUT_WEIGHT);
        if (weight != null && weight.length() > 0) {
            try {
                return Float.parseFloat(weight);
            } catch (NumberFormatException nfe) {
                AdtPlugin.log(nfe, "Invalid weight %1$s", weight);
            }
        }

        return 0.0f;
    }

    /**
     * Returns the sum of all the layout weights of the children in the given LinearLayout
     *
     * @param linearLayout the layout to compute the total sum for
     * @return the total sum of all the layout weights in the given layout
     */
    private float getWeightSum(Element linearLayout) {
        float sum = 0;
        for (Element child : DomUtilities.getChildren(linearLayout)) {
            sum += getWeight(child);
        }

        return sum;
    }

    /**
     * Analyzes the given LinearLayout and updates the constraints to reflect
     * relationships it can infer - based on baseline alignment, gravity, order and
     * weights. This method also removes "0dip" as a special width/height used in
     * LinearLayouts with weight distribution.
     */
    private void analyzeLinearLayout(EdgeList edgeList, Element layout) {
        boolean isVertical = VALUE_VERTICAL.equals(layout.getAttributeNS(ANDROID_URI,
                ATTR_ORIENTATION));
        View baselineRef = null;
        if (!isVertical &&
            !VALUE_FALSE.equals(layout.getAttributeNS(ANDROID_URI, ATTR_BASELINE_ALIGNED))) {
            // Baseline alignment. Find the tallest child and set it as the baseline reference.
            int tallestHeight = 0;
            View tallest = null;
            for (Element child : DomUtilities.getChildren(layout)) {
                View view = edgeList.getView(child);
                if (view != null && view.getHeight() > tallestHeight) {
                    tallestHeight = view.getHeight();
                    tallest = view;
                }
            }
            if (tallest != null) {
                baselineRef = tallest;
            }
        }

        float weightSum = getWeightSum(layout);
        float cumulativeWeight = 0;

        List<Element> children = DomUtilities.getChildren(layout);
        String prevId = null;
        boolean isFirstChild = true;
        boolean linkBackwards = true;
        boolean linkForwards = false;

        for (int index = 0, childCount = children.size(); index < childCount; index++) {
            Element child = children.get(index);

            View childView = edgeList.getView(child);
            if (childView == null) {
                // Could be a nested layout that is being removed etc
                prevId = null;
                isFirstChild = false;
                continue;
            }

            // Look at the layout_weight attributes and determine whether we should be
            // attached on the bottom/right or on the top/left
            if (weightSum > 0.0f) {
                float weight = getWeight(child);

                // We can't emulate a LinearLayout where multiple children have positive
                // weights. However, we CAN support the common scenario where a single
                // child has a non-zero weight, and all children after it are pushed
                // to the end and the weighted child fills the remaining space.
                if (cumulativeWeight == 0 && weight > 0) {
                    // See if we have a bottom/right edge to attach the forwards link to
                    // (at the end of the forwards chains). Only if so can we link forwards.
                    View referenced;
                    if (isVertical) {
                        referenced = edgeList.getSharedBottomEdge(layout);
                    } else {
                        referenced = edgeList.getSharedRightEdge(layout);
                    }
                    if (referenced != null) {
                        linkForwards = true;
                    }
                } else if (cumulativeWeight > 0) {
                    linkBackwards = false;
                }

                cumulativeWeight += weight;
            }

            analyzeGravity(edgeList, layout, isVertical, child, childView);
            convert0dipToWrapContent(child);

            // Chain elements together in the flow direction of the linear layout
            if (prevId != null) { // No constraint for first child
                if (linkBackwards) {
                    if (isVertical) {
                        childView.addVerticalConstraint(ATTR_LAYOUT_BELOW, prevId);
                    } else {
                        childView.addHorizConstraint(ATTR_LAYOUT_TO_RIGHT_OF, prevId);
                    }
                }
            } else if (isFirstChild) {
                assert linkBackwards;

                // First element; attach it to the parent if we can
                if (isVertical) {
                    View referenced = edgeList.getSharedTopEdge(layout);
                    if (referenced != null) {
                        if (isAncestor(referenced.getElement(), child)) {
                            childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_PARENT_TOP,
                                VALUE_TRUE);
                        } else {
                            childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_TOP,
                                    referenced.getId());
                        }
                    }
                } else {
                    View referenced = edgeList.getSharedLeftEdge(layout);
                    if (referenced != null) {
                        if (isAncestor(referenced.getElement(), child)) {
                            childView.addHorizConstraint(ATTR_LAYOUT_ALIGN_PARENT_LEFT,
                                    VALUE_TRUE);
                        } else {
                            childView.addHorizConstraint(
                                    ATTR_LAYOUT_ALIGN_LEFT, referenced.getId());
                        }
                    }
                }
            }

            if (linkForwards) {
                if (index < (childCount - 1)) {
                    Element nextChild = children.get(index + 1);
                    String nextId = mRefactoring.ensureHasId(mRootEdit, nextChild, null);
                    if (nextId != null) {
                        if (isVertical) {
                            childView.addVerticalConstraint(ATTR_LAYOUT_ABOVE, nextId);
                        } else {
                            childView.addHorizConstraint(ATTR_LAYOUT_TO_LEFT_OF, nextId);
                        }
                    }
                } else {
                    // Attach to right/bottom edge of the layout
                    if (isVertical) {
                        View referenced = edgeList.getSharedBottomEdge(layout);
                        if (referenced != null) {
                            if (isAncestor(referenced.getElement(), child)) {
                                childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_PARENT_BOTTOM,
                                    VALUE_TRUE);
                            } else {
                                childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_BOTTOM,
                                        referenced.getId());
                            }
                        }
                    } else {
                        View referenced = edgeList.getSharedRightEdge(layout);
                        if (referenced != null) {
                            if (isAncestor(referenced.getElement(), child)) {
                                childView.addHorizConstraint(ATTR_LAYOUT_ALIGN_PARENT_RIGHT,
                                        VALUE_TRUE);
                            } else {
                                childView.addHorizConstraint(
                                        ATTR_LAYOUT_ALIGN_RIGHT, referenced.getId());
                            }
                        }
                    }
                }
            }

            if (baselineRef != null && baselineRef.getId() != null
                    && !baselineRef.getId().equals(childView.getId())) {
                assert !isVertical;
                // Only align if they share the same gravity
                if ((childView.getGravity() & GRAVITY_VERT_MASK) ==
                        (baselineRef.getGravity() & GRAVITY_VERT_MASK)) {
                    childView.addHorizConstraint(ATTR_LAYOUT_ALIGN_BASELINE, baselineRef.getId());
                }
            }

            prevId = mRefactoring.ensureHasId(mRootEdit, child, null);
            isFirstChild = false;
        }
    }

    /**
     * Checks the layout "gravity" value for the given child and updates the constraints
     * to account for the gravity
     */
    private int analyzeGravity(EdgeList edgeList, Element layout, boolean isVertical,
            Element child, View childView) {
        // Use gravity to constrain elements in the axis orthogonal to the
        // direction of the layout
        int gravity = childView.getGravity();
        if (isVertical) {
            if ((gravity & GRAVITY_RIGHT) != 0) {
                View referenced = edgeList.getSharedRightEdge(layout);
                if (referenced != null) {
                    if (isAncestor(referenced.getElement(), child)) {
                        childView.addHorizConstraint(ATTR_LAYOUT_ALIGN_PARENT_RIGHT,
                                VALUE_TRUE);
                    } else {
                        childView.addHorizConstraint(ATTR_LAYOUT_ALIGN_RIGHT,
                                referenced.getId());
                    }
                }
            } else if ((gravity & GRAVITY_CENTER_HORIZ) != 0) {
                View referenced1 = edgeList.getSharedLeftEdge(layout);
                View referenced2 = edgeList.getSharedRightEdge(layout);
                if (referenced1 != null && referenced2 == referenced1) {
                    if (isAncestor(referenced1.getElement(), child)) {
                        childView.addHorizConstraint(ATTR_LAYOUT_CENTER_HORIZONTAL,
                                VALUE_TRUE);
                    }
                }
            } else if ((gravity & GRAVITY_FILL_HORIZ) != 0) {
                View referenced1 = edgeList.getSharedLeftEdge(layout);
                View referenced2 = edgeList.getSharedRightEdge(layout);
                if (referenced1 != null && referenced2 == referenced1) {
                    if (isAncestor(referenced1.getElement(), child)) {
                        childView.addHorizConstraint(ATTR_LAYOUT_ALIGN_PARENT_LEFT,
                                VALUE_TRUE);
                        childView.addHorizConstraint(ATTR_LAYOUT_ALIGN_PARENT_RIGHT,
                                VALUE_TRUE);
                    } else {
                        childView.addHorizConstraint(ATTR_LAYOUT_ALIGN_LEFT,
                                referenced1.getId());
                        childView.addHorizConstraint(ATTR_LAYOUT_ALIGN_RIGHT,
                                referenced2.getId());
                    }
                }
            } else if ((gravity & GRAVITY_LEFT) != 0) {
                View referenced = edgeList.getSharedLeftEdge(layout);
                if (referenced != null) {
                    if (isAncestor(referenced.getElement(), child)) {
                        childView.addHorizConstraint(ATTR_LAYOUT_ALIGN_PARENT_LEFT,
                                VALUE_TRUE);
                    } else {
                        childView.addHorizConstraint(ATTR_LAYOUT_ALIGN_LEFT,
                                referenced.getId());
                    }
                }
            }
        } else {
            // Handle horizontal layout: perform vertical gravity attachments
            if ((gravity & GRAVITY_BOTTOM) != 0) {
                View referenced = edgeList.getSharedBottomEdge(layout);
                if (referenced != null) {
                    if (isAncestor(referenced.getElement(), child)) {
                        childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_PARENT_BOTTOM,
                                VALUE_TRUE);
                    } else {
                        childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_BOTTOM,
                                referenced.getId());
                    }
                }
            } else if ((gravity & GRAVITY_CENTER_VERT) != 0) {
                View referenced1 = edgeList.getSharedTopEdge(layout);
                View referenced2 = edgeList.getSharedBottomEdge(layout);
                if (referenced1 != null && referenced2 == referenced1) {
                    if (isAncestor(referenced1.getElement(), child)) {
                        childView.addVerticalConstraint(ATTR_LAYOUT_CENTER_VERTICAL,
                                VALUE_TRUE);
                    }
                }
            } else if ((gravity & GRAVITY_FILL_VERT) != 0) {
                View referenced1 = edgeList.getSharedTopEdge(layout);
                View referenced2 = edgeList.getSharedBottomEdge(layout);
                if (referenced1 != null && referenced2 == referenced1) {
                    if (isAncestor(referenced1.getElement(), child)) {
                        childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_PARENT_TOP,
                                VALUE_TRUE);
                        childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_PARENT_BOTTOM,
                                VALUE_TRUE);
                    } else {
                        childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_TOP,
                                referenced1.getId());
                        childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_BOTTOM,
                                referenced2.getId());
                    }
                }
            } else if ((gravity & GRAVITY_TOP) != 0) {
                View referenced = edgeList.getSharedTopEdge(layout);
                if (referenced != null) {
                    if (isAncestor(referenced.getElement(), child)) {
                        childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_PARENT_TOP,
                                VALUE_TRUE);
                    } else {
                        childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_TOP,
                                referenced.getId());
                    }
                }
            }
        }
        return gravity;
    }

    /** Converts 0dip values in layout_width and layout_height to wrap_content instead */
    private void convert0dipToWrapContent(Element child) {
        // Must convert layout_height="0dip" to layout_height="wrap_content".
        // 0dip is a special trick used in linear layouts in the presence of
        // weights where 0dip ensures that the height of the view is not taken
        // into account when distributing the weights. However, when converted
        // to RelativeLayout this will instead cause the view to actually be assigned
        // 0 height.
        String height = child.getAttributeNS(ANDROID_URI, ATTR_LAYOUT_HEIGHT);
        // 0dip, 0dp, 0px, etc
        if (height != null && height.startsWith("0")) { //$NON-NLS-1$
            mRefactoring.setAttribute(mRootEdit, child, ANDROID_URI,
                    mRefactoring.getAndroidNamespacePrefix(), ATTR_LAYOUT_HEIGHT,
                    VALUE_WRAP_CONTENT);
        }
        String width = child.getAttributeNS(ANDROID_URI, ATTR_LAYOUT_WIDTH);
        if (width != null && width.startsWith("0")) { //$NON-NLS-1$
            mRefactoring.setAttribute(mRootEdit, child, ANDROID_URI,
                    mRefactoring.getAndroidNamespacePrefix(), ATTR_LAYOUT_WIDTH,
                    VALUE_WRAP_CONTENT);
        }
    }

    /**
     * Analyzes an embedded RelativeLayout within a layout hierarchy and updates the
     * constraints in the EdgeList with those relationships which can continue in the
     * outer single RelativeLayout.
     */
    private void analyzeRelativeLayout(EdgeList edgeList, Element layout) {
        NodeList children = layout.getChildNodes();
        for (int i = 0, n = children.getLength(); i < n; i++) {
            Node node = children.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                Element child = (Element) node;
                View childView = edgeList.getView(child);
                if (childView == null) {
                    // Could be a nested layout that is being removed etc
                    continue;
                }

                NamedNodeMap attributes = child.getAttributes();
                for (int j = 0, m = attributes.getLength(); j < m; j++) {
                    Attr attribute = (Attr) attributes.item(j);
                    String name = attribute.getLocalName();
                    String value = attribute.getValue();
                    if (name.equals(ATTR_LAYOUT_WIDTH)
                            || name.equals(ATTR_LAYOUT_HEIGHT)) {
                        // Ignore these for now
                    } else if (name.startsWith(ATTR_LAYOUT_RESOURCE_PREFIX)
                            && ANDROID_URI.equals(attribute.getNamespaceURI())) {
                        // Determine if the reference is to a known edge
                        String id = getIdBasename(value);
                        if (id != null) {
                            View referenced = edgeList.getView(id);
                            if (referenced != null) {
                                // This is a valid reference, so preserve
                                // the attribute
                                if (name.equals(ATTR_LAYOUT_BELOW) ||
                                        name.equals(ATTR_LAYOUT_ABOVE) ||
                                        name.equals(ATTR_LAYOUT_ALIGN_TOP) ||
                                        name.equals(ATTR_LAYOUT_ALIGN_BOTTOM) ||
                                        name.equals(ATTR_LAYOUT_ALIGN_BASELINE)) {
                                    // Vertical constraint
                                    childView.addVerticalConstraint(name, value);
                                } else if (name.equals(ATTR_LAYOUT_ALIGN_LEFT) ||
                                        name.equals(ATTR_LAYOUT_TO_LEFT_OF) ||
                                        name.equals(ATTR_LAYOUT_TO_RIGHT_OF) ||
                                        name.equals(ATTR_LAYOUT_ALIGN_RIGHT)) {
                                    // Horizontal constraint
                                    childView.addHorizConstraint(name, value);
                                } else {
                                    // We don't expect this
                                    assert false : name;
                                }
                            } else {
                                // Reference to some layout that is not included here.
                                // TODO: See if the given layout has an edge
                                // that corresponds to one of our known views
                                // so we can adjust the constraints and keep it after all.
                            }
                        } else {
                            // It's a parent-relative constraint (such
                            // as aligning with a parent edge, or centering
                            // in the parent view)
                            boolean remove = true;
                            if (name.equals(ATTR_LAYOUT_ALIGN_PARENT_LEFT)) {
                                View referenced = edgeList.getSharedLeftEdge(layout);
                                if (referenced != null) {
                                    if (isAncestor(referenced.getElement(), child)) {
                                        childView.addHorizConstraint(name, VALUE_TRUE);
                                    } else {
                                        childView.addHorizConstraint(
                                                ATTR_LAYOUT_ALIGN_LEFT, referenced.getId());
                                    }
                                    remove = false;
                                }
                            } else if (name.equals(ATTR_LAYOUT_ALIGN_PARENT_RIGHT)) {
                                View referenced = edgeList.getSharedRightEdge(layout);
                                if (referenced != null) {
                                    if (isAncestor(referenced.getElement(), child)) {
                                        childView.addHorizConstraint(name, VALUE_TRUE);
                                    } else {
                                        childView.addHorizConstraint(
                                            ATTR_LAYOUT_ALIGN_RIGHT, referenced.getId());
                                    }
                                    remove = false;
                                }
                            } else if (name.equals(ATTR_LAYOUT_ALIGN_PARENT_TOP)) {
                                View referenced = edgeList.getSharedTopEdge(layout);
                                if (referenced != null) {
                                    if (isAncestor(referenced.getElement(), child)) {
                                        childView.addVerticalConstraint(name, VALUE_TRUE);
                                    } else {
                                        childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_TOP,
                                                referenced.getId());
                                    }
                                    remove = false;
                                }
                            } else if (name.equals(ATTR_LAYOUT_ALIGN_PARENT_BOTTOM)) {
                                View referenced = edgeList.getSharedBottomEdge(layout);
                                if (referenced != null) {
                                    if (isAncestor(referenced.getElement(), child)) {
                                        childView.addVerticalConstraint(name, VALUE_TRUE);
                                    } else {
                                        childView.addVerticalConstraint(ATTR_LAYOUT_ALIGN_BOTTOM,
                                                referenced.getId());
                                    }
                                    remove = false;
                                }
                            }

                            boolean alignWithParent =
                                    name.equals(ATTR_LAYOUT_ALIGN_WITH_PARENT_MISSING);
                            if (remove && alignWithParent) {
                                // TODO - look for this one AFTER we have processed
                                // everything else, and then set constraints as necessary
                                // IF there are no other conflicting constraints!
                            }

                            // Otherwise it's some kind of centering which we don't support
                            // yet.

                            // TODO: Find a way to determine whether we have
                            // a corresponding edge for the parent (e.g. if
                            // the ViewInfo bounds match our outer parent or
                            // some other edge) and if so, substitute for that
                            // id.
                            // For example, if this element was centered
                            // horizontally in a RelativeLayout that actually
                            // occupies the entire width of our outer layout,
                            // then it can be preserved after all!

                            if (remove) {
                                if (name.startsWith("layout_margin")) { //$NON-NLS-1$
                                    continue;
                                }

                                // Remove unknown attributes?
                                // It's too early to do this, because we may later want
                                // to *set* this value and it would result in an overlapping edits
                                // exception. Therefore, we need to RECORD which attributes should
                                // be removed, which lines should have its indentation adjusted
                                // etc and finally process it all at the end!
                                //mRefactoring.removeAttribute(mRootEdit, child,
                                //        attribute.getNamespaceURI(), name);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * Given {@code @id/foo} or {@code @+id/foo}, returns foo. Note that given foo it will
     * return null.
     */
    private static String getIdBasename(String id) {
        if (id.startsWith(NEW_ID_PREFIX)) {
            return id.substring(NEW_ID_PREFIX.length());
        } else if (id.startsWith(ID_PREFIX)) {
            return id.substring(ID_PREFIX.length());
        }

        return null;
    }

    /** Returns true if the given second argument is a descendant of the first argument */
    private static boolean isAncestor(Node ancestor, Node node) {
        while (node != null) {
            if (node == ancestor) {
                return true;
            }
            node = node.getParentNode();
        }
        return false;
    }

    /**
     * Computes horizontal constraints for the views in the grid for any remaining views
     * that do not have constraints (as the result of the analysis of known layouts). This
     * will look at the rendered layout coordinates and attempt to connect elements based
     * on a spatial layout in the grid.
     */
    private void computeHorizontalConstraints(Grid grid) {
        int columns = grid.getColumns();

        String attachLeftProperty = ATTR_LAYOUT_ALIGN_PARENT_LEFT;
        String attachLeftValue = VALUE_TRUE;
        int marginLeft = 0;
        for (int col = 0; col < columns; col++) {
            if (!grid.colContainsTopLeftCorner(col)) {
                // Just accumulate margins for the next column
                marginLeft += grid.getColumnWidth(col);
            } else {
                // Add horizontal attachments
                String firstId = null;
                for (View view : grid.viewsStartingInCol(col, true)) {
                    assert view.getId() != null;
                    if (firstId == null) {
                        firstId = view.getId();
                        if (view.isConstrainedHorizontally()) {
                            // Nothing to do -- we already have an accurate position for
                            // this view
                        } else if (attachLeftProperty != null) {
                            view.addHorizConstraint(attachLeftProperty, attachLeftValue);
                            if (marginLeft > 0) {
                                view.addHorizConstraint(ATTR_LAYOUT_MARGIN_LEFT,
                                        String.format(VALUE_N_DP, marginLeft));
                                marginLeft = 0;
                            }
                        } else {
                            assert false;
                        }
                    } else if (!view.isConstrainedHorizontally()) {
                        view.addHorizConstraint(ATTR_LAYOUT_ALIGN_LEFT, firstId);
                    }
                }
            }

            // Figure out edge for the next column
            View view = grid.findRightEdgeView(col);
            if (view != null) {
                assert view.getId() != null;
                attachLeftProperty = ATTR_LAYOUT_TO_RIGHT_OF;
                attachLeftValue = view.getId();

                marginLeft = 0;
            } else if (marginLeft == 0) {
                marginLeft = grid.getColumnWidth(col);
            }
        }
    }

    /**
     * Performs vertical layout just like the {@link #computeHorizontalConstraints} method
     * did horizontally
     */
    private void computeVerticalConstraints(Grid grid) {
        int rows = grid.getRows();

        String attachTopProperty = ATTR_LAYOUT_ALIGN_PARENT_TOP;
        String attachTopValue = VALUE_TRUE;
        int marginTop = 0;
        for (int row = 0; row < rows; row++) {
            if (!grid.rowContainsTopLeftCorner(row)) {
                // Just accumulate margins for the next column
                marginTop += grid.getRowHeight(row);
            } else {
                // Add horizontal attachments
                String firstId = null;
                for (View view : grid.viewsStartingInRow(row, true)) {
                    assert view.getId() != null;
                    if (firstId == null) {
                        firstId = view.getId();
                        if (view.isConstrainedVertically()) {
                            // Nothing to do -- we already have an accurate position for
                            // this view
                        } else if (attachTopProperty != null) {
                            view.addVerticalConstraint(attachTopProperty, attachTopValue);
                            if (marginTop > 0) {
                                view.addVerticalConstraint(ATTR_LAYOUT_MARGIN_TOP,
                                        String.format(VALUE_N_DP, marginTop));
                                marginTop = 0;
                            }
                        } else {
                            assert false;
                        }
                    } else if (!view.isConstrainedVertically()) {
                        view.addVerticalConstraint(ATTR_LAYOUT_ALIGN_TOP, firstId);
                    }
                }
            }

            // Figure out edge for the next row
            View view = grid.findBottomEdgeView(row);
            if (view != null) {
                assert view.getId() != null;
                attachTopProperty = ATTR_LAYOUT_BELOW;
                attachTopValue = view.getId();
                marginTop = 0;
            } else if (marginTop == 0) {
                marginTop = grid.getRowHeight(row);
            }
        }
    }

    /**
     * Searches a view hierarchy and locates the {@link CanvasViewInfo} for the given
     * {@link Element}
     *
     * @param info the root {@link CanvasViewInfo} to search below
     * @param element the target element
     * @return the {@link CanvasViewInfo} which corresponds to the given element
     */
    private CanvasViewInfo findViewForElement(CanvasViewInfo info, Element element) {
        if (getElement(info) == element) {
            return info;
        }

        for (CanvasViewInfo child : info.getChildren()) {
            CanvasViewInfo result = findViewForElement(child, element);
            if (result != null) {
                return result;
            }
        }

        return null;
    }

    /** Returns the {@link Element} for the given {@link CanvasViewInfo} */
    private static Element getElement(CanvasViewInfo info) {
        Node node = info.getUiViewNode().getXmlNode();
        if (node instanceof Element) {
            return (Element) node;
        }

        return null;
    }

    /**
     * A grid of cells which can contain views, used to infer spatial relationships when
     * computing constraints. Note that a view can appear in than one cell; they will
     * appear in all cells that their bounds overlap with!
     */
    private class Grid {
        private final int[] mLeft;
        private final int[] mTop;
        // A list from row to column to cell, where a cell is a list of views
        private final List<List<List<View>>> mRowList;
        private int mRowCount;
        private int mColCount;

        Grid(List<View> views, int[] left, int[] top) {
            mLeft = left;
            mTop = top;

            // The left/top arrays should include the ending point too
            mColCount = left.length - 1;
            mRowCount = top.length - 1;

            // Using nested lists rather than arrays to avoid lack of typed arrays
            // (can't create List<View>[row][column] arrays)
            mRowList = new ArrayList<List<List<View>>>(top.length);
            for (int row = 0; row < top.length; row++) {
                List<List<View>> columnList = new ArrayList<List<View>>(left.length);
                for (int col = 0; col < left.length; col++) {
                    columnList.add(new ArrayList<View>(4));
                }
                mRowList.add(columnList);
            }

            for (View view : views) {
                // Get rid of the root view; we don't want that in the attachments logic;
                // it was there originally such that it would contribute the outermost
                // edges.
                if (view.mElement == mLayout) {
                    continue;
                }

                for (int i = 0; i < view.mRowSpan; i++) {
                    for (int j = 0; j < view.mColSpan; j++) {
                        mRowList.get(view.mRow + i).get(view.mCol + j).add(view);
                    }
                }
            }
        }

        /**
         * Returns the number of rows in the grid
         *
         * @return the row count
         */
        public int getRows() {
            return mRowCount;
        }

        /**
         * Returns the number of columns in the grid
         *
         * @return the column count
         */
        public int getColumns() {
            return mColCount;
        }

        /**
         * Returns the list of views overlapping the given cell
         *
         * @param row the row of the target cell
         * @param col the column of the target cell
         * @return a list of views overlapping the given column
         */
        public List<View> get(int row, int col) {
            return mRowList.get(row).get(col);
        }

        /**
         * Returns true if the given column contains a top left corner of a view
         *
         * @param column the column to check
         * @return true if one or more views have their top left corner in this column
         */
        public boolean colContainsTopLeftCorner(int column) {
            for (int row = 0; row < mRowCount; row++) {
                View view = getTopLeftCorner(row, column);
                if (view != null) {
                    return true;
                }
            }

            return false;
        }

        /**
         * Returns true if the given row contains a top left corner of a view
         *
         * @param row the row to check
         * @return true if one or more views have their top left corner in this row
         */
        public boolean rowContainsTopLeftCorner(int row) {
            for (int col = 0; col < mColCount; col++) {
                View view = getTopLeftCorner(row, col);
                if (view != null) {
                    return true;
                }
            }

            return false;
        }

        /**
         * Returns a list of views (optionally sorted by increasing row index) that have
         * their left edge starting in the given column
         *
         * @param col the column to look up views for
         * @param sort whether to sort the result in increasing row order
         * @return a list of views starting in the given column
         */
        public List<View> viewsStartingInCol(int col, boolean sort) {
            List<View> views = new ArrayList<View>();
            for (int row = 0; row < mRowCount; row++) {
                View view = getTopLeftCorner(row, col);
                if (view != null) {
                    views.add(view);
                }
            }

            if (sort) {
                View.sortByRow(views);
            }

            return views;
        }

        /**
         * Returns a list of views (optionally sorted by increasing column index) that have
         * their top edge starting in the given row
         *
         * @param row the row to look up views for
         * @param sort whether to sort the result in increasing column order
         * @return a list of views starting in the given row
         */
        public List<View> viewsStartingInRow(int row, boolean sort) {
            List<View> views = new ArrayList<View>();
            for (int col = 0; col < mColCount; col++) {
                View view = getTopLeftCorner(row, col);
                if (view != null) {
                    views.add(view);
                }
            }

            if (sort) {
                View.sortByColumn(views);
            }

            return views;
        }

        /**
         * Returns the pixel width of the given column
         *
         * @param col the column to look up the width of
         * @return the width of the column
         */
        public int getColumnWidth(int col) {
            return mLeft[col + 1] - mLeft[col];
        }

        /**
         * Returns the pixel height of the given row
         *
         * @param row the row to look up the height of
         * @return the height of the row
         */
        public int getRowHeight(int row) {
            return mTop[row + 1] - mTop[row];
        }

        /**
         * Returns the first view found that has its top left corner in the cell given by
         * the row and column indexes, or null if not found.
         *
         * @param row the row of the target cell
         * @param col the column of the target cell
         * @return a view with its top left corner in the given cell, or null if not found
         */
        View getTopLeftCorner(int row, int col) {
            List<View> views = get(row, col);
            if (views.size() > 0) {
                for (View view : views) {
                    if (view.mRow == row && view.mCol == col) {
                        return view;
                    }
                }
            }

            return null;
        }

        public View findRightEdgeView(int col) {
            for (int row = 0; row < mRowCount; row++) {
                List<View> views = get(row, col);
                if (views.size() > 0) {
                    List<View> result = new ArrayList<View>();
                    for (View view : views) {
                        // Ends on the right edge of this column?
                        if (view.mCol + view.mColSpan == col + 1) {
                            result.add(view);
                        }
                    }
                    if (result.size() > 1) {
                        View.sortByColumn(result);
                    }
                    if (result.size() > 0) {
                        return result.get(0);
                    }
                }
            }

            return null;
        }

        public View findBottomEdgeView(int row) {
            for (int col = 0; col < mColCount; col++) {
                List<View> views = get(row, col);
                if (views.size() > 0) {
                    List<View> result = new ArrayList<View>();
                    for (View view : views) {
                        // Ends on the bottom edge of this column?
                        if (view.mRow + view.mRowSpan == row + 1) {
                            result.add(view);
                        }
                    }
                    if (result.size() > 1) {
                        View.sortByRow(result);
                    }
                    if (result.size() > 0) {
                        return result.get(0);
                    }

                }
            }

            return null;
        }

        /**
         * Produces a display of view contents along with the pixel positions of each row/column,
         * like the following (used for diagnostics only)
         * <pre>
         *          |0                  |49                 |143                |192           |240
         *        36|                   |                   |button2            |
         *        72|                   |radioButton1       |button2            |
         *        74|button1            |radioButton1       |button2            |
         *       108|button1            |                   |button2            |
         *       110|                   |                   |button2            |
         *       149|                   |                   |                   |
         *       320
         * </pre>
         */
        @Override
        public String toString() {
            // Dump out the view table
            int cellWidth = 20;

            StringWriter stringWriter = new StringWriter();
            PrintWriter out = new PrintWriter(stringWriter);
            out.printf("%" + cellWidth + "s", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            for (int col = 0; col < mColCount + 1; col++) {
                out.printf("|%-" + (cellWidth - 1) + "d", mLeft[col]); //$NON-NLS-1$ //$NON-NLS-2$
            }
            out.printf("\n"); //$NON-NLS-1$
            for (int row = 0; row < mRowCount + 1; row++) {
                out.printf("%" + cellWidth + "d", mTop[row]); //$NON-NLS-1$ //$NON-NLS-2$
                if (row == mRowCount) {
                    break;
                }
                for (int col = 0; col < mColCount; col++) {
                    List<View> views = get(row, col);
                    StringBuilder sb = new StringBuilder();
                    for (View view : views) {
                        String id = view != null ? view.getId() : ""; //$NON-NLS-1$
                        if (id.startsWith(NEW_ID_PREFIX)) {
                            id = id.substring(NEW_ID_PREFIX.length());
                        }
                        if (id.length() > cellWidth - 2) {
                            id = id.substring(0, cellWidth - 2);
                        }
                        if (sb.length() > 0) {
                            sb.append(',');
                        }
                        sb.append(id);
                    }
                    String cellString = sb.toString();
                    if (cellString.contains(",") && cellString.length() > cellWidth - 2) { //$NON-NLS-1$
                        cellString = cellString.substring(0, cellWidth - 6) + "...,"; //$NON-NLS-1$
                    }
                    out.printf("|%-" + (cellWidth - 2) + "s ", cellString); //$NON-NLS-1$ //$NON-NLS-2$
                }
                out.printf("\n"); //$NON-NLS-1$
            }

            out.flush();
            return stringWriter.toString();
        }
    }

    /** Holds layout information about an individual view. */
    private static class View {
        private final Element mElement;
        private int mRow = -1;
        private int mCol = -1;
        private int mRowSpan = -1;
        private int mColSpan = -1;
        private CanvasViewInfo mInfo;
        private String mId;
        private List<Pair<String, String>> mHorizConstraints =
            new ArrayList<Pair<String, String>>(4);
        private List<Pair<String, String>> mVerticalConstraints =
            new ArrayList<Pair<String, String>>(4);
        private int mGravity;

        public View(CanvasViewInfo view, Element element) {
            mInfo = view;
            mElement = element;
            mGravity = GravityHelper.getGravity(element);
        }

        public int getHeight() {
            return mInfo.getAbsRect().height;
        }

        public int getGravity() {
            return mGravity;
        }

        public String getId() {
            return mId;
        }

        public Element getElement() {
            return mElement;
        }

        public List<Pair<String, String>> getHorizConstraints() {
            return mHorizConstraints;
        }

        public List<Pair<String, String>> getVerticalConstraints() {
            return mVerticalConstraints;
        }

        public boolean isConstrainedHorizontally() {
            return mHorizConstraints.size() > 0;
        }

        public boolean isConstrainedVertically() {
            return mVerticalConstraints.size() > 0;
        }

        public void addHorizConstraint(String property, String value) {
            assert property != null && value != null;
            // TODO - look for duplicates?
            mHorizConstraints.add(Pair.of(property, value));
        }

        public void addVerticalConstraint(String property, String value) {
            assert property != null && value != null;
            mVerticalConstraints.add(Pair.of(property, value));
        }

        public int getLeftEdge() {
            return mInfo.getAbsRect().x;
        }

        public int getTopEdge() {
            return mInfo.getAbsRect().y;
        }

        public int getRightEdge() {
            Rectangle bounds = mInfo.getAbsRect();
            // +1: make the bounds overlap, so the right edge is the same as the
            // left edge of the neighbor etc. Otherwise we end up with lots of 1-pixel wide
            // columns between adjacent items.
            return bounds.x + bounds.width + 1;
        }

        public int getBottomEdge() {
            Rectangle bounds = mInfo.getAbsRect();
            return bounds.y + bounds.height + 1;
        }

        @Override
        public String toString() {
            return "View [mId=" + mId + "]"; //$NON-NLS-1$ //$NON-NLS-2$
        }

        public static void sortByRow(List<View> views) {
            Collections.sort(views, new ViewComparator(true/*rowSort*/));
        }

        public static void sortByColumn(List<View> views) {
            Collections.sort(views, new ViewComparator(false/*rowSort*/));
        }

        /** Comparator to help sort views by row or column index */
        private static class ViewComparator implements Comparator<View> {
            boolean mRowSort;

            public ViewComparator(boolean rowSort) {
                mRowSort = rowSort;
            }

            @Override
            public int compare(View view1, View view2) {
                if (mRowSort) {
                    return view1.mRow - view2.mRow;
                } else {
                    return view1.mCol - view2.mCol;
                }
            }
        }
    }

    /**
     * An edge list takes a hierarchy of elements and records the bounds of each element
     * into various lists such that it can answer queries about shared edges, about which
     * particular pixels occur as a boundary edge, etc.
     */
    private class EdgeList {
        private final Map<Element, View> mElementToViewMap = new HashMap<Element, View>(100);
        private final Map<String, View> mIdToViewMap = new HashMap<String, View>(100);
        private final Map<Integer, List<View>> mLeft = new HashMap<Integer, List<View>>();
        private final Map<Integer, List<View>> mTop = new HashMap<Integer, List<View>>();
        private final Map<Integer, List<View>> mRight = new HashMap<Integer, List<View>>();
        private final Map<Integer, List<View>> mBottom = new HashMap<Integer, List<View>>();
        private final Map<Element, Element> mSharedLeftEdge = new HashMap<Element, Element>();
        private final Map<Element, Element> mSharedTopEdge = new HashMap<Element, Element>();
        private final Map<Element, Element> mSharedRightEdge = new HashMap<Element, Element>();
        private final Map<Element, Element> mSharedBottomEdge = new HashMap<Element, Element>();
        private final List<Element> mDelete = new ArrayList<Element>();

        EdgeList(CanvasViewInfo view) {
            analyze(view, true);
            mDelete.remove(getElement(view));
        }

        public void setIdAttributeValue(View view, String id) {
            assert id.startsWith(NEW_ID_PREFIX) || id.startsWith(ID_PREFIX);
            view.mId = id;
            mIdToViewMap.put(getIdBasename(id), view);
        }

        public View getView(Element element) {
            return mElementToViewMap.get(element);
        }

        public View getView(String id) {
            return mIdToViewMap.get(id);
        }

        public List<View> getTopEdgeViews(Integer topOffset) {
            return mTop.get(topOffset);
        }

        public List<View> getLeftEdgeViews(Integer leftOffset) {
            return mLeft.get(leftOffset);
        }

        void record(Map<Integer, List<View>> map, Integer edge, View info) {
            List<View> list = map.get(edge);
            if (list == null) {
                list = new ArrayList<View>();
                map.put(edge, list);
            }
            list.add(info);
        }

        private List<Integer> getOffsets(Set<Integer> first, Set<Integer> second) {
            Set<Integer> joined = new HashSet<Integer>(first.size() + second.size());
            joined.addAll(first);
            joined.addAll(second);
            List<Integer> unique = new ArrayList<Integer>(joined);
            Collections.sort(unique);

            return unique;
        }

        public List<Element> getDeletedElements() {
            return mDelete;
        }

        public List<Integer> getColumnOffsets() {
            return getOffsets(mLeft.keySet(), mRight.keySet());
        }
        public List<Integer> getRowOffsets() {
            return getOffsets(mTop.keySet(), mBottom.keySet());
        }

        private View analyze(CanvasViewInfo view, boolean isRoot) {
            View added = null;
            if (!mFlatten || !isRemovableLayout(view)) {
                added = add(view);
                if (!isRoot) {
                    return added;
                }
            } else {
                mDelete.add(getElement(view));
            }

            Element parentElement = getElement(view);
            Rectangle parentBounds = view.getAbsRect();

            // Build up a table model of the view
            for (CanvasViewInfo child : view.getChildren()) {
                Rectangle childBounds = child.getAbsRect();
                Element childElement = getElement(child);

                // See if this view shares the edge with the removed
                // parent layout, and if so, record that such that we can
                // later handle attachments to the removed parent edges
                if (parentBounds.x == childBounds.x) {
                    mSharedLeftEdge.put(childElement, parentElement);
                }
                if (parentBounds.y == childBounds.y) {
                    mSharedTopEdge.put(childElement, parentElement);
                }
                if (parentBounds.x + parentBounds.width == childBounds.x + childBounds.width) {
                    mSharedRightEdge.put(childElement, parentElement);
                }
                if (parentBounds.y + parentBounds.height == childBounds.y + childBounds.height) {
                    mSharedBottomEdge.put(childElement, parentElement);
                }

                if (mFlatten && isRemovableLayout(child)) {
                    // When flattening, we want to disregard all layouts and instead
                    // add their children!
                    for (CanvasViewInfo childView : child.getChildren()) {
                        analyze(childView, false);

                        Element childViewElement = getElement(childView);
                        Rectangle childViewBounds = childView.getAbsRect();

                        // See if this view shares the edge with the removed
                        // parent layout, and if so, record that such that we can
                        // later handle attachments to the removed parent edges
                        if (parentBounds.x == childViewBounds.x) {
                            mSharedLeftEdge.put(childViewElement, parentElement);
                        }
                        if (parentBounds.y == childViewBounds.y) {
                            mSharedTopEdge.put(childViewElement, parentElement);
                        }
                        if (parentBounds.x + parentBounds.width == childViewBounds.x
                                + childViewBounds.width) {
                            mSharedRightEdge.put(childViewElement, parentElement);
                        }
                        if (parentBounds.y + parentBounds.height == childViewBounds.y
                                + childViewBounds.height) {
                            mSharedBottomEdge.put(childViewElement, parentElement);
                        }
                    }
                    mDelete.add(childElement);
                } else {
                    analyze(child, false);
                }
            }

            return added;
        }

        public View getSharedLeftEdge(Element element) {
            return getSharedEdge(element, mSharedLeftEdge);
        }

        public View getSharedRightEdge(Element element) {
            return getSharedEdge(element, mSharedRightEdge);
        }

        public View getSharedTopEdge(Element element) {
            return getSharedEdge(element, mSharedTopEdge);
        }

        public View getSharedBottomEdge(Element element) {
            return getSharedEdge(element, mSharedBottomEdge);
        }

        private View getSharedEdge(Element element, Map<Element, Element> sharedEdgeMap) {
            Element original = element;

            while (element != null) {
                View view = getView(element);
                if (view != null) {
                    assert isAncestor(element, original);
                    return view;
                }
                element = sharedEdgeMap.get(element);
            }

            return null;
        }

        private View add(CanvasViewInfo info) {
            Rectangle bounds = info.getAbsRect();
            Element element = getElement(info);
            View view = new View(info, element);
            mElementToViewMap.put(element, view);
            record(mLeft, Integer.valueOf(bounds.x), view);
            record(mTop, Integer.valueOf(bounds.y), view);
            record(mRight, Integer.valueOf(view.getRightEdge()), view);
            record(mBottom, Integer.valueOf(view.getBottomEdge()), view);
            return view;
        }

        /**
         * Returns true if the given {@link CanvasViewInfo} represents an element we
         * should remove in a flattening conversion. We don't want to remove non-layout
         * views, or layout views that for example contain drawables on their own.
         */
        private boolean isRemovableLayout(CanvasViewInfo child) {
            // The element being converted is NOT removable!
            Element element = getElement(child);
            if (element == mLayout) {
                return false;
            }

            ElementDescriptor descriptor = child.getUiViewNode().getDescriptor();
            String name = descriptor.getXmlLocalName();
            if (name.equals(LINEAR_LAYOUT) || name.equals(RELATIVE_LAYOUT)) {
                // Don't delete layouts that provide a background image or gradient
                if (element.hasAttributeNS(ANDROID_URI, ATTR_BACKGROUND)) {
                    AdtPlugin.log(IStatus.WARNING,
                            "Did not flatten layout %1$s because it defines a '%2$s' attribute",
                            VisualRefactoring.getId(element), ATTR_BACKGROUND);
                    return false;
                }

                return true;
            }

            return false;
        }
    }
}
