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

package com.android.ide.common.layout;

import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_CLASS;
import static com.android.SdkConstants.ATTR_HINT;
import static com.android.SdkConstants.ATTR_ID;
import static com.android.SdkConstants.ATTR_LAYOUT_HEIGHT;
import static com.android.SdkConstants.ATTR_LAYOUT_RESOURCE_PREFIX;
import static com.android.SdkConstants.ATTR_LAYOUT_WIDTH;
import static com.android.SdkConstants.ATTR_STYLE;
import static com.android.SdkConstants.ATTR_TEXT;
import static com.android.SdkConstants.DOT_LAYOUT_PARAMS;
import static com.android.SdkConstants.ID_PREFIX;
import static com.android.SdkConstants.NEW_ID_PREFIX;
import static com.android.SdkConstants.VALUE_FALSE;
import static com.android.SdkConstants.VALUE_FILL_PARENT;
import static com.android.SdkConstants.VALUE_MATCH_PARENT;
import static com.android.SdkConstants.VALUE_TRUE;
import static com.android.SdkConstants.VALUE_WRAP_CONTENT;
import static com.android.SdkConstants.VIEW_FRAGMENT;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.api.AbstractViewRule;
import com.android.ide.common.api.IAttributeInfo;
import com.android.ide.common.api.IAttributeInfo.Format;
import com.android.ide.common.api.IClientRulesEngine;
import com.android.ide.common.api.IDragElement;
import com.android.ide.common.api.IMenuCallback;
import com.android.ide.common.api.INode;
import com.android.ide.common.api.IViewMetadata;
import com.android.ide.common.api.IViewRule;
import com.android.ide.common.api.RuleAction;
import com.android.ide.common.api.RuleAction.ActionProvider;
import com.android.ide.common.api.RuleAction.ChoiceProvider;
import com.android.resources.ResourceType;
import com.android.utils.Pair;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * Common IViewRule processing to all view and layout classes.
 */
public class BaseViewRule extends AbstractViewRule {
    /** List of recently edited properties */
    private static List<String> sRecent = new LinkedList<String>();

    /** Maximum number of recent properties to track and list */
    private final static int MAX_RECENT_COUNT = 12;

    // Strings used as internal ids, group ids and prefixes for actions
    private static final String FALSE_ID = "false"; //$NON-NLS-1$
    private static final String TRUE_ID = "true"; //$NON-NLS-1$
    private static final String PROP_PREFIX = "@prop@"; //$NON-NLS-1$
    private static final String CLEAR_ID = "clear"; //$NON-NLS-1$
    private static final String ZCUSTOM = "zcustom"; //$NON-NLS-1$

    protected IClientRulesEngine mRulesEngine;

    // Cache of attributes. Key is FQCN of a node mixed with its view hierarchy
    // parent. Values are a custom map as needed by getContextMenu.
    private Map<String, Map<String, Prop>> mAttributesMap =
        new HashMap<String, Map<String, Prop>>();

    @Override
    public boolean onInitialize(@NonNull String fqcn, @NonNull IClientRulesEngine engine) {
        mRulesEngine = engine;

        // This base rule can handle any class so we don't need to filter on
        // FQCN. Derived classes should do so if they can handle some
        // subclasses.

        // If onInitialize returns false, it means it can't handle the given
        // FQCN and will be unloaded.

        return true;
    }

    /**
     * Returns the {@link IClientRulesEngine} associated with this {@link IViewRule}
     *
     * @return the {@link IClientRulesEngine} associated with this {@link IViewRule}
     */
    public IClientRulesEngine getRulesEngine() {
        return mRulesEngine;
    }

    // === Context Menu ===

