/*
 * 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.common.layout.grid;

import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_COLUMN_COUNT;
import static com.android.SdkConstants.ATTR_ID;
import static com.android.SdkConstants.ATTR_LAYOUT_COLUMN;
import static com.android.SdkConstants.ATTR_LAYOUT_COLUMN_SPAN;
import static com.android.SdkConstants.ATTR_LAYOUT_GRAVITY;
import static com.android.SdkConstants.ATTR_LAYOUT_HEIGHT;
import static com.android.SdkConstants.ATTR_LAYOUT_ROW;
import static com.android.SdkConstants.ATTR_LAYOUT_ROW_SPAN;
import static com.android.SdkConstants.ATTR_LAYOUT_WIDTH;
import static com.android.SdkConstants.ATTR_ORIENTATION;
import static com.android.SdkConstants.ATTR_ROW_COUNT;
import static com.android.SdkConstants.FQCN_GRID_LAYOUT;
import static com.android.SdkConstants.FQCN_SPACE;
import static com.android.SdkConstants.FQCN_SPACE_V7;
import static com.android.SdkConstants.GRID_LAYOUT;
import static com.android.SdkConstants.NEW_ID_PREFIX;
import static com.android.SdkConstants.SPACE;
import static com.android.SdkConstants.VALUE_BOTTOM;
import static com.android.SdkConstants.VALUE_CENTER_VERTICAL;
import static com.android.SdkConstants.VALUE_N_DP;
import static com.android.SdkConstants.VALUE_TOP;
import static com.android.SdkConstants.VALUE_VERTICAL;
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_RIGHT;
import static java.lang.Math.abs;
import static java.lang.Math.max;
import static java.lang.Math.min;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.api.IClientRulesEngine;
import com.android.ide.common.api.INode;
import com.android.ide.common.api.IViewMetadata;
import com.android.ide.common.api.Margins;
import com.android.ide.common.api.Rect;
import com.android.ide.common.layout.GravityHelper;
import com.android.ide.common.layout.GridLayoutRule;
import com.android.utils.Pair;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/** Models a GridLayout */
public class GridModel {
    /** Marker value used to indicate values (rows, columns, etc) which have not been set */
    static final int UNDEFINED = Integer.MIN_VALUE;

    /** The size of spacers in the dimension that they are not defining */
    static final int SPACER_SIZE_DP = 1;

    /** Attribute value used for {@link #SPACER_SIZE_DP} */
    private static final String SPACER_SIZE = String.format(VALUE_N_DP, SPACER_SIZE_DP);

    /** Width assigned to a newly added column with the Add Column action */
    private static final int DEFAULT_CELL_WIDTH = 100;

    /** Height assigned to a newly added row with the Add Row action */
    private static final int DEFAULT_CELL_HEIGHT = 15;

    /** The GridLayout node, never null */
    public final INode layout;

    /** True if this is a vertical layout, and false if it is horizontal (the default) */
    public boolean vertical;

    /** The declared count of rows (which may be {@link #UNDEFINED} if not specified) */
    public int declaredRowCount;

    /** The declared count of columns (which may be {@link #UNDEFINED} if not specified) */
    public int declaredColumnCount;

    /** The actual count of rows found in the grid */
    public int actualRowCount;

    /** The actual count of columns found in the grid */
    public int actualColumnCount;

    /**
     * Array of positions (indexed by column) of the left edge of table cells; this
     * corresponds to the column positions in the grid
     */
    private int[] mLeft;

    /**
     * Array of positions (indexed by row) of the top edge of table cells; this
     * corresponds to the row positions in the grid
     */
    private int[] mTop;

    /**
     * Array of positions (indexed by column) of the maximum right hand side bounds of a
     * node in the given column; this represents the visual edge of a column even when the
     * actual column is wider
     */
    private int[] mMaxRight;

    /**
     * Array of positions (indexed by row) of the maximum bottom bounds of a node in the
     * given row; this represents the visual edge of a row even when the actual row is
     * taller
     */
    private int[] mMaxBottom;

    /**
     * Array of baselines computed for the rows. This array is populated lazily and should
     * not be accessed directly; call {@link #getBaseline(int)} instead.
     */
    private int[] mBaselines;

    /** List of all the view data for the children in this layout */
    private List<ViewData> mChildViews;

    /** The {@link IClientRulesEngine} */
    private final IClientRulesEngine mRulesEngine;

    /**
     * An actual instance of a GridLayout object that this grid model corresponds to.
     */
    private Object mViewObject;

    /** The namespace to use for attributes */
    private String mNamespace;

    /**
     * Constructs a {@link GridModel} for the given layout
     *
     * @param rulesEngine the associated rules engine
     * @param node the GridLayout node
     * @param viewObject an actual GridLayout instance, or null
     */
    private GridModel(IClientRulesEngine rulesEngine, INode node, Object viewObject) {
        mRulesEngine = rulesEngine;
        layout = node;
        mViewObject = viewObject;
        loadFromXml();
    }

    // Factory cache for most recent item (used primarily because during paints and drags
    // the grid model is called repeatedly for the same view object.)
    private static WeakReference<Object> sCachedViewObject = new WeakReference<Object>(null);
    private static WeakReference<GridModel> sCachedViewModel;

    /**
     * Factory which returns a grid model for the given node.
     *
     * @param rulesEngine the associated rules engine
     * @param node the GridLayout node
     * @param viewObject an actual GridLayout instance, or null
     * @return a new model
     */
    @NonNull
    public static GridModel get(
            @NonNull IClientRulesEngine rulesEngine,
            @NonNull INode node,
            @Nullable Object viewObject) {
        if (viewObject != null && viewObject == sCachedViewObject.get()) {
            GridModel model = sCachedViewModel.get();
            if (model != null) {
                return model;
            }
        }

        GridModel model = new GridModel(rulesEngine, node, viewObject);
        sCachedViewModel = new WeakReference<GridModel>(model);
        sCachedViewObject = new WeakReference<Object>(viewObject);
        return model;
    }

    /**
     * Returns the {@link ViewData} for the child at the given index
     *
     * @param index the position of the child node whose view we want to look up
     * @return the corresponding {@link ViewData}
     */
    public ViewData getView(int index) {
        return mChildViews.get(index);
    }

    /**
     * Returns the {@link ViewData} for the given child node.
     *
     * @param node the node for which we want the view info
     * @return the view info for the node, or null if not found
     */
    public ViewData getView(INode node) {
        for (ViewData view : mChildViews) {
            if (view.node == node) {
                return view;
            }
        }

        return null;
    }

    /**
     * Computes the index (among the children nodes) to insert a new node into which
     * should be positioned at the given row and column. This will skip over any nodes
     * that have implicit positions earlier than the given node, and will also ensure that
     * all nodes are placed before the spacer nodes.
     *
     * @param row the target row of the new node
     * @param column the target column of the new node
     * @return the insert position to use or -1 if no preference is found
     */
    public int getInsertIndex(int row, int column) {
        if (vertical) {
            for (ViewData view : mChildViews) {
                if (view.column > column || view.column == column && view.row >= row) {
                    return view.index;
                }
            }
        } else {
            for (ViewData view : mChildViews) {
                if (view.row > row || view.row == row && view.column >= column) {
                    return view.index;
                }
            }
        }

        // Place it before the first spacer
        for (ViewData view : mChildViews) {
            if (view.isSpacer()) {
                return view.index;
            }
        }

        return -1;
    }

    /**
     * Returns the baseline of the given row, or -1 if none is found. This looks for views
     * in the row which have baseline vertical alignment and also define their own
     * baseline, and returns the first such match.
     *
     * @param row the row to look up a baseline for
     * @return the baseline relative to the row position, or -1 if not defined
     */
    public int getBaseline(int row) {
        if (row < 0 || row >= mBaselines.length) {
            return -1;
        }

        int baseline = mBaselines[row];
        if (baseline == UNDEFINED) {
            baseline = -1;

            // TBD: Consider stringing together row information in the view data
            // so I can quickly identify the views in a given row instead of searching
            // among all?
            for (ViewData view : mChildViews) {
                // We only count baselines for views with rowSpan=1 because
                // baseline alignment doesn't work for cell spanning views
                if (view.row == row && view.rowSpan == 1) {
                    baseline = view.node.getBaseline();
                    if (baseline != -1) {
                        // Even views that do have baselines do not count towards a row
                        // baseline if they have a vertical gravity
                        String gravity = getGridAttribute(view.node, ATTR_LAYOUT_GRAVITY);
                        if (gravity == null
                                || !(gravity.contains(VALUE_TOP)
                                        || gravity.contains(VALUE_BOTTOM)
                                        || gravity.contains(VALUE_CENTER_VERTICAL))) {
                            // Compute baseline relative to the row, not the view itself
                            baseline += view.node.getBounds().y - getRowY(row);
                            break;
                        }
                    }
                }
            }
            mBaselines[row] = baseline;
        }

        return baseline;
    }

    /** Applies the row and column values into the XML */
    void applyPositionAttributes() {
        for (ViewData view : mChildViews) {
            view.applyPositionAttributes();
        }

        // Also fix the columnCount
        if (getGridAttribute(layout, ATTR_COLUMN_COUNT) != null &&
                declaredColumnCount > actualColumnCount) {
            setGridAttribute(layout, ATTR_COLUMN_COUNT, actualColumnCount);
        }
    }

    /**
     * Sets the given GridLayout attribute (rowCount, layout_row, etc) to the
     * given value. This automatically handles using the right XML namespace
     * based on whether the GridLayout is the android.widget.GridLayout, or the
     * support library GridLayout, and whether it's in a library project or not
     * etc.
     *
     * @param node the node to apply the attribute to
     * @param name the local name of the attribute
     * @param value the integer value to set the attribute to
     */
    public void setGridAttribute(INode node, String name, int value) {
        setGridAttribute(node, name, Integer.toString(value));
    }

    /**
     * Sets the given GridLayout attribute (rowCount, layout_row, etc) to the
     * given value. This automatically handles using the right XML namespace
     * based on whether the GridLayout is the android.widget.GridLayout, or the
     * support library GridLayout, and whether it's in a library project or not
     * etc.
     *
     * @param node the node to apply the attribute to
     * @param name the local name of the attribute
     * @param value the string value to set the attribute to, or null to clear
     *            it
     */
    public void setGridAttribute(INode node, String name, String value) {
        node.setAttribute(getNamespace(), name, value);
    }

    /**
     * Returns the namespace URI to use for GridLayout-specific attributes, such
     * as columnCount, layout_column, layout_column_span, layout_gravity etc.
     *
     * @return the namespace, never null
     */
    public String getNamespace() {
        if (mNamespace == null) {
            mNamespace = ANDROID_URI;

            String fqcn = layout.getFqcn();
            if (!fqcn.equals(GRID_LAYOUT) && !fqcn.equals(FQCN_GRID_LAYOUT)) {
                mNamespace = mRulesEngine.getAppNameSpace();
            }
        }

        return mNamespace;
    }

    /** Removes the given flag from a flag attribute value and returns the result */
    static String removeFlag(String flag, String value) {
        if (value.equals(flag)) {
            return null;
        }
        // Handle spaces between pipes and flag are a prefix, suffix and interior occurrences
        int index = value.indexOf(flag);
        if (index != -1) {
            int pipe = value.lastIndexOf('|', index);
            int endIndex = index + flag.length();
            if (pipe != -1) {
                value = value.substring(0, pipe).trim() + value.substring(endIndex).trim();
            } else {
                pipe = value.indexOf('|', endIndex);
                if (pipe != -1) {
                    value = value.substring(0, index).trim() + value.substring(pipe + 1).trim();
                } else {
                    value = value.substring(0, index).trim() + value.substring(endIndex).trim();
                }
            }
        }

        return value;
    }

    /**
     * Loads a {@link GridModel} from the XML model.
     */
    private void loadFromXml() {
        INode[] children = layout.getChildren();

        declaredRowCount = getGridAttribute(layout, ATTR_ROW_COUNT, UNDEFINED);
        declaredColumnCount = getGridAttribute(layout, ATTR_COLUMN_COUNT, UNDEFINED);
        // Horizontal is the default, so if no value is specified it is horizontal.
        vertical = VALUE_VERTICAL.equals(getGridAttribute(layout, ATTR_ORIENTATION));

        mChildViews = new ArrayList<ViewData>(children.length);
        int index = 0;
        for (INode child : children) {
            ViewData view = new ViewData(child, index++);
            mChildViews.add(view);
        }

        // Assign row/column positions to all cells that do not explicitly define them
        if (!assignRowsAndColumnsFromViews(mChildViews)) {
            assignRowsAndColumnsFromXml(
                    declaredRowCount == UNDEFINED ? children.length : declaredRowCount,
                    declaredColumnCount == UNDEFINED ? children.length : declaredColumnCount);
        }

        assignCellBounds();

        for (int i = 0; i <= actualRowCount; i++) {
            mBaselines[i] = UNDEFINED;
        }
    }

    private Pair<Map<Integer, Integer>, Map<Integer, Integer>> findCellsOutsideDeclaredBounds() {
        // See if we have any (row,column) pairs that fall outside the declared
        // bounds; for these we identify the number of unique values and assign these
        // consecutive values
        Map<Integer, Integer> extraColumnsMap = null;
        Map<Integer, Integer> extraRowsMap = null;
        if (declaredRowCount != UNDEFINED) {
            Set<Integer> extraRows = null;
            for (ViewData view : mChildViews) {
                if (view.row >= declaredRowCount) {
                    if (extraRows == null) {
                        extraRows = new HashSet<Integer>();
                    }
                    extraRows.add(view.row);
                }
            }
            if (extraRows != null && declaredRowCount != UNDEFINED) {
                List<Integer> rows = new ArrayList<Integer>(extraRows);
                Collections.sort(rows);
                int row = declaredRowCount;
                extraRowsMap = new HashMap<Integer, Integer>();
                for (Integer declared : rows) {
                    extraRowsMap.put(declared, row++);
                }
            }
        }
        if (declaredColumnCount != UNDEFINED) {
            Set<Integer> extraColumns = null;
            for (ViewData view : mChildViews) {
                if (view.column >= declaredColumnCount) {
                    if (extraColumns == null) {
                        extraColumns = new HashSet<Integer>();
                    }
                    extraColumns.add(view.column);
                }
            }
            if (extraColumns != null && declaredColumnCount != UNDEFINED) {
                List<Integer> columns = new ArrayList<Integer>(extraColumns);
                Collections.sort(columns);
                int column = declaredColumnCount;
                extraColumnsMap = new HashMap<Integer, Integer>();
                for (Integer declared : columns) {
                    extraColumnsMap.put(declared, column++);
                }
            }
        }

        return Pair.of(extraRowsMap, extraColumnsMap);
    }

    /**
     * Figure out actual row and column numbers for views that do not specify explicit row
     * and/or column numbers
     * TODO: Consolidate with the algorithm in GridLayout to ensure we get the
     * exact same results!
     */
    private void assignRowsAndColumnsFromXml(int rowCount, int columnCount) {
        Pair<Map<Integer, Integer>, Map<Integer, Integer>> p = findCellsOutsideDeclaredBounds();
        Map<Integer, Integer> extraRowsMap = p.getFirst();
        Map<Integer, Integer> extraColumnsMap = p.getSecond();

        if (!vertical) {
            // Horizontal GridLayout: this is the default. Row and column numbers
            // are assigned by assuming that the children are assigned successive
            // column numbers until we get to the column count of the grid, at which
            // point we jump to the next row. If any cell specifies either an explicit
            // row number of column number, we jump to the next available position.
            // Note also that if there are any rowspans on the current row, then the
            // next row we jump to is below the largest such rowspan - in other words,
            // the algorithm does not fill holes in the middle!

            // TODO: Ensure that we don't run into trouble if a later element specifies
            // an earlier number... find out what the layout does in that case!
            int row = 0;
            int column = 0;
            int nextRow = 1;
            for (ViewData view : mChildViews) {
                int declaredColumn = view.column;
                if (declaredColumn != UNDEFINED) {
                    if (declaredColumn >= columnCount) {
                        assert extraColumnsMap != null;
                        declaredColumn = extraColumnsMap.get(declaredColumn);
                        view.column = declaredColumn;
                    }
                    if (declaredColumn < column) {
                        // Must jump to the next row to accommodate the new row
                        assert nextRow > row;
                        //row++;
                        row = nextRow;
                    }
                    column = declaredColumn;
                } else {
                    view.column = column;
                }
                if (view.row != UNDEFINED) {
                    // TODO: Should this adjust the column number too? (If so must
                    // also update view.column since we've already processed the local
                    // column number)
                    row = view.row;
                } else {
                    view.row = row;
                }

                nextRow = Math.max(nextRow, view.row + view.rowSpan);

                // Advance
                column += view.columnSpan;
                if (column >= columnCount) {
                    column = 0;
                    assert nextRow > row;
                    //row++;
                    row = nextRow;
                }
            }
        } else {
            // Vertical layout: successive children are assigned to the same column in
            // successive rows.
            int row = 0;
            int column = 0;
            int nextColumn = 1;
            for (ViewData view : mChildViews) {
                int declaredRow = view.row;
                if (declaredRow != UNDEFINED) {
                    if (declaredRow >= rowCount) {
                        declaredRow = extraRowsMap.get(declaredRow);
                        view.row = declaredRow;
                    }
                    if (declaredRow < row) {
                        // Must jump to the next column to accommodate the new column
                        assert nextColumn > column;
                        column = nextColumn;
                    }
                    row = declaredRow;
                } else {
                    view.row = row;
                }
                if (view.column != UNDEFINED) {
                    // TODO: Should this adjust the row number too? (If so must
                    // also update view.row since we've already processed the local
                    // row number)
                    column = view.column;
                } else {
                    view.column = column;
                }

                nextColumn = Math.max(nextColumn, view.column + view.columnSpan);

                // Advance
                row += view.rowSpan;
                if (row >= rowCount) {
                    row = 0;
                    assert nextColumn > column;
                    //row++;
                    column = nextColumn;
                }
            }
        }
    }

    private static boolean sAttemptSpecReflection = true;

    private boolean assignRowsAndColumnsFromViews(List<ViewData> views) {
        if (!sAttemptSpecReflection) {
            return false;
        }

        try {
            // Lazily initialized reflection methods
            Field spanField = null;
            Field rowSpecField = null;
            Field colSpecField = null;
            Field minField = null;
            Field maxField = null;
            Method getLayoutParams = null;

            for (ViewData view : views) {
                // TODO: If the element *specifies* anything in XML, use that instead
                Object child = mRulesEngine.getViewObject(view.node);
                if (child == null) {
                    // Fallback to XML model
                    return false;
                }

                if (getLayoutParams == null) {
                    getLayoutParams = child.getClass().getMethod("getLayoutParams"); //$NON-NLS-1$
                }
                Object layoutParams = getLayoutParams.invoke(child);
                if (rowSpecField == null) {
                    Class<? extends Object> layoutParamsClass = layoutParams.getClass();
                    rowSpecField = layoutParamsClass.getDeclaredField("rowSpec");    //$NON-NLS-1$
                    colSpecField = layoutParamsClass.getDeclaredField("columnSpec"); //$NON-NLS-1$
                    rowSpecField.setAccessible(true);
                    colSpecField.setAccessible(true);
                }
                assert colSpecField != null;

                Object rowSpec = rowSpecField.get(layoutParams);
                Object colSpec = colSpecField.get(layoutParams);
                if (spanField == null) {
                    spanField = rowSpec.getClass().getDeclaredField("span"); //$NON-NLS-1$
                    spanField.setAccessible(true);
                }
                assert spanField != null;
                Object rowInterval = spanField.get(rowSpec);
                Object colInterval = spanField.get(colSpec);
                if (minField == null) {
                    Class<? extends Object> intervalClass = rowInterval.getClass();
                    minField = intervalClass.getDeclaredField("min"); //$NON-NLS-1$
                    maxField = intervalClass.getDeclaredField("max"); //$NON-NLS-1$
                    minField.setAccessible(true);
                    maxField.setAccessible(true);
                }
                assert maxField != null;

                int row = minField.getInt(rowInterval);
                int col = minField.getInt(colInterval);
                int rowEnd = maxField.getInt(rowInterval);
                int colEnd = maxField.getInt(colInterval);

                view.column = col;
                view.row = row;
                view.columnSpan = colEnd - col;
                view.rowSpan = rowEnd - row;
            }

            return true;

        } catch (Throwable e) {
            sAttemptSpecReflection = false;
            return false;
        }
    }