    /**
     * Generate custom actions for the context menu: <br/>
     * - Explicit layout_width and layout_height attributes.
     * - List of all other simple toggle attributes.
     */
    @Override
    public void addContextMenuActions(@NonNull List<RuleAction> actions,
            final @NonNull INode selectedNode) {
        String width = null;
        String currentWidth = selectedNode.getStringAttr(ANDROID_URI, ATTR_LAYOUT_WIDTH);

        String fillParent = getFillParentValueName();
        boolean canMatchParent = supportsMatchParent();
        if (canMatchParent && VALUE_FILL_PARENT.equals(currentWidth)) {
            currentWidth = VALUE_MATCH_PARENT;
        } else if (!canMatchParent && VALUE_MATCH_PARENT.equals(currentWidth)) {
            currentWidth = VALUE_FILL_PARENT;
        } else if (!VALUE_WRAP_CONTENT.equals(currentWidth) && !fillParent.equals(currentWidth)) {
            width = currentWidth;
        }

        String height = null;
        String currentHeight = selectedNode.getStringAttr(ANDROID_URI, ATTR_LAYOUT_HEIGHT);

        if (canMatchParent && VALUE_FILL_PARENT.equals(currentHeight)) {
            currentHeight = VALUE_MATCH_PARENT;
        } else if (!canMatchParent && VALUE_MATCH_PARENT.equals(currentHeight)) {
            currentHeight = VALUE_FILL_PARENT;
        } else if (!VALUE_WRAP_CONTENT.equals(currentHeight)
                && !fillParent.equals(currentHeight)) {
            height = currentHeight;
        }
        final String newWidth = width;
        final String newHeight = height;

        final IMenuCallback onChange = new IMenuCallback() {
            @Override
            public void action(
                    final @NonNull RuleAction action,
                    final @NonNull List<? extends INode> selectedNodes,
                    final @Nullable String valueId, final @Nullable Boolean newValue) {
                String fullActionId = action.getId();
                boolean isProp = fullActionId.startsWith(PROP_PREFIX);
                final String actionId = isProp ?
                        fullActionId.substring(PROP_PREFIX.length()) : fullActionId;

                if (fullActionId.equals(ATTR_LAYOUT_WIDTH)) {
                    final String newAttrValue = getValue(valueId, newWidth);
                    if (newAttrValue != null) {
                        for (INode node : selectedNodes) {
                            node.editXml("Change Attribute " + ATTR_LAYOUT_WIDTH,
                                    new PropertySettingNodeHandler(ANDROID_URI,
                                            ATTR_LAYOUT_WIDTH, newAttrValue));
                        }
                        editedProperty(ATTR_LAYOUT_WIDTH);
                    }
                    return;
                } else if (fullActionId.equals(ATTR_LAYOUT_HEIGHT)) {
                    // Ask the user
                    final String newAttrValue = getValue(valueId, newHeight);
                    if (newAttrValue != null) {
                        for (INode node : selectedNodes) {
                            node.editXml("Change Attribute " + ATTR_LAYOUT_HEIGHT,
                                    new PropertySettingNodeHandler(ANDROID_URI,
                                            ATTR_LAYOUT_HEIGHT, newAttrValue));
                        }
                        editedProperty(ATTR_LAYOUT_HEIGHT);
                    }
                    return;
                } else if (fullActionId.equals(ATTR_ID)) {
                    // Ids must be set individually so open the id dialog for each
                    // selected node (though allow cancel to break the loop)
                    for (INode node : selectedNodes) {
                        if (!mRulesEngine.rename(node)) {
                            break;
                        }
                    }
                    editedProperty(ATTR_ID);
                    return;
                } else if (isProp) {
                    INode firstNode = selectedNodes.get(0);
                    String key = getPropertyMapKey(selectedNode);
                    Map<String, Prop> props = mAttributesMap.get(key);
                    final Prop prop = (props != null) ? props.get(actionId) : null;

                    if (prop != null) {
                        editedProperty(actionId);

                        // For custom values (requiring an input dialog) input the
                        // value outside the undo-block.
                        // Input the value as a text, unless we know it's the "text" or
                        // "style" attributes (where we know we want to ask for specific
                        // resource types).
                        String uri = ANDROID_URI;
                        String v = null;
                        if (prop.isStringEdit()) {
                            boolean isStyle = actionId.equals(ATTR_STYLE);
                            boolean isText = actionId.equals(ATTR_TEXT);
                            boolean isHint = actionId.equals(ATTR_HINT);
                            if (isStyle || isText || isHint) {
                                String resourceTypeName = isStyle
                                        ? ResourceType.STYLE.getName()
                                        : ResourceType.STRING.getName();
                                String oldValue = selectedNodes.size() == 1
                                    ? (isStyle ? firstNode.getStringAttr(ATTR_STYLE, actionId)
                                            : firstNode.getStringAttr(ANDROID_URI, actionId))
                                    : ""; //$NON-NLS-1$
                                oldValue = ensureValidString(oldValue);
                                v = mRulesEngine.displayResourceInput(resourceTypeName, oldValue);
                                if (isStyle) {
                                    uri = null;
                                }
                            } else if (actionId.equals(ATTR_CLASS) && selectedNodes.size() >= 1 &&
                                    VIEW_FRAGMENT.equals(selectedNodes.get(0).getFqcn())) {
                                v = mRulesEngine.displayFragmentSourceInput();
                                uri = null;
                            } else {
                                v = inputAttributeValue(firstNode, actionId);
                            }
                        }
                        final String customValue = v;

                        for (INode n : selectedNodes) {
                            if (prop.isToggle()) {
                                // case of toggle
                                String value = "";                  //$NON-NLS-1$
                                if (valueId.equals(TRUE_ID)) {
                                    value = newValue ? "true" : ""; //$NON-NLS-1$ //$NON-NLS-2$
                                } else if (valueId.equals(FALSE_ID)) {
                                    value = newValue ? "false" : "";//$NON-NLS-1$ //$NON-NLS-2$
                                }
                                n.setAttribute(uri, actionId, value);
                            } else if (prop.isFlag()) {
                                // case of a flag
                                String values = "";                 //$NON-NLS-1$
                                if (!valueId.equals(CLEAR_ID)) {
                                    values = n.getStringAttr(ANDROID_URI, actionId);
                                    Set<String> newValues = new HashSet<String>();
                                    if (values != null) {
                                        newValues.addAll(Arrays.asList(
                                                values.split("\\|"))); //$NON-NLS-1$
                                    }
                                    if (newValue) {
                                        newValues.add(valueId);
                                    } else {
                                        newValues.remove(valueId);
                                    }

                                    List<String> sorted = new ArrayList<String>(newValues);
                                    Collections.sort(sorted);
                                    values = join('|', sorted);

                                    // Special case
                                    if (valueId.equals("normal")) { //$NON-NLS-1$
                                        // For textStyle for example, if you have "bold|italic"
                                        // and you select the "normal" property, this should
                                        // not behave in the normal flag way and "or" itself in;
                                        // it should replace the other two.
                                        // This also applies to imeOptions.
                                        values = valueId;
                                    }
                                }
                                n.setAttribute(uri, actionId, values);
                            } else if (prop.isEnum()) {
                                // case of an enum
                                String value = "";                   //$NON-NLS-1$
                                if (!valueId.equals(CLEAR_ID)) {
                                    value = newValue ? valueId : ""; //$NON-NLS-1$
                                }
                                n.setAttribute(uri, actionId, value);
                            } else {
                                assert prop.isStringEdit();
                                // We've already received the value outside the undo block
                                if (customValue != null) {
                                    n.setAttribute(uri, actionId, customValue);
                                }
                            }
                        }
                    }
                }
            }

            /**
             * Input the custom value for the given attribute. This will use the Reference
             * Chooser if it is a reference value, otherwise a plain text editor.
             */
            private String inputAttributeValue(final INode node, final String attribute) {
                String oldValue = node.getStringAttr(ANDROID_URI, attribute);
                oldValue = ensureValidString(oldValue);
                IAttributeInfo attributeInfo = node.getAttributeInfo(ANDROID_URI, attribute);
                if (attributeInfo != null
                        && attributeInfo.getFormats().contains(Format.REFERENCE)) {
                    return mRulesEngine.displayReferenceInput(oldValue);
                } else {
                    // A single resource type? If so use a resource chooser initialized
                    // to this specific type
                    /* This does not work well, because the metadata is a bit misleading:
                     * for example a Button's "text" property and a Button's "onClick" property
                     * both claim to be of type [string], but @string/ is NOT valid for
                     * onClick..
                    if (attributeInfo != null && attributeInfo.getFormats().length == 1) {
                        // Resource chooser
                        Format format = attributeInfo.getFormats()[0];
                        return mRulesEngine.displayResourceInput(format.name(), oldValue);
                    }
                    */

                    // Fallback: just edit the raw XML string
                    String message = String.format("New %1$s Value:", attribute);
                    return mRulesEngine.displayInput(message, oldValue, null);
                }
            }

            /**
             * Returns the value (which will ask the user if the value is the special
             * {@link #ZCUSTOM} marker
             */
            private String getValue(String valueId, String defaultValue) {
                if (valueId.equals(ZCUSTOM)) {
                    if (defaultValue == null) {
                        defaultValue = "";
                    }
                    String value = mRulesEngine.displayInput(
                            "Set custom layout attribute value (example: 50dp)",
                            defaultValue, null);
                    if (value != null && value.trim().length() > 0) {
                        return value.trim();
                    } else {
                        return null;
                    }
                }

                return valueId;
            }
        };

        IAttributeInfo textAttribute = selectedNode.getAttributeInfo(ANDROID_URI, ATTR_TEXT);
        if (textAttribute != null) {
            actions.add(RuleAction.createAction(PROP_PREFIX + ATTR_TEXT, "Edit Text...", onChange,
                    null, 10, true));
        }

        String editIdLabel = selectedNode.getStringAttr(ANDROID_URI, ATTR_ID) != null ?
                "Edit ID..." : "Assign ID...";
        actions.add(RuleAction.createAction(ATTR_ID, editIdLabel, onChange, null, 20, true));

        addCommonPropertyActions(actions, selectedNode, onChange, 21);

        // Create width choice submenu
        actions.add(RuleAction.createSeparator(32));
        List<Pair<String, String>> widthChoices = new ArrayList<Pair<String,String>>(4);
        widthChoices.add(Pair.of(VALUE_WRAP_CONTENT, "Wrap Content"));
        if (canMatchParent) {
            widthChoices.add(Pair.of(VALUE_MATCH_PARENT, "Match Parent"));
        } else {
            widthChoices.add(Pair.of(VALUE_FILL_PARENT, "Fill Parent"));
        }
        if (width != null) {
            widthChoices.add(Pair.of(width, width));
        }
        widthChoices.add(Pair.of(ZCUSTOM, "Other..."));
        actions.add(RuleAction.createChoices(
                ATTR_LAYOUT_WIDTH, "Layout Width",
                onChange,
                null /* iconUrls */,
                currentWidth,
                null, 35,
                true, // supportsMultipleNodes
                widthChoices));

        // Create height choice submenu
        List<Pair<String, String>> heightChoices = new ArrayList<Pair<String,String>>(4);
        heightChoices.add(Pair.of(VALUE_WRAP_CONTENT, "Wrap Content"));
        if (canMatchParent) {
            heightChoices.add(Pair.of(VALUE_MATCH_PARENT, "Match Parent"));
        } else {
            heightChoices.add(Pair.of(VALUE_FILL_PARENT, "Fill Parent"));
        }
        if (height != null) {
            heightChoices.add(Pair.of(height, height));
        }
        heightChoices.add(Pair.of(ZCUSTOM, "Other..."));
        actions.add(RuleAction.createChoices(
                ATTR_LAYOUT_HEIGHT, "Layout Height",
                onChange,
                null /* iconUrls */,
                currentHeight,
                null, 40,
                true,
                heightChoices));

        actions.add(RuleAction.createSeparator(45));
        RuleAction properties = RuleAction.createChoices("properties", "Other Properties", //$NON-NLS-1$
                onChange /*callback*/, null /*icon*/, 50,
                true /*supportsMultipleNodes*/, new ActionProvider() {
            @Override
            public @NonNull List<RuleAction> getNestedActions(@NonNull INode node) {
                List<RuleAction> propertyActionTypes = new ArrayList<RuleAction>();
                propertyActionTypes.add(RuleAction.createChoices(
                        "recent", "Recent", //$NON-NLS-1$
                        onChange /*callback*/, null /*icon*/, 10,
                        true /*supportsMultipleNodes*/, new ActionProvider() {
                            @Override
                            public @NonNull List<RuleAction> getNestedActions(@NonNull INode n) {
                                List<RuleAction> propertyActions = new ArrayList<RuleAction>();
                                addRecentPropertyActions(propertyActions, n, onChange);
                                return propertyActions;
                            }
                }));

                propertyActionTypes.add(RuleAction.createSeparator(20));

                addInheritedProperties(propertyActionTypes, node, onChange, 30);

                propertyActionTypes.add(RuleAction.createSeparator(50));
                propertyActionTypes.add(RuleAction.createChoices(
                        "layoutparams", "Layout Parameters", //$NON-NLS-1$
                        onChange /*callback*/, null /*icon*/, 60,
                        true /*supportsMultipleNodes*/, new ActionProvider() {
                            @Override
                            public @NonNull List<RuleAction> getNestedActions(@NonNull INode n) {
                                List<RuleAction> propertyActions = new ArrayList<RuleAction>();
                                addPropertyActions(propertyActions, n, onChange, null, true);
                                return propertyActions;
                            }
                }));

                propertyActionTypes.add(RuleAction.createSeparator(70));

                propertyActionTypes.add(RuleAction.createChoices(
                        "allprops", "All By Name", //$NON-NLS-1$
                        onChange /*callback*/, null /*icon*/, 80,
                        true /*supportsMultipleNodes*/, new ActionProvider() {
                            @Override
                            public @NonNull List<RuleAction> getNestedActions(@NonNull INode n) {
                                List<RuleAction> propertyActions = new ArrayList<RuleAction>();
                                addPropertyActions(propertyActions, n, onChange, null, false);
                                return propertyActions;
                            }
                }));

                return propertyActionTypes;
            }
        });

        actions.add(properties);
    }