    /**
     * Computes the positions of the column and row boundaries
     */
    private void assignCellBounds() {
        if (!assignCellBoundsFromView()) {
            assignCellBoundsFromBounds();
        }
        initializeMaxBounds();
        mBaselines = new int[actualRowCount + 1];
    }

    /**
     * Computes the positions of the column and row boundaries, using actual
     * layout data from the associated GridLayout instance (stored in
     * {@link #mViewObject})
     */
    private boolean assignCellBoundsFromView() {
        if (mViewObject != null) {
            Pair<int[], int[]> cellBounds = GridModel.getAxisBounds(mViewObject);
            if (cellBounds != null) {
                int[] xs = cellBounds.getFirst();
                int[] ys = cellBounds.getSecond();
                Rect layoutBounds = layout.getBounds();

                // Handle "blank" grid layouts: insert a fake grid of CELL_COUNT^2 cells
                // where the user can do initial placement
                if (actualColumnCount <= 1 && actualRowCount <= 1 && mChildViews.isEmpty()) {
                    final int CELL_COUNT = 1;
                    xs = new int[CELL_COUNT + 1];
                    ys = new int[CELL_COUNT + 1];
                    int cellWidth = layoutBounds.w / CELL_COUNT;
                    int cellHeight = layoutBounds.h / CELL_COUNT;

                    for (int i = 0; i <= CELL_COUNT; i++) {
                        xs[i] = i * cellWidth;
                        ys[i] = i * cellHeight;
                    }
                }

                actualColumnCount = xs.length - 1;
                actualRowCount = ys.length - 1;

                int layoutBoundsX = layoutBounds.x;
                int layoutBoundsY = layoutBounds.y;
                mLeft = new int[xs.length];
                mTop = new int[ys.length];
                for (int i = 0; i < xs.length; i++) {
                    mLeft[i] = xs[i] + layoutBoundsX;
                }
                for (int i = 0; i < ys.length; i++) {
                    mTop[i] = ys[i] + layoutBoundsY;
                }

                return true;
            }
        }

        return false;
    }

    /**
     * Computes the boundaries of the rows and columns by considering the bounds of the
     * children.
     */
    private void assignCellBoundsFromBounds() {
        Rect layoutBounds = layout.getBounds();

        // Compute the actualColumnCount and actualRowCount. This -should- be
        // as easy as declaredColumnCount + extraColumnsMap.size(),
        // but the user doesn't *have* to declare a column count (or a row count)
        // and we need both, so go and find the actual row and column maximums.
        int maxColumn = 0;
        int maxRow = 0;
        for (ViewData view : mChildViews) {
            maxColumn = max(maxColumn, view.column);
            maxRow = max(maxRow, view.row);
        }
        actualColumnCount = maxColumn + 1;
        actualRowCount = maxRow + 1;

        mLeft = new int[actualColumnCount + 1];
        for (int i = 1; i < actualColumnCount; i++) {
            mLeft[i] = UNDEFINED;
        }
        mLeft[0] = layoutBounds.x;
        mLeft[actualColumnCount] = layoutBounds.x2();
        mTop = new int[actualRowCount + 1];
        for (int i = 1; i < actualRowCount; i++) {
            mTop[i] = UNDEFINED;
        }
        mTop[0] = layoutBounds.y;
        mTop[actualRowCount] = layoutBounds.y2();

        for (ViewData view : mChildViews) {
            Rect bounds = view.node.getBounds();
            if (!bounds.isValid()) {
                continue;
            }
            int column = view.column;
            int row = view.row;

            if (mLeft[column] == UNDEFINED) {
                mLeft[column] = bounds.x;
            } else {
                mLeft[column] = Math.min(bounds.x, mLeft[column]);
            }
            if (mTop[row] == UNDEFINED) {
                mTop[row] = bounds.y;
            } else {
                mTop[row] = Math.min(bounds.y, mTop[row]);
            }
        }

        // Ensure that any empty columns/rows have a valid boundary value; for now,
        for (int i = actualColumnCount - 1; i >= 0; i--) {
            if (mLeft[i] == UNDEFINED) {
                if (i == 0) {
                    mLeft[i] = layoutBounds.x;
                } else if (i < actualColumnCount - 1) {
                    mLeft[i] = mLeft[i + 1] - 1;
                    if (mLeft[i - 1] != UNDEFINED && mLeft[i] < mLeft[i - 1]) {
                        mLeft[i] = mLeft[i - 1];
                    }
                } else {
                    mLeft[i] = layoutBounds.x2();
                }
            }
        }
        for (int i = actualRowCount - 1; i >= 0; i--) {
            if (mTop[i] == UNDEFINED) {
                if (i == 0) {
                    mTop[i] = layoutBounds.y;
                } else if (i < actualRowCount - 1) {
                    mTop[i] = mTop[i + 1] - 1;
                    if (mTop[i - 1] != UNDEFINED && mTop[i] < mTop[i - 1]) {
                        mTop[i] = mTop[i - 1];
                    }
                } else {
                    mTop[i] = layoutBounds.y2();
                }
            }
        }

        // The bounds should be in ascending order now
        if (false && GridLayoutRule.sDebugGridLayout) {
            for (int i = 1; i < actualRowCount; i++) {
                assert mTop[i + 1] >= mTop[i];
            }
            for (int i = 0; i < actualColumnCount; i++) {
                assert mLeft[i + 1] >= mLeft[i];
            }
        }
    }

    /**
     * Determine, for each row and column, what the largest x and y edges are
     * within that row or column. This is used to find a natural split point to
     * suggest when adding something "to the right of" or "below" another view.
     */
    private void initializeMaxBounds() {
        mMaxRight = new int[actualColumnCount + 1];
        mMaxBottom = new int[actualRowCount + 1];

        for (ViewData view : mChildViews) {
            Rect bounds = view.node.getBounds();
            if (!bounds.isValid()) {
                continue;
            }

            if (!view.isSpacer()) {
                int x2 = bounds.x2();
                int y2 = bounds.y2();
                int column = view.column;
                int row = view.row;
                int targetColumn = min(actualColumnCount - 1,
                        column + view.columnSpan - 1);
                int targetRow = min(actualRowCount - 1, row + view.rowSpan - 1);
                IViewMetadata metadata = mRulesEngine.getMetadata(view.node.getFqcn());
                if (metadata != null) {
                    Margins insets = metadata.getInsets();
                    if (insets != null) {
                        x2 -= insets.right;
                        y2 -= insets.bottom;
                    }
                }
                if (mMaxRight[targetColumn] < x2
                        && ((view.gravity & (GRAVITY_CENTER_HORIZ | GRAVITY_RIGHT)) == 0)) {
                    mMaxRight[targetColumn] = x2;
                }
                if (mMaxBottom[targetRow] < y2
                        && ((view.gravity & (GRAVITY_CENTER_VERT | GRAVITY_BOTTOM)) == 0)) {
                    mMaxBottom[targetRow] = y2;
                }
            }
        }
    }

    /**
     * Looks up the x[] and y[] locations of the columns and rows in the given GridLayout
     * instance.
     *
     * @param view the GridLayout object, which should already have performed layout
     * @return a pair of x[] and y[] integer arrays, or null if it could not be found
     */
    public static Pair<int[], int[]> getAxisBounds(Object view) {
        try {
            Class<?> clz = view.getClass();
            String verticalAxisName = "verticalAxis";
            Field horizontalAxis;
            try {
                horizontalAxis = clz.getDeclaredField("horizontalAxis"); //$NON-NLS-1$
            } catch (NoSuchFieldException e) {
                // Field names changed in KitKat
                horizontalAxis = clz.getDeclaredField("mHorizontalAxis"); //$NON-NLS-1$
                verticalAxisName = "mVerticalAxis";
            }
            Field verticalAxis = clz.getDeclaredField(verticalAxisName);
            horizontalAxis.setAccessible(true);
            verticalAxis.setAccessible(true);
            Object horizontal = horizontalAxis.get(view);
            Object vertical = verticalAxis.get(view);
            Field locations = horizontal.getClass().getDeclaredField("locations"); //$NON-NLS-1$
            assert locations.getType().isArray() : locations.getType();
            locations.setAccessible(true);
            Object horizontalLocations = locations.get(horizontal);
            Object verticalLocations = locations.get(vertical);
            int[] xs = (int[]) horizontalLocations;
            int[] ys = (int[]) verticalLocations;
            return Pair.of(xs, ys);
        } catch (Throwable t) {
            // Probably trying to show a GridLayout on a platform that does not support it.
            // Return null to indicate that the grid bounds must be computed from view bounds.
            return null;
        }
    }