    @Override
    @Nullable
    public String getDefaultActionId(@NonNull final INode selectedNode) {
        IAttributeInfo textAttribute = selectedNode.getAttributeInfo(ANDROID_URI, ATTR_TEXT);
        if (textAttribute != null) {
            return PROP_PREFIX + ATTR_TEXT;
        }

        return null;
    }

    private static String getPropertyMapKey(INode node) {
        // Compute the key for mAttributesMap. This depends on the type of this
        // node and its parent in the view hierarchy.
        StringBuilder sb = new StringBuilder();
        sb.append(node.getFqcn());
        sb.append('_');
        INode parent = node.getParent();
        if (parent != null) {
            sb.append(parent.getFqcn());
        }
        return sb.toString();
    }

    /**
     * Adds menu items for the inherited attributes, one pull-right menu for each super class
     * that defines attributes.
     *
     * @param propertyActionTypes the actions list to add into
     * @param node the node to apply the attributes to
     * @param onChange the callback to use for setting attributes
     * @param sortPriority the initial sort attribute for the first menu item
     */
    private void addInheritedProperties(List<RuleAction> propertyActionTypes, INode node,
            final IMenuCallback onChange, int sortPriority) {
        List<String> attributeSources = node.getAttributeSources();
        for (final String definedBy : attributeSources) {
            String sourceClass = definedBy;

            // Strip package prefixes when necessary
            int index = sourceClass.length();
            if (sourceClass.endsWith(DOT_LAYOUT_PARAMS)) {
                index = sourceClass.length() - DOT_LAYOUT_PARAMS.length() - 1;
            }
            int lastDot = sourceClass.lastIndexOf('.', index);
            if (lastDot != -1) {
                sourceClass = sourceClass.substring(lastDot + 1);
            }

            String label;
            if (definedBy.equals(node.getFqcn())) {
                label = String.format("Defined by %1$s", sourceClass);
            } else {
                label = String.format("Inherited from %1$s", sourceClass);
            }

            propertyActionTypes.add(RuleAction.createChoices("def_" + definedBy,
                    label,
                    onChange /*callback*/, null /*icon*/, sortPriority++,
                    true /*supportsMultipleNodes*/, new ActionProvider() {
                        @Override
                        public @NonNull List<RuleAction> getNestedActions(@NonNull INode n) {
                            List<RuleAction> propertyActions = new ArrayList<RuleAction>();
                            addPropertyActions(propertyActions, n, onChange, definedBy, false);
                            return propertyActions;
                        }
           }));
        }
    }