    /**
     * Add a new column.
     *
     * @param selectedChildren if null or empty, add the column at the end of the grid,
     *            and otherwise add it before the column of the first selected child
     * @return the newly added column spacer
     */
    public INode addColumn(List<? extends INode> selectedChildren) {
        // Determine insert index
        int newColumn = actualColumnCount;
        if (selectedChildren != null && selectedChildren.size() > 0) {
            INode first = selectedChildren.get(0);
            ViewData view = getView(first);
            newColumn = view.column;
        }

        INode newView = addColumn(newColumn, null, UNDEFINED, false, UNDEFINED, UNDEFINED);
        if (newView != null) {
            mRulesEngine.select(Collections.singletonList(newView));
        }

        return newView;
    }

    /**
     * Adds a new column.
     *
     * @param newColumn the column index to insert before
     * @param newView the {@link INode} to insert as the column spacer, which may be null
     *            (in which case a spacer is automatically created)
     * @param columnWidthDp the width, in device independent pixels, of the column to be
     *            added (which may be {@link #UNDEFINED}
     * @param split if true, split the existing column into two at the given x position
     * @param row the row to add the newView to
     * @param x the x position of the column we're inserting
     * @return the column spacer
     */
    public INode addColumn(int newColumn, INode newView, int columnWidthDp,
            boolean split, int row, int x) {
        // Insert a new column
        actualColumnCount++;
        if (declaredColumnCount != UNDEFINED) {
            declaredColumnCount++;
            setGridAttribute(layout, ATTR_COLUMN_COUNT, declaredColumnCount);
        }

        boolean isLastColumn = true;
        for (ViewData view : mChildViews) {
            if (view.column >= newColumn) {
                isLastColumn = false;
                break;
            }
        }

        for (ViewData view : mChildViews) {
            boolean columnSpanSet = false;

            int endColumn = view.column + view.columnSpan;
            if (view.column >= newColumn || endColumn == newColumn) {
                if (view.column == newColumn || endColumn == newColumn) {
                    //if (view.row == 0) {
                    if (newView == null && !isLastColumn) {
                        // Insert a new spacer
                        int index = getChildIndex(layout.getChildren(), view.node);
                        assert view.index == index; // TODO: Get rid of getter
                        if (endColumn == newColumn) {
                            // This cell -ends- at the desired position: insert it after
                            index++;
                        }

                        ViewData newViewData = addSpacer(layout, index,
                                split ? row : UNDEFINED,
                                split ? newColumn - 1 : UNDEFINED,
                                columnWidthDp != UNDEFINED ? columnWidthDp : DEFAULT_CELL_WIDTH,
                                DEFAULT_CELL_HEIGHT);
                        newViewData.column = newColumn - 1;
                        newViewData.row = row;
                        newView = newViewData.node;
                    }

                    // Set the actual row number on the first cell on the new row.
                    // This means we don't really need the spacer above to imply
                    // the new row number, but we use the spacer to assign the row
                    // some height.
                    if (view.column == newColumn) {
                        view.column++;
                        setGridAttribute(view.node, ATTR_LAYOUT_COLUMN, view.column);
                    } // else: endColumn == newColumn: handled below
                } else if (getGridAttribute(view.node, ATTR_LAYOUT_COLUMN) != null) {
                    view.column++;
                    setGridAttribute(view.node, ATTR_LAYOUT_COLUMN, view.column);
                }
            } else if (endColumn > newColumn) {
                view.columnSpan++;
                setColumnSpanAttribute(view.node, view.columnSpan);
                columnSpanSet = true;
            }

            if (split && !columnSpanSet && view.node.getBounds().x2() > x) {
                if (view.node.getBounds().x < x) {
                    view.columnSpan++;
                    setColumnSpanAttribute(view.node, view.columnSpan);
                }
            }
        }

        // Hardcode the row numbers if the last column is a new column such that
        // they don't jump back to backfill the previous row's new last cell
        if (isLastColumn) {
            for (ViewData view : mChildViews) {
                if (view.column == 0 && view.row > 0) {
                    setGridAttribute(view.node, ATTR_LAYOUT_ROW, view.row);
                }
            }
            if (split) {
                assert newView == null;
                addSpacer(layout, -1, row, newColumn -1,
                        columnWidthDp != UNDEFINED ? columnWidthDp : DEFAULT_CELL_WIDTH,
                                SPACER_SIZE_DP);
            }
        }

        return newView;
    }

    /**
     * Removes the columns containing the given selection
     *
     * @param selectedChildren a list of nodes whose columns should be deleted
     */
    public void removeColumns(List<? extends INode> selectedChildren) {
        if (selectedChildren.size() == 0) {
            return;
        }

        // Figure out which columns should be removed
        Set<Integer> removeColumns = new HashSet<Integer>();
        Set<ViewData> removedViews = new HashSet<ViewData>();
        for (INode child : selectedChildren) {
            ViewData view = getView(child);
            removedViews.add(view);
            removeColumns.add(view.column);
        }
        // Sort them in descending order such that we can process each
        // deletion independently
        List<Integer> removed = new ArrayList<Integer>(removeColumns);
        Collections.sort(removed, Collections.reverseOrder());

        for (int removedColumn : removed) {
            // Remove column.
            // First, adjust column count.
            // TODO: Don't do this if the column being deleted is outside
            // the declared column range!
            // TODO: Do this under a write lock? / editXml lock?
            actualColumnCount--;
            if (declaredColumnCount != UNDEFINED) {
                declaredColumnCount--;
            }

            // Remove any elements that begin in the deleted columns...
            // If they have colspan > 1, then we must insert a spacer instead.
            // For any other elements that overlap, we need to subtract from the span.

            for (ViewData view : mChildViews) {
                if (view.column == removedColumn) {
                    int index = getChildIndex(layout.getChildren(), view.node);
                    assert view.index == index; // TODO: Get rid of getter
                    if (view.columnSpan > 1) {
                        // Make a new spacer which is the width of the following
                        // columns
                        int columnWidth = getColumnWidth(removedColumn, view.columnSpan) -
                                getColumnWidth(removedColumn, 1);
                        int columnWidthDip = mRulesEngine.pxToDp(columnWidth);
                        ViewData spacer = addSpacer(layout, index, UNDEFINED, UNDEFINED,
                                columnWidthDip, SPACER_SIZE_DP);
                        spacer.row = 0;
                        spacer.column = removedColumn;
                    }
                    layout.removeChild(view.node);
                } else if (view.column < removedColumn
                        && view.column + view.columnSpan > removedColumn) {
                    // Subtract column span to skip this item
                    view.columnSpan--;
                    setColumnSpanAttribute(view.node, view.columnSpan);
                } else if (view.column > removedColumn) {
                    view.column--;
                    if (getGridAttribute(view.node, ATTR_LAYOUT_COLUMN) != null) {
                        setGridAttribute(view.node, ATTR_LAYOUT_COLUMN, view.column);
                    }
                }
            }
        }

        // Remove children from child list!
        if (removedViews.size() <= 2) {
            mChildViews.removeAll(removedViews);
        } else {
            List<ViewData> remaining =
                    new ArrayList<ViewData>(mChildViews.size() - removedViews.size());
            for (ViewData view : mChildViews) {
                if (!removedViews.contains(view)) {
                    remaining.add(view);
                }
            }
            mChildViews = remaining;
        }

        //if (declaredColumnCount != UNDEFINED) {
            setGridAttribute(layout, ATTR_COLUMN_COUNT, actualColumnCount);
        //}

    }

    /**
     * Add a new row.
     *
     * @param selectedChildren if null or empty, add the row at the bottom of the grid,
     *            and otherwise add it before the row of the first selected child
     * @return the newly added row spacer
     */
    public INode addRow(List<? extends INode> selectedChildren) {
        // Determine insert index
        int newRow = actualRowCount;
        if (selectedChildren.size() > 0) {
            INode first = selectedChildren.get(0);
            ViewData view = getView(first);
            newRow = view.row;
        }

        INode newView = addRow(newRow, null, UNDEFINED, false, UNDEFINED, UNDEFINED);
        if (newView != null) {
            mRulesEngine.select(Collections.singletonList(newView));
        }

        return newView;
    }