    /**
     * Creates a list of properties that are commonly edited for views of the
     * selected node's type
     */
    private void addCommonPropertyActions(List<RuleAction> actions, INode selectedNode,
            IMenuCallback onChange, int sortPriority) {
        Map<String, Prop> properties = getPropertyMetadata(selectedNode);
        IViewMetadata metadata = mRulesEngine.getMetadata(selectedNode.getFqcn());
        if (metadata != null) {
            List<String> attributes = metadata.getTopAttributes();
            if (attributes.size() > 0) {
                for (String attribute : attributes) {
                    // Text and ID are handled manually in the menu construction code because
                    // we want to place them consistently and customize the action label
                    if (ATTR_TEXT.equals(attribute) || ATTR_ID.equals(attribute)) {
                        continue;
                    }

                    Prop property = properties.get(attribute);
                    if (property != null) {
                        String title = property.getTitle();
                        if (title.endsWith("...")) {
                            title = String.format("Edit %1$s", property.getTitle());
                        }
                        actions.add(createPropertyAction(property, attribute, title,
                                selectedNode, onChange, sortPriority));
                        sortPriority++;
                    }
                }
            }
        }
    }

    /**
     * Record that the given property was just edited; adds it to the front of
     * the recently edited property list
     *
     * @param property the name of the property
     */
    static void editedProperty(String property) {
        if (sRecent.contains(property)) {
            sRecent.remove(property);
        } else if (sRecent.size() > MAX_RECENT_COUNT) {
            sRecent.remove(sRecent.size() - 1);
        }
        sRecent.add(0, property);
    }