    /**
     * Adds a new column.
     *
     * @param newRow the row index to insert before
     * @param newView the {@link INode} to insert as the row spacer, which may be null (in
     *            which case a spacer is automatically created)
     * @param rowHeightDp the height, in device independent pixels, of the row to be added
     *            (which may be {@link #UNDEFINED}
     * @param split if true, split the existing row into two at the given y position
     * @param column the column to add the newView to
     * @param y the y position of the row we're inserting
     * @return the row spacer
     */
    public INode addRow(int newRow, INode newView, int rowHeightDp, boolean split,
            int column, int y) {
        actualRowCount++;
        if (declaredRowCount != UNDEFINED) {
            declaredRowCount++;
            setGridAttribute(layout, ATTR_ROW_COUNT, declaredRowCount);
        }

        boolean added = false;
        for (ViewData view : mChildViews) {
            if (view.row >= newRow) {
                // Adjust the column count
                if (view.row == newRow && view.column == 0) {
                    // Insert a new spacer
                    if (newView == null) {
                        int index = getChildIndex(layout.getChildren(), view.node);
                        assert view.index == index; // TODO: Get rid of getter
                        if (declaredColumnCount != UNDEFINED && !split) {
                            setGridAttribute(layout, ATTR_COLUMN_COUNT, declaredColumnCount);
                        }
                        ViewData newViewData = addSpacer(layout, index,
                                    split ? newRow - 1 : UNDEFINED,
                                    split ? column : UNDEFINED,
                                    SPACER_SIZE_DP,
                                    rowHeightDp != UNDEFINED ? rowHeightDp : DEFAULT_CELL_HEIGHT);
                        newViewData.column = column;
                        newViewData.row = newRow - 1;
                        newView = newViewData.node;
                    }

                    // Set the actual row number on the first cell on the new row.
                    // This means we don't really need the spacer above to imply
                    // the new row number, but we use the spacer to assign the row
                    // some height.
                    view.row++;
                    setGridAttribute(view.node, ATTR_LAYOUT_ROW, view.row);

                    added = true;
                } else if (getGridAttribute(view.node, ATTR_LAYOUT_ROW) != null) {
                    view.row++;
                    setGridAttribute(view.node, ATTR_LAYOUT_ROW, view.row);
                }
            } else {
                int endRow = view.row + view.rowSpan;
                if (endRow > newRow) {
                    view.rowSpan++;
                    setRowSpanAttribute(view.node, view.rowSpan);
                } else if (split && view.node.getBounds().y2() > y) {
                    if (view.node.getBounds().y < y) {
                        view.rowSpan++;
                        setRowSpanAttribute(view.node, view.rowSpan);
                    }
                }
            }
        }

        if (!added) {
            // Append a row at the end
            if (newView == null) {
                ViewData newViewData = addSpacer(layout, -1, UNDEFINED, UNDEFINED,
                        SPACER_SIZE_DP,
                        rowHeightDp != UNDEFINED ? rowHeightDp : DEFAULT_CELL_HEIGHT);
                newViewData.column = column;
                // TODO: MAke sure this row number is right!
                newViewData.row = split ? newRow - 1 : newRow;
                newView = newViewData.node;
            }
            if (declaredColumnCount != UNDEFINED && !split) {
                setGridAttribute(layout, ATTR_COLUMN_COUNT, declaredColumnCount);
            }
            if (split) {
                setGridAttribute(newView, ATTR_LAYOUT_ROW, newRow - 1);
                setGridAttribute(newView, ATTR_LAYOUT_COLUMN, column);
            }
        }

        return newView;
    }

    /**
     * Removes the rows containing the given selection
     *
     * @param selectedChildren a list of nodes whose rows should be deleted
     */
    public void removeRows(List<? extends INode> selectedChildren) {
        if (selectedChildren.size() == 0) {
            return;
        }

        // Figure out which rows should be removed
        Set<ViewData> removedViews = new HashSet<ViewData>();
        Set<Integer> removedRows = new HashSet<Integer>();
        for (INode child : selectedChildren) {
            ViewData view = getView(child);
            removedViews.add(view);
            removedRows.add(view.row);
        }
        // Sort them in descending order such that we can process each
        // deletion independently
        List<Integer> removed = new ArrayList<Integer>(removedRows);
        Collections.sort(removed, Collections.reverseOrder());

        for (int removedRow : removed) {
            // Remove row.
            // First, adjust row count.
            // TODO: Don't do this if the row being deleted is outside
            // the declared row range!
            actualRowCount--;
            if (declaredRowCount != UNDEFINED) {
                declaredRowCount--;
                setGridAttribute(layout, ATTR_ROW_COUNT, declaredRowCount);
            }

            // Remove any elements that begin in the deleted rows...
            // If they have colspan > 1, then we must hardcode a new row number
            // instead.
            // For any other elements that overlap, we need to subtract from the span.

            for (ViewData view : mChildViews) {
                if (view.row == removedRow) {
                    // We don't have to worry about a rowSpan > 1 here, because even
                    // if it is, those rowspans are not used to assign default row/column
                    // positions for other cells
// TODO: Check this; it differs from the removeColumns logic!
                    layout.removeChild(view.node);
                } else if (view.row > removedRow) {
                    view.row--;
                    if (getGridAttribute(view.node, ATTR_LAYOUT_ROW) != null) {
                        setGridAttribute(view.node, ATTR_LAYOUT_ROW, view.row);
                    }
                } else if (view.row < removedRow
                        && view.row + view.rowSpan > removedRow) {
                    // Subtract row span to skip this item
                    view.rowSpan--;
                    setRowSpanAttribute(view.node, view.rowSpan);
                }
            }
        }

        // Remove children from child list!
        if (removedViews.size() <= 2) {
            mChildViews.removeAll(removedViews);
        } else {
            List<ViewData> remaining =
                    new ArrayList<ViewData>(mChildViews.size() - removedViews.size());
            for (ViewData view : mChildViews) {
                if (!removedViews.contains(view)) {
                    remaining.add(view);
                }
            }
            mChildViews = remaining;
        }
    }

    /**
     * Returns the row containing the given y line
     *
     * @param y the vertical position
     * @return the row containing the given line
     */
    public int getRow(int y) {
        int row = Arrays.binarySearch(mTop, y);
        if (row == -1) {
            // Smaller than the first element; just use the first row
            return 0;
        } else if (row < 0) {
            row = -(row + 2);
        }

        return row;
    }

    /**
     * Returns the column containing the given x line
     *
     * @param x the horizontal position
     * @return the column containing the given line
     */
    public int getColumn(int x) {
        int column = Arrays.binarySearch(mLeft, x);
        if (column == -1) {
            // Smaller than the first element; just use the first column
            return 0;
        } else if (column < 0) {
            column = -(column + 2);
        }

        return column;
    }

    /**
     * Returns the closest row to the given y line. This is
     * either the row containing the line, or the row below it.
     *
     * @param y the vertical position
     * @return the closest row
     */
    public int getClosestRow(int y) {
        int row = Arrays.binarySearch(mTop, y);
        if (row == -1) {
            // Smaller than the first element; just use the first column
            return 0;
        } else if (row < 0) {
            row = -(row + 2);
        }

        if (getRowDistance(row, y) < getRowDistance(row + 1, y)) {
            return row;
        } else {
            return row + 1;
        }
    }

    /**
     * Returns the closest column to the given x line. This is
     * either the column containing the line, or the column following it.
     *
     * @param x the horizontal position
     * @return the closest column
     */
    public int getClosestColumn(int x) {
        int column = Arrays.binarySearch(mLeft, x);
        if (column == -1) {
            // Smaller than the first element; just use the first column
            return 0;
        } else if (column < 0) {
            column = -(column + 2);
        }

        if (getColumnDistance(column, x) < getColumnDistance(column + 1, x)) {
            return column;
        } else {
            return column + 1;
        }
    }

    /**
     * Returns the distance between the given x position and the beginning of the given column
     *
     * @param column the column
     * @param x the x position
     * @return the distance between the two
     */
    public int getColumnDistance(int column, int x) {
        return abs(getColumnX(column) - x);
    }

    /**
     * Returns the actual width of the given column. This returns the difference between
     * the rightmost edge of the views (not including spacers) and the left edge of the
     * column.
     *
     * @param column the column
     * @return the actual width of the non-spacer views in the column
     */
    public int getColumnActualWidth(int column) {
        return getColumnMaxX(column) - getColumnX(column);
    }

    /**
     * Returns the distance between the given y position and the top of the given row
     *
     * @param row the row
     * @param y the y position
     * @return the distance between the two
     */
    public int getRowDistance(int row, int y) {
        return abs(getRowY(row) - y);
    }

    /**
     * Returns the y position of the top of the given row
     *
     * @param row the target row
     * @return the y position of its top edge
     */
    public int getRowY(int row) {
        return mTop[min(mTop.length - 1, max(0, row))];
    }

    /**
     * Returns the bottom-most edge of any of the non-spacer children in the given row
     *
     * @param row the target row
     * @return the bottom-most edge of any of the non-spacer children in the row
     */
    public int getRowMaxY(int row) {
        return mMaxBottom[min(mMaxBottom.length - 1, max(0, row))];
    }

    /**
     * Returns the actual height of the given row. This returns the difference between
     * the bottom-most edge of the views (not including spacers) and the top edge of the
     * row.
     *
     * @param row the row
     * @return the actual height of the non-spacer views in the row
     */
    public int getRowActualHeight(int row) {
        return getRowMaxY(row) - getRowY(row);
    }

    /**
     * Returns a list of all the nodes that intersects the rows in the range
     * {@code y1 <= y <= y2}.
     *
     * @param y1 the starting y, inclusive
     * @param y2 the ending y, inclusive
     * @return a list of nodes intersecting the given rows, never null but possibly empty
     */
    public Collection<INode> getIntersectsRow(int y1, int y2) {
        List<INode> nodes = new ArrayList<INode>();

        for (ViewData view : mChildViews) {
            if (!view.isSpacer()) {
                Rect bounds = view.node.getBounds();
                if (bounds.y2() >= y1 && bounds.y <= y2) {
                    nodes.add(view.node);
                }
            }
        }

        return nodes;
    }

    /**
     * Returns the height of the given row or rows (if the rowSpan is greater than 1)
     *
     * @param row the target row
     * @param rowSpan the row span
     * @return the height in pixels of the given rows
     */
    public int getRowHeight(int row, int rowSpan) {
        return getRowY(row + rowSpan) - getRowY(row);
    }

    /**
     * Returns the x position of the left edge of the given column
     *
     * @param column the target column
     * @return the x position of its left edge
     */
    public int getColumnX(int column) {
        return mLeft[min(mLeft.length - 1, max(0, column))];
    }

    /**
     * Returns the rightmost edge of any of the non-spacer children in the given row
     *
     * @param column the target column
     * @return the rightmost edge of any of the non-spacer children in the column
     */
    public int getColumnMaxX(int column) {
        return mMaxRight[min(mMaxRight.length - 1, max(0, column))];
    }

    /**
     * Returns the width of the given column or columns (if the columnSpan is greater than 1)
     *
     * @param column the target column
     * @param columnSpan the column span
     * @return the width in pixels of the given columns
     */
    public int getColumnWidth(int column, int columnSpan) {
        return getColumnX(column + columnSpan) - getColumnX(column);
    }

    /**
     * Returns the bounds of the cell at the given row and column position, with the given
     * row and column spans.
     *
     * @param row the target row
     * @param column the target column
     * @param rowSpan the row span
     * @param columnSpan the column span
     * @return the bounds, in pixels, of the given cell
     */
    public Rect getCellBounds(int row, int column, int rowSpan, int columnSpan) {
        return new Rect(getColumnX(column), getRowY(row),
                getColumnWidth(column, columnSpan),
                getRowHeight(row, rowSpan));
    }

    /**
     * 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 = 25;

        List<List<List<ViewData>>> rowList = new ArrayList<List<List<ViewData>>>(mTop.length);
        for (int row = 0; row < mTop.length; row++) {
            List<List<ViewData>> columnList = new ArrayList<List<ViewData>>(mLeft.length);
            for (int col = 0; col < mLeft.length; col++) {
                columnList.add(new ArrayList<ViewData>(4));
            }
            rowList.add(columnList);
        }
        for (ViewData view : mChildViews) {
            for (int i = 0; i < view.rowSpan; i++) {
                if (view.row + i > mTop.length) { // Guard against bogus span values
                    break;
                }
                if (rowList.size() <= view.row + i) {
                    break;
                }
                for (int j = 0; j < view.columnSpan; j++) {
                    List<List<ViewData>> columnList = rowList.get(view.row + i);
                    if (columnList.size() <= view.column + j) {
                        break;
                    }
                    columnList.get(view.column + j).add(view);
                }
            }
        }

        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 < actualColumnCount + 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 < actualRowCount + 1; row++) {
            out.printf("%" + cellWidth + "d", mTop[row]); //$NON-NLS-1$ //$NON-NLS-2$
            if (row == actualRowCount) {
                break;
            }
            for (int col = 0; col < actualColumnCount; col++) {
                List<ViewData> views = rowList.get(row).get(col);

                StringBuilder sb = new StringBuilder();
                for (ViewData 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();
    }

    /**
     * Split a cell into two or three columns.
     *
     * @param newColumn The column number to insert before
     * @param insertMarginColumn If false, then the cell at newColumn -1 is split with the
     *            left part taking up exactly columnWidthDp dips. If true, then the column
     *            is split twice; the left part is the implicit width of the column, the
     *            new middle (margin) column is exactly the columnWidthDp size and the
     *            right column is the remaining space of the old cell.
     * @param columnWidthDp The width of the column inserted before the new column (or if
     *            insertMarginColumn is false, then the width of the margin column)
     * @param x the x coordinate of the new column
     */
    public void splitColumn(int newColumn, boolean insertMarginColumn, int columnWidthDp, int x) {
        actualColumnCount++;

        // Insert a new column
        if (declaredColumnCount != UNDEFINED) {
            declaredColumnCount++;
            if (insertMarginColumn) {
                declaredColumnCount++;
            }
            setGridAttribute(layout, ATTR_COLUMN_COUNT, declaredColumnCount);
        }

        // Are we inserting a new last column in the grid? That requires some special handling...
        boolean isLastColumn = true;
        for (ViewData view : mChildViews) {
            if (view.column >= newColumn) {
                isLastColumn = false;
                break;
            }
        }

        // Hardcode the row numbers if the last column is a new column such that
        // they don't jump back to backfill the previous row's new last cell:
        // TODO: Only do this for horizontal layouts!
        if (isLastColumn) {
            for (ViewData view : mChildViews) {
                if (view.column == 0 && view.row > 0) {
                    if (getGridAttribute(view.node, ATTR_LAYOUT_ROW) == null) {
                        setGridAttribute(view.node, ATTR_LAYOUT_ROW, view.row);
                    }
                }
            }
        }

        // Find the spacer which marks this column, and if found, mark it as a split
        ViewData prevColumnSpacer = null;
        for (ViewData view : mChildViews) {
            if (view.column == newColumn - 1 && view.isColumnSpacer()) {
                prevColumnSpacer = view;
                break;
            }
        }

        // Process all existing grid elements:
        //  * Increase column numbers for all columns that have a hardcoded column number
        //     greater than the new column
        //  * Set an explicit column=0 where needed (TODO: Implement this)
        //  * Increase the columnSpan for all columns that overlap the newly inserted column edge
        //  * Split the spacer which defined the size of this column into two
        //    (and if not found, create a new spacer)
        //
        for (ViewData view : mChildViews) {
            if (view == prevColumnSpacer) {
                continue;
            }

            INode node = view.node;
            int column = view.column;
            if (column > newColumn || (column == newColumn && view.node.getBounds().x2() > x)) {
                // ALWAYS set the column, because
                //    (1) if it has been set, it needs to be corrected
                //    (2) if it has not been set, it needs to be set to cause this column
                //        to skip over the new column (there may be no views for the new
                //        column on this row).
                //   TODO: Enhance this such that we only set the column to a skip number
                //   where necessary, e.g. only on the FIRST view on this row following the
                //   skipped column!

                //if (getGridAttribute(node, ATTR_LAYOUT_COLUMN) != null) {
                view.column += insertMarginColumn ? 2 : 1;
                setGridAttribute(node, ATTR_LAYOUT_COLUMN, view.column);
                //}
            } else if (!view.isSpacer()) {
                // Adjust the column span? We must increase it if
                //  (1) the new column is inside the range [column, column + columnSpan]
                //  (2) the new column is within the last cell in the column span,
                //      and the exact X location of the split is within the horizontal
                //      *bounds* of this node (provided it has gravity=left)
                //  (3) the new column is within the last cell and the cell has gravity
                //      right or gravity center
                int endColumn = column + view.columnSpan;
                if (endColumn > newColumn
                        || endColumn == newColumn && (view.node.getBounds().x2() > x
                                || GravityHelper.isConstrainedHorizontally(view.gravity)
                                    &&  !GravityHelper.isLeftAligned(view.gravity))) {
                    // This cell spans the new insert position, so increment the column span
                    view.columnSpan += insertMarginColumn ? 2 : 1;
                    setColumnSpanAttribute(node, view.columnSpan);
                }
            }
        }

        // Insert new spacer:
        if (prevColumnSpacer != null) {
            int px = getColumnWidth(newColumn - 1, 1);
            if (insertMarginColumn || columnWidthDp == 0) {
                px -= getColumnActualWidth(newColumn - 1);
            }
            int dp = mRulesEngine.pxToDp(px);
            int remaining = dp - columnWidthDp;
            if (remaining > 0) {
                prevColumnSpacer.node.setAttribute(ANDROID_URI, ATTR_LAYOUT_WIDTH,
                        String.format(VALUE_N_DP, remaining));
                prevColumnSpacer.column = insertMarginColumn ? newColumn + 1 : newColumn;
                setGridAttribute(prevColumnSpacer.node, ATTR_LAYOUT_COLUMN,
                        prevColumnSpacer.column);
            }
        }

        if (columnWidthDp > 0) {
            int index = prevColumnSpacer != null ? prevColumnSpacer.index : -1;

            addSpacer(layout, index, 0, insertMarginColumn ? newColumn : newColumn - 1,
                columnWidthDp, SPACER_SIZE_DP);
        }
    }

    /**
     * Split a cell into two or three rows.
     *
     * @param newRow The row number to insert before
     * @param insertMarginRow If false, then the cell at newRow -1 is split with the above
     *            part taking up exactly rowHeightDp dips. If true, then the row is split
     *            twice; the top part is the implicit height of the row, the new middle
     *            (margin) row is exactly the rowHeightDp size and the bottom column is
     *            the remaining space of the old cell.
     * @param rowHeightDp The height of the row inserted before the new row (or if
     *            insertMarginRow is false, then the height of the margin row)
     * @param y the y coordinate of the new row
     */
    public void splitRow(int newRow, boolean insertMarginRow, int rowHeightDp, int y) {
        actualRowCount++;

        // Insert a new row
        if (declaredRowCount != UNDEFINED) {
            declaredRowCount++;
            if (insertMarginRow) {
                declaredRowCount++;
            }
            setGridAttribute(layout, ATTR_ROW_COUNT, declaredRowCount);
        }

        // Find the spacer which marks this row, and if found, mark it as a split
        ViewData prevRowSpacer = null;
        for (ViewData view : mChildViews) {
            if (view.row == newRow - 1 && view.isRowSpacer()) {
                prevRowSpacer = view;
                break;
            }
        }

        // Se splitColumn() for details
        for (ViewData view : mChildViews) {
            if (view == prevRowSpacer) {
                continue;
            }

            INode node = view.node;
            int row = view.row;
            if (row > newRow || (row == newRow && view.node.getBounds().y2() > y)) {
                //if (getGridAttribute(node, ATTR_LAYOUT_ROW) != null) {
                view.row += insertMarginRow ? 2 : 1;
                setGridAttribute(node, ATTR_LAYOUT_ROW, view.row);
                //}
            } else if (!view.isSpacer()) {
                int endRow = row + view.rowSpan;
                if (endRow > newRow
                        || endRow == newRow && (view.node.getBounds().y2() > y
                                || GravityHelper.isConstrainedVertically(view.gravity)
                                    && !GravityHelper.isTopAligned(view.gravity))) {
                    // This cell spans the new insert position, so increment the row span
                    view.rowSpan += insertMarginRow ? 2 : 1;
                    setRowSpanAttribute(node, view.rowSpan);
                }
            }
        }

        // Insert new spacer:
        if (prevRowSpacer != null) {
            int px = getRowHeight(newRow - 1, 1);
            if (insertMarginRow || rowHeightDp == 0) {
                px -= getRowActualHeight(newRow - 1);
            }
            int dp = mRulesEngine.pxToDp(px);
            int remaining = dp - rowHeightDp;
            if (remaining > 0) {
                prevRowSpacer.node.setAttribute(ANDROID_URI, ATTR_LAYOUT_HEIGHT,
                        String.format(VALUE_N_DP, remaining));
                prevRowSpacer.row = insertMarginRow ? newRow + 1 : newRow;
                setGridAttribute(prevRowSpacer.node, ATTR_LAYOUT_ROW, prevRowSpacer.row);
            }
        }

        if (rowHeightDp > 0) {
            int index = prevRowSpacer != null ? prevRowSpacer.index : -1;
            addSpacer(layout, index, insertMarginRow ? newRow : newRow - 1,
                    0, SPACER_SIZE_DP, rowHeightDp);
        }
    }