    /**
     * Creates a list of recently modified properties that apply to the given selected node
     */
    private void addRecentPropertyActions(List<RuleAction> actions, INode selectedNode,
            IMenuCallback onChange) {
        int sortPriority = 10;
        Map<String, Prop> properties = getPropertyMetadata(selectedNode);
        for (String attribute : sRecent) {
            Prop property = properties.get(attribute);
            if (property != null) {
                actions.add(createPropertyAction(property, attribute, property.getTitle(),
                        selectedNode, onChange, sortPriority));
                sortPriority += 10;
            }
        }
    }

    /**
     * Creates a list of nested actions representing the property-setting
     * actions for the given selected node
     */
    private void addPropertyActions(List<RuleAction> actions, INode selectedNode,
            IMenuCallback onChange, String definedBy, boolean layoutParamsOnly) {

        Map<String, Prop> properties = getPropertyMetadata(selectedNode);

        int sortPriority = 10;
        for (Map.Entry<String, Prop> entry : properties.entrySet()) {
            String id = entry.getKey();
            Prop property = entry.getValue();
            if (layoutParamsOnly) {
                // If we have definedBy information, that is most accurate; all layout
                // params will be defined by a class whose name ends with
                // .LayoutParams:
                if (definedBy != null) {
                    if (!definedBy.endsWith(DOT_LAYOUT_PARAMS)) {
                        continue;
                    }
                } else if (!id.startsWith(ATTR_LAYOUT_RESOURCE_PREFIX)) {
                    continue;
                }
            }
            if (definedBy != null && !definedBy.equals(property.getDefinedBy())) {
                continue;
            }
            actions.add(createPropertyAction(property, id, property.getTitle(),
                    selectedNode, onChange, sortPriority));
            sortPriority += 10;
        }

        // The properties are coming out of map key order which isn't right, so sort
        // alphabetically instead
        Collections.sort(actions, new Comparator<RuleAction>() {
            @Override
            public int compare(RuleAction action1, RuleAction action2) {
                return action1.getTitle().compareTo(action2.getTitle());
            }
        });
    }