    /**
     * Data about a view in a table; this is not the same as a cell because multiple views
     * can share a single cell, and a view can span many cells.
     */
    public class ViewData {
        public final INode node;
        public final int index;
        public int row;
        public int column;
        public int rowSpan;
        public int columnSpan;
        public int gravity;

        ViewData(INode n, int index) {
            node = n;
            this.index = index;

            column = getGridAttribute(n, ATTR_LAYOUT_COLUMN, UNDEFINED);
            columnSpan = getGridAttribute(n, ATTR_LAYOUT_COLUMN_SPAN, 1);
            row = getGridAttribute(n, ATTR_LAYOUT_ROW, UNDEFINED);
            rowSpan = getGridAttribute(n, ATTR_LAYOUT_ROW_SPAN, 1);
            gravity = GravityHelper.getGravity(getGridAttribute(n, ATTR_LAYOUT_GRAVITY), 0);
        }

        /** Applies the column and row fields into the XML model */
        void applyPositionAttributes() {
            setGridAttribute(node, ATTR_LAYOUT_COLUMN, column);
            setGridAttribute(node, ATTR_LAYOUT_ROW, row);
        }

        /** Returns the id of this node, or makes one up for display purposes */
        String getId() {
            String id = node.getStringAttr(ANDROID_URI, ATTR_ID);
            if (id == null) {
                id = "<unknownid>"; //$NON-NLS-1$
                String fqn = node.getFqcn();
                fqn = fqn.substring(fqn.lastIndexOf('.') + 1);
                id = fqn + "-"
                        + Integer.toString(System.identityHashCode(node)).substring(0, 3);
            }

            return id;
        }

        /** Returns true if this {@link ViewData} represents a spacer */
        boolean isSpacer() {
            return isSpace(node.getFqcn());
        }

        /**
         * Returns true if this {@link ViewData} represents a column spacer
         */
        boolean isColumnSpacer() {
            return isSpacer() &&
                // Any spacer not found in column 0 is a column spacer since we
                // place all horizontal spacers in column 0
                ((column > 0)
                // TODO: Find a cleaner way. Maybe set ids on the elements in (0,0) and
                // for column distinguish by id. Or at least only do this for column 0!
                || !SPACER_SIZE.equals(node.getStringAttr(ANDROID_URI, ATTR_LAYOUT_WIDTH)));
        }

        /**
         * Returns true if this {@link ViewData} represents a row spacer
         */
        boolean isRowSpacer() {
            return isSpacer() &&
                // Any spacer not found in row 0 is a row spacer since we
                // place all vertical spacers in row 0
                ((row > 0)
                // TODO: Find a cleaner way. Maybe set ids on the elements in (0,0) and
                // for column distinguish by id. Or at least only do this for column 0!
                || !SPACER_SIZE.equals(node.getStringAttr(ANDROID_URI, ATTR_LAYOUT_HEIGHT)));
        }
    }

    /**
     * Sets the column span of the given node to the given value (or if the value is 1,
     * removes it)
     *
     * @param node the target node
     * @param span the new column span
     */
    public void setColumnSpanAttribute(INode node, int span) {
        setGridAttribute(node, ATTR_LAYOUT_COLUMN_SPAN, span > 1 ? Integer.toString(span) : null);
    }

    /**
     * Sets the row span of the given node to the given value (or if the value is 1,
     * removes it)
     *
     * @param node the target node
     * @param span the new row span
     */
    public void setRowSpanAttribute(INode node, int span) {
        setGridAttribute(node, ATTR_LAYOUT_ROW_SPAN, span > 1 ? Integer.toString(span) : null);
    }

    /** Returns the index of the given target node in the given child node array */
    static int getChildIndex(INode[] children, INode target) {
        int index = 0;
        for (INode child : children) {
            if (child == target) {
                return index;
            }
            index++;
        }

        return -1;
    }