    private RuleAction createPropertyAction(Prop p, String id, String title, INode selectedNode,
            IMenuCallback onChange, int sortPriority) {
        if (p.isToggle()) {
            // Toggles are handled as a multiple-choice between true, false
            // and nothing (clear)
            String value = selectedNode.getStringAttr(ANDROID_URI, id);
            if (value != null) {
                value = value.toLowerCase(Locale.US);
            }
            if (VALUE_TRUE.equals(value)) {
                value = TRUE_ID;
            } else if (VALUE_FALSE.equals(value)) {
                value = FALSE_ID;
            } else {
                value = CLEAR_ID;
            }
            return RuleAction.createChoices(PROP_PREFIX + id, title,
                    onChange, BOOLEAN_CHOICE_PROVIDER,
                    value,
                    null, sortPriority,
                    true);
        } else if (p.getChoices() != null) {
            // Enum or flags. Their possible values are the multiple-choice
            // items, with an extra "clear" option to remove everything.
            String current = selectedNode.getStringAttr(ANDROID_URI, id);
            if (current == null || current.length() == 0) {
                current = CLEAR_ID;
            }
            return RuleAction.createChoices(PROP_PREFIX + id, title,
                    onChange, new EnumPropertyChoiceProvider(p),
                    current,
                    null, sortPriority,
                    true);
        } else {
            return RuleAction.createAction(
                    PROP_PREFIX + id,
                    title,
                    onChange,
                    null, sortPriority,
                    true);
        }
    }