    /**
     * Update the model to account for the given nodes getting deleted. The nodes
     * are not actually deleted by this method; that is assumed to be performed by the
     * caller. Instead this method performs whatever model updates are necessary to
     * preserve the grid structure.
     *
     * @param nodes the nodes to be deleted
     */
    public void onDeleted(@NonNull List<INode> nodes) {
        if (nodes.size() == 0) {
            return;
        }

        // Attempt to clean up spacer objects for any newly-empty rows or columns
        // as the result of this deletion

        Set<INode> deleted = new HashSet<INode>();

        for (INode child : nodes) {
            // We don't care about deletion of spacers
            String fqcn = child.getFqcn();
            if (fqcn.equals(FQCN_SPACE) || fqcn.equals(FQCN_SPACE_V7)) {
                continue;
            }
            deleted.add(child);
        }

        Set<Integer> usedColumns = new HashSet<Integer>(actualColumnCount);
        Set<Integer> usedRows = new HashSet<Integer>(actualRowCount);
        Multimap<Integer, ViewData> columnSpacers = ArrayListMultimap.create(actualColumnCount, 2);
        Multimap<Integer, ViewData> rowSpacers = ArrayListMultimap.create(actualRowCount, 2);
        Set<ViewData> removedViews = new HashSet<ViewData>();

        for (ViewData view : mChildViews) {
            if (deleted.contains(view.node)) {
                removedViews.add(view);
            } else if (view.isColumnSpacer()) {
                columnSpacers.put(view.column, view);
            } else if (view.isRowSpacer()) {
                rowSpacers.put(view.row, view);
            } else {
                usedColumns.add(Integer.valueOf(view.column));
                usedRows.add(Integer.valueOf(view.row));
            }
        }

        if (usedColumns.size() == 0 || usedRows.size() == 0) {
            // No more views - just remove all the spacers
            for (ViewData spacer : columnSpacers.values()) {
                layout.removeChild(spacer.node);
            }
            for (ViewData spacer : rowSpacers.values()) {
                layout.removeChild(spacer.node);
            }
            mChildViews.clear();
            actualColumnCount = 0;
            declaredColumnCount = 2;
            actualRowCount = 0;
            declaredRowCount = UNDEFINED;
            setGridAttribute(layout, ATTR_COLUMN_COUNT, 2);

            return;
        }

        // Determine columns to introduce spacers into:
        // This is tricky; I should NOT combine spacers if there are cells tied to
        // individual ones

        // TODO: Invalidate column sizes too! Otherwise repeated updates might get confused!
        // Similarly, inserts need to do the same!

        // Produce map of old column numbers to new column numbers
        // Collapse regions of consecutive space and non-space ranges together
        int[] columnMap = new int[actualColumnCount + 1]; // +1: Easily handle columnSpans as well
        int newColumn = 0;
        boolean prevUsed = usedColumns.contains(0);
        for (int column = 1; column < actualColumnCount; column++) {
            boolean used = usedColumns.contains(column);
            if (used || prevUsed != used) {
                newColumn++;
                prevUsed = used;
            }
            columnMap[column] = newColumn;
        }
        newColumn++;
        columnMap[actualColumnCount] = newColumn;
        assert columnMap[0] == 0;

        int[] rowMap = new int[actualRowCount + 1]; // +1: Easily handle rowSpans as well
        int newRow = 0;
        prevUsed = usedRows.contains(0);
        for (int row = 1; row < actualRowCount; row++) {
            boolean used = usedRows.contains(row);
            if (used || prevUsed != used) {
                newRow++;
                prevUsed = used;
            }
            rowMap[row] = newRow;
        }
        newRow++;
        rowMap[actualRowCount] = newRow;
        assert rowMap[0] == 0;


        // Adjust column and row numbers to account for deletions: for a given cell, if it
        // is to the right of a deleted column, reduce its column number, and if it only
        // spans across the deleted column, reduce its column span.
        for (ViewData view : mChildViews) {
            if (removedViews.contains(view)) {
                continue;
            }
            int newColumnStart = columnMap[Math.min(columnMap.length - 1, view.column)];
            // Gracefully handle rogue/invalid columnSpans in the XML
            int newColumnEnd = columnMap[Math.min(columnMap.length - 1,
                    view.column + view.columnSpan)];
            if (newColumnStart != view.column) {
                view.column = newColumnStart;
                setGridAttribute(view.node, ATTR_LAYOUT_COLUMN, view.column);
            }

            int columnSpan = newColumnEnd - newColumnStart;
            if (columnSpan != view.columnSpan) {
                if (columnSpan >= 1) {
                    view.columnSpan = columnSpan;
                    setColumnSpanAttribute(view.node, view.columnSpan);
                } // else: merging spacing columns together
            }


            int newRowStart = rowMap[Math.min(rowMap.length - 1, view.row)];
            int newRowEnd = rowMap[Math.min(rowMap.length - 1, view.row + view.rowSpan)];
            if (newRowStart != view.row) {
                view.row = newRowStart;
                setGridAttribute(view.node, ATTR_LAYOUT_ROW, view.row);
            }

            int rowSpan = newRowEnd - newRowStart;
            if (rowSpan != view.rowSpan) {
                if (rowSpan >= 1) {
                    view.rowSpan = rowSpan;
                    setRowSpanAttribute(view.node, view.rowSpan);
                } // else: merging spacing rows together
            }
        }

        // Merge spacers (and add spacers for newly empty columns)
        int start = 0;
        while (start < actualColumnCount) {
            // Find next unused span
            while (start < actualColumnCount && usedColumns.contains(start)) {
                start++;
            }
            if (start == actualColumnCount) {
                break;
            }
            assert !usedColumns.contains(start);
            // Find the next span of unused columns and produce a SINGLE
            // spacer for that range (unless it's a zero-sized columns)
            int end = start + 1;
            for (; end < actualColumnCount; end++) {
                if (usedColumns.contains(end)) {
                    break;
                }
            }

            // Add up column sizes
            int width = getColumnWidth(start, end - start);

            // Find all spacers: the first one found should be moved to the start column
            // and assigned to the full height of the columns, and
            // the column count reduced by the corresponding amount

            // TODO: if width = 0, fully remove

            boolean isFirstSpacer = true;
            for (int column = start; column < end; column++) {
                Collection<ViewData> spacers = columnSpacers.get(column);
                if (spacers != null && !spacers.isEmpty()) {
                    // Avoid ConcurrentModificationException since we're inserting into the
                    // map within this loop (always at a different index, but the map doesn't
                    // know that)
                    spacers = new ArrayList<ViewData>(spacers);
                    for (ViewData spacer : spacers) {
                        if (isFirstSpacer) {
                            isFirstSpacer = false;
                            spacer.column = columnMap[start];
                            setGridAttribute(spacer.node, ATTR_LAYOUT_COLUMN, spacer.column);
                            if (end - start > 1) {
                                // Compute a merged width for all the spacers (not needed if
                                // there's just one spacer; it should already have the correct width)
                                int columnWidthDp = mRulesEngine.pxToDp(width);
                                spacer.node.setAttribute(ANDROID_URI, ATTR_LAYOUT_WIDTH,
                                        String.format(VALUE_N_DP, columnWidthDp));
                            }
                            columnSpacers.put(start, spacer);
                        } else {
                            removedViews.add(spacer); // Mark for model removal
                            layout.removeChild(spacer.node);
                        }
                    }
                }
            }

            if (isFirstSpacer) {
                // No spacer: create one
                int columnWidthDp = mRulesEngine.pxToDp(width);
                addSpacer(layout, -1, UNDEFINED, columnMap[start], columnWidthDp, DEFAULT_CELL_HEIGHT);
            }

            start = end;
        }
        actualColumnCount = newColumn;
//if (usedColumns.contains(newColumn)) {
//    // TODO: This may be totally wrong for right aligned content!
//    actualColumnCount++;
//}

        // Merge spacers for rows
        start = 0;
        while (start < actualRowCount) {
            // Find next unused span
            while (start < actualRowCount && usedRows.contains(start)) {
                start++;
            }
            if (start == actualRowCount) {
                break;
            }
            assert !usedRows.contains(start);
            // Find the next span of unused rows and produce a SINGLE
            // spacer for that range (unless it's a zero-sized rows)
            int end = start + 1;
            for (; end < actualRowCount; end++) {
                if (usedRows.contains(end)) {
                    break;
                }
            }

            // Add up row sizes
            int height = getRowHeight(start, end - start);

            // Find all spacers: the first one found should be moved to the start row
            // and assigned to the full height of the rows, and
            // the row count reduced by the corresponding amount

            // TODO: if width = 0, fully remove

            boolean isFirstSpacer = true;
            for (int row = start; row < end; row++) {
                Collection<ViewData> spacers = rowSpacers.get(row);
                if (spacers != null && !spacers.isEmpty()) {
                    // Avoid ConcurrentModificationException since we're inserting into the
                    // map within this loop (always at a different index, but the map doesn't
                    // know that)
                    spacers = new ArrayList<ViewData>(spacers);
                    for (ViewData spacer : spacers) {
                        if (isFirstSpacer) {
                            isFirstSpacer = false;
                            spacer.row = rowMap[start];
                            setGridAttribute(spacer.node, ATTR_LAYOUT_ROW, spacer.row);
                            if (end - start > 1) {
                                // Compute a merged width for all the spacers (not needed if
                                // there's just one spacer; it should already have the correct height)
                                int rowHeightDp = mRulesEngine.pxToDp(height);
                                spacer.node.setAttribute(ANDROID_URI, ATTR_LAYOUT_HEIGHT,
                                        String.format(VALUE_N_DP, rowHeightDp));
                            }
                            rowSpacers.put(start, spacer);
                        } else {
                            removedViews.add(spacer); // Mark for model removal
                            layout.removeChild(spacer.node);
                        }
                    }
                }
            }

            if (isFirstSpacer) {
                // No spacer: create one
                int rowWidthDp = mRulesEngine.pxToDp(height);
                addSpacer(layout, -1, rowMap[start], UNDEFINED, DEFAULT_CELL_WIDTH, rowWidthDp);
            }

            start = end;
        }
        actualRowCount = newRow;
//        if (usedRows.contains(newRow)) {
//            actualRowCount++;
//        }

        // Update the model: remove removed children from the view data list
        if (removedViews.size() <= 2) {
            mChildViews.removeAll(removedViews);
        } else {
            List<ViewData> remaining =
                    new ArrayList<ViewData>(mChildViews.size() - removedViews.size());
            for (ViewData view : mChildViews) {
                if (!removedViews.contains(view)) {
                    remaining.add(view);
                }
            }
            mChildViews = remaining;
        }

        // Update the final column and row declared attributes
        if (declaredColumnCount != UNDEFINED) {
            declaredColumnCount = actualColumnCount;
            setGridAttribute(layout, ATTR_COLUMN_COUNT, actualColumnCount);
        }
        if (declaredRowCount != UNDEFINED) {
            declaredRowCount = actualRowCount;
            setGridAttribute(layout, ATTR_ROW_COUNT, actualRowCount);
        }
    }

    /**
     * Adds a spacer to the given parent, at the given index.
     *
     * @param parent the GridLayout
     * @param index the index to insert the spacer at, or -1 to append
     * @param row the row to add the spacer to (or {@link #UNDEFINED} to not set a row yet
     * @param column the column to add the spacer to (or {@link #UNDEFINED} to not set a
     *            column yet
     * @param widthDp the width in device independent pixels to assign to the spacer
     * @param heightDp the height in device independent pixels to assign to the spacer
     * @return the newly added spacer
     */
    ViewData addSpacer(INode parent, int index, int row, int column,
            int widthDp, int heightDp) {
        INode spacer;

        String tag = FQCN_SPACE;
        String gridLayout = parent.getFqcn();
        if (!gridLayout.equals(GRID_LAYOUT) && gridLayout.length() > GRID_LAYOUT.length()) {
            String pkg = gridLayout.substring(0, gridLayout.length() - GRID_LAYOUT.length());
            tag = pkg + SPACE;
        }
        if (index != -1) {
            spacer = parent.insertChildAt(tag, index);
        } else {
            spacer = parent.appendChild(tag);
        }

        ViewData view = new ViewData(spacer, index != -1 ? index : mChildViews.size());
        mChildViews.add(view);

        if (row != UNDEFINED) {
            view.row = row;
            setGridAttribute(spacer, ATTR_LAYOUT_ROW, row);
        }
        if (column != UNDEFINED) {
            view.column = column;
            setGridAttribute(spacer, ATTR_LAYOUT_COLUMN, column);
        }
        if (widthDp > 0) {
            spacer.setAttribute(ANDROID_URI, ATTR_LAYOUT_WIDTH,
                    String.format(VALUE_N_DP, widthDp));
        }
        if (heightDp > 0) {
            spacer.setAttribute(ANDROID_URI, ATTR_LAYOUT_HEIGHT,
                    String.format(VALUE_N_DP, heightDp));
        }

        // Temporary hack
        if (GridLayoutRule.sDebugGridLayout) {
            //String id = NEW_ID_PREFIX + "s";
            //if (row == 0) {
            //    id += "c";
            //}
            //if (column == 0) {
            //    id += "r";
            //}
            //if (row > 0) {
            //    id += Integer.toString(row);
            //}
            //if (column > 0) {
            //    id += Integer.toString(column);
            //}
            String id = NEW_ID_PREFIX + "spacer_" //$NON-NLS-1$
                    + Integer.toString(System.identityHashCode(spacer)).substring(0, 3);
            spacer.setAttribute(ANDROID_URI, ATTR_ID, id);
        }


        return view;
    }

    /**
     * Returns the string value of the given attribute, or null if it does not
     * exist. This only works for attributes that are GridLayout specific, such
     * as columnCount, layout_column, layout_row_span, etc.
     *
     * @param node the target node
     * @param name the attribute name (which must be in the android: namespace)
     * @return the attribute value or null
     */

    public String getGridAttribute(INode node, String name) {
        return node.getStringAttr(getNamespace(), name);
    }

    /**
     * Returns the integer value of the given attribute, or the given defaultValue if the
     * attribute was not set. This only works for attributes that are GridLayout specific,
     * such as columnCount, layout_column, layout_row_span, etc.
     *
     * @param node the target node
     * @param attribute the attribute name (which must be in the android: namespace)
     * @param defaultValue the default value to use if the value is not set
     * @return the attribute integer value
     */
    private int getGridAttribute(INode node, String attribute, int defaultValue) {
        String valueString = node.getStringAttr(getNamespace(), attribute);
        if (valueString != null) {
            try {
                return Integer.decode(valueString);
            } catch (NumberFormatException nufe) {
                // Ignore - error in user's XML
            }
        }

        return defaultValue;
    }

    /**
     * Returns the number of children views in the GridLayout
     *
     * @return the number of children views in the GridLayout
     */
    public int getViewCount() {
        return mChildViews.size();
    }

    /**
     * Returns true if the given class name represents a spacer
     *
     * @param fqcn the fully qualified class name
     * @return true if this is a spacer
     */
    public static boolean isSpace(String fqcn) {
        return FQCN_SPACE.equals(fqcn) || FQCN_SPACE_V7.equals(fqcn);
    }
}