    private Map<String, Prop> getPropertyMetadata(final INode selectedNode) {
        String key = getPropertyMapKey(selectedNode);
        Map<String, Prop> props = mAttributesMap.get(key);
        if (props == null) {
            // Prepare the property map
            props = new HashMap<String, Prop>();
            for (IAttributeInfo attrInfo : selectedNode.getDeclaredAttributes()) {
                String id = attrInfo != null ? attrInfo.getName() : null;
                if (id == null || id.equals(ATTR_LAYOUT_WIDTH) || id.equals(ATTR_LAYOUT_HEIGHT)) {
                    // Layout width/height are already handled at the root level
                    continue;
                }
                if (attrInfo == null) {
                    continue;
                }
                EnumSet<Format> formats = attrInfo.getFormats();

                String title = getAttributeDisplayName(id);

                String definedBy = attrInfo != null ? attrInfo.getDefinedBy() : null;
                if (formats.contains(IAttributeInfo.Format.BOOLEAN)) {
                    props.put(id, new Prop(title, true, definedBy));
                } else if (formats.contains(IAttributeInfo.Format.ENUM)) {
                    // Convert each enum into a map id=>title
                    Map<String, String> values = new HashMap<String, String>();
                    if (attrInfo != null) {
                        for (String e : attrInfo.getEnumValues()) {
                            values.put(e, getAttributeDisplayName(e));
                        }
                    }

                    props.put(id, new Prop(title, false, false, values, definedBy));
                } else if (formats.contains(IAttributeInfo.Format.FLAG)) {
                    // Convert each flag into a map id=>title
                    Map<String, String> values = new HashMap<String, String>();
                    if (attrInfo != null) {
                        for (String e : attrInfo.getFlagValues()) {
                            values.put(e, getAttributeDisplayName(e));
                        }
                    }

                    props.put(id, new Prop(title, false, true, values, definedBy));
                } else {
                    props.put(id, new Prop(title + "...", false, definedBy));
                }
            }
            mAttributesMap.put(key, props);
        }
        return props;
    }

    /**
     * A {@link ChoiceProvder} which provides alternatives suitable for choosing
     * values for a boolean property: true, false, or "default".
     */
    private static ChoiceProvider BOOLEAN_CHOICE_PROVIDER = new ChoiceProvider() {
        @Override
        public void addChoices(@NonNull List<String> titles, @NonNull List<URL> iconUrls,
                @NonNull List<String> ids) {
            titles.add("True");
            ids.add(TRUE_ID);

            titles.add("False");
            ids.add(FALSE_ID);

            titles.add(RuleAction.SEPARATOR);
            ids.add(RuleAction.SEPARATOR);

            titles.add("Default");
            ids.add(CLEAR_ID);
        }
    };

    /**
     * A {@link ChoiceProvider} which provides the various available
     * attribute values available for a given {@link Prop} property descriptor.
     */
    private static class EnumPropertyChoiceProvider implements ChoiceProvider {
        private Prop mProperty;

        public EnumPropertyChoiceProvider(Prop property) {
            super();
            mProperty = property;
        }

        @Override
        public void addChoices(@NonNull List<String> titles, @NonNull List<URL> iconUrls,
                @NonNull List<String> ids) {
            for (Entry<String, String> entry : mProperty.getChoices().entrySet()) {
                ids.add(entry.getKey());
                titles.add(entry.getValue());
            }

            titles.add(RuleAction.SEPARATOR);
            ids.add(RuleAction.SEPARATOR);

            titles.add("Default");
            ids.add(CLEAR_ID);
        }
    }

    /**
     * Returns true if the given node is "filled" (e.g. has layout width set to match
     * parent or fill parent
     */
    protected final boolean isFilled(INode node, String attribute) {
        String value = node.getStringAttr(ANDROID_URI, attribute);
        return VALUE_MATCH_PARENT.equals(value) || VALUE_FILL_PARENT.equals(value);
    }

    /**
     * Returns fill_parent or match_parent, depending on whether the minimum supported
     * platform supports match_parent or not
     *
     * @return match_parent or fill_parent depending on which is supported by the project
     */
    protected final String getFillParentValueName() {
        return supportsMatchParent() ? VALUE_MATCH_PARENT : VALUE_FILL_PARENT;
    }

    /**
     * Returns true if the project supports match_parent instead of just fill_parent
     *
     * @return true if the project supports match_parent instead of just fill_parent
     */
    protected final boolean supportsMatchParent() {
        // fill_parent was renamed match_parent in API level 8
        return mRulesEngine.getMinApiLevel() >= 8;
    }

    /** Join strings into a single string with the given delimiter */
    static String join(char delimiter, Collection<String> strings) {
        StringBuilder sb = new StringBuilder(100);
        for (String s : strings) {
            if (sb.length() > 0) {
                sb.append(delimiter);
            }
            sb.append(s);
        }
        return sb.toString();
    }

    static Map<String, String> concatenate(Map<String, String> pre, Map<String, String> post) {
        Map<String, String> result = new HashMap<String, String>(pre.size() + post.size());
        result.putAll(pre);
        result.putAll(post);
        return result;
    }

    // Quick utility for building up maps declaratively to minimize the diffs
    static Map<String, String> mapify(String... values) {
        Map<String, String> map = new HashMap<String, String>(values.length / 2);
        for (int i = 0; i < values.length; i += 2) {
            String key = values[i];
            if (key == null) {
                continue;
            }
            String value = values[i + 1];
            map.put(key, value);
        }

        return map;
    }

    /**
     * Produces a display name for an attribute, usually capitalizing the attribute name
     * and splitting up underscores into new words
     *
     * @param name the attribute name to convert
     * @return a display name for the attribute name
     */
    public static String getAttributeDisplayName(String name) {
        if (name != null && name.length() > 0) {
            StringBuilder sb = new StringBuilder();
            boolean capitalizeNext = true;
            for (int i = 0, n = name.length(); i < n; i++) {
                char c = name.charAt(i);
                if (capitalizeNext) {
                    c = Character.toUpperCase(c);
                }
                capitalizeNext = false;
                if (c == '_') {
                    c = ' ';
                    capitalizeNext = true;
                }
                sb.append(c);
            }

            return sb.toString();
        }

        return name;
    }


    // ==== Paste support ====

    /**
     * Most views can't accept children so there's nothing to paste on them. In
     * this case, defer the call to the parent layout and use the target node as
     * an indication of where to paste.
     */
    @Override
    public void onPaste(@NonNull INode targetNode, @Nullable Object targetView,
            @NonNull IDragElement[] elements) {
        //
        INode parent = targetNode.getParent();
        if (parent != null) {
            String parentFqcn = parent.getFqcn();
            IViewRule parentRule = mRulesEngine.loadRule(parentFqcn);

            if (parentRule instanceof BaseLayoutRule) {
                ((BaseLayoutRule) parentRule).onPasteBeforeChild(parent, targetView, targetNode,
                        elements);
            }
        }
    }

    /**
     * Support class for the context menu code. Stores state about properties in
     * the context menu.
     */
    private static class Prop {
        private final boolean mToggle;
        private final boolean mFlag;
        private final String mTitle;
        private final Map<String, String> mChoices;
        private String mDefinedBy;

        public Prop(String title, boolean isToggle, boolean isFlag, Map<String, String> choices,
                String definedBy) {
            mTitle = title;
            mToggle = isToggle;
            mFlag = isFlag;
            mChoices = choices;
            mDefinedBy = definedBy;
        }

        public String getDefinedBy() {
            return mDefinedBy;
        }

        public Prop(String title, boolean isToggle, String definedBy) {
            this(title, isToggle, false, null, definedBy);
        }

        private boolean isToggle() {
            return mToggle;
        }

        private boolean isFlag() {
            return mFlag && mChoices != null;
        }

        private boolean isEnum() {
            return !mFlag && mChoices != null;
        }

        private String getTitle() {
            return mTitle;
        }

        private Map<String, String> getChoices() {
            return mChoices;
        }

        private boolean isStringEdit() {
            return mChoices == null && !mToggle;
        }
    }

    /**
     * Returns a source attribute value which points to a sample image. This is typically
     * used to provide an initial image shown on ImageButtons, etc. There is no guarantee
     * that the source pointed to by this method actually exists.
     *
     * @return a source attribute to use for sample images, never null
     */
    protected final String getSampleImageSrc() {
        // Builtin graphics available since v1:
        return "@android:drawable/btn_star"; //$NON-NLS-1$
    }

    /**
     * Strips the {@code @+id} or {@code @id} prefix off of the given id
     *
     * @param id attribute to be stripped
     * @return the id name without the {@code @+id} or {@code @id} prefix
     */
    @NonNull
    public static String stripIdPrefix(@Nullable String id) {
        if (id == null) {
            return ""; //$NON-NLS-1$
        } else if (id.startsWith(NEW_ID_PREFIX)) {
            return id.substring(NEW_ID_PREFIX.length());
        } else if (id.startsWith(ID_PREFIX)) {
            return id.substring(ID_PREFIX.length());
        }
        return id;
    }

    private static String ensureValidString(String value) {
        if (value == null) {
            value = ""; //$NON-NLS-1$
        }
        return value;
    }
 }
