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

package com.android.ide.eclipse.adt.internal.editors.layout.gre;

import static com.android.SdkConstants.ANDROID_WIDGET_PREFIX;
import static com.android.SdkConstants.VIEW_MERGE;
import static com.android.SdkConstants.VIEW_TAG;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.api.DropFeedback;
import com.android.ide.common.api.IDragElement;
import com.android.ide.common.api.IGraphics;
import com.android.ide.common.api.INode;
import com.android.ide.common.api.IViewRule;
import com.android.ide.common.api.InsertType;
import com.android.ide.common.api.Point;
import com.android.ide.common.api.Rect;
import com.android.ide.common.api.RuleAction;
import com.android.ide.common.api.SegmentType;
import com.android.ide.common.layout.ViewRule;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.GCWrapper;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SimpleElement;
import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.IAndroidTarget;

import org.eclipse.core.resources.IProject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

/**
 * The rule engine manages the layout rules and interacts with them.
 * There's one {@link RulesEngine} instance per layout editor.
 * Each instance has 2 sets of rules: the static ADT rules (shared across all instances)
 * and the project specific rules (local to the current instance / layout editor).
 */
public class RulesEngine {
    private final IProject mProject;
    private final Map<Object, IViewRule> mRulesCache = new HashMap<Object, IViewRule>();

    /**
     * The type of any upcoming node manipulations performed by the {@link IViewRule}s.
     * When actions are performed in the tool (like a paste action, or a drag from palette,
     * or a drag move within the canvas, etc), these are different types of inserts,
     * and we don't want to have the rules track them closely (and pass them back to us
     * in the {@link INode#insertChildAt} methods etc), so instead we track the state
     * here on behalf of the currently executing rule.
     */
    private InsertType mInsertType = InsertType.CREATE;

    /**
     * Per-project loader for custom view rules
     */
    private RuleLoader mRuleLoader;
    private ClassLoader mUserClassLoader;

    /**
     * The editor which owns this {@link RulesEngine}
     */
    private final GraphicalEditorPart mEditor;

    /**
     * Creates a new {@link RulesEngine} associated with the selected project.
     * <p/>
     * The rules engine will look in the project for a tools jar to load custom view rules.
     *
     * @param editor the editor which owns this {@link RulesEngine}
     * @param project A non-null open project.
     */
    public RulesEngine(GraphicalEditorPart editor, IProject project) {
        mProject = project;
        mEditor = editor;

        mRuleLoader = RuleLoader.get(project);
    }

     /**
     * Returns the {@link IProject} on which the {@link RulesEngine} was created.
     */
    public IProject getProject() {
        return mProject;
    }

    /**
     * Returns the {@link GraphicalEditorPart} for which the {@link RulesEngine} was
     * created.
     *
     * @return the associated editor
     */
    public GraphicalEditorPart getEditor() {
        return mEditor;
    }

    /**
     * Called by the owner of the {@link RulesEngine} when it is going to be disposed.
     * This frees some resources, such as the project's folder monitor.
     */
    public void dispose() {
        clearCache();
    }

    /**
     * Invokes {@link IViewRule#getDisplayName()} on the rule matching the specified element.
     *
     * @param element The view element to target. Can be null.
     * @return Null if the rule failed, there's no rule or the rule does not want to override
     *   the display name. Otherwise, a string as returned by the rule.
     */
    public String callGetDisplayName(UiViewElementNode element) {
        // try to find a rule for this element's FQCN
        IViewRule rule = loadRule(element);

        if (rule != null) {
            try {
                return rule.getDisplayName();

            } catch (Exception e) {
                AdtPlugin.log(e, "%s.getDisplayName() failed: %s",
                        rule.getClass().getSimpleName(),
                        e.toString());
            }
        }

        return null;
    }

    /**
     * Invokes {@link IViewRule#addContextMenuActions(List, INode)} on the rule matching the specified element.
     *
     * @param selectedNode The node selected. Never null.
     * @return Null if the rule failed, there's no rule or the rule does not provide
     *   any custom menu actions. Otherwise, a list of {@link RuleAction}.
     */
    @Nullable
    public List<RuleAction> callGetContextMenu(NodeProxy selectedNode) {
        // try to find a rule for this element's FQCN
        IViewRule rule = loadRule(selectedNode.getNode());

        if (rule != null) {
            try {
                mInsertType = InsertType.CREATE;
                List<RuleAction> actions = new ArrayList<RuleAction>();
                rule.addContextMenuActions(actions, selectedNode);
                Collections.sort(actions);

                return actions;
            } catch (Exception e) {
                AdtPlugin.log(e, "%s.getContextMenu() failed: %s",
                        rule.getClass().getSimpleName(),
                        e.toString());
            }
        }

        return null;
    }

    /**
     * Calls the selected node to return its default action
     *
     * @param selectedNode the node to apply the action to
     * @return the default action id
     */
    public String callGetDefaultActionId(@NonNull NodeProxy selectedNode) {
        // try to find a rule for this element's FQCN
        IViewRule rule = loadRule(selectedNode.getNode());

        if (rule != null) {
            try {
                mInsertType = InsertType.CREATE;
                return rule.getDefaultActionId(selectedNode);
            } catch (Exception e) {
                AdtPlugin.log(e, "%s.getDefaultAction() failed: %s",
                        rule.getClass().getSimpleName(),
                        e.toString());
            }
        }

        return null;
    }

    /**
     * Invokes {@link IViewRule#addLayoutActions(List, INode, List)} on the rule
     * matching the specified element.
     *
     * @param actions The list of actions to add layout actions into
     * @param parentNode The layout node
     * @param children The selected children of the node, if any (used to
     *            initialize values of child layout controls, if applicable)
     * @return Null if the rule failed, there's no rule or the rule does not
     *         provide any custom menu actions. Otherwise, a list of
     *         {@link RuleAction}.
     */
    public List<RuleAction> callAddLayoutActions(List<RuleAction> actions,
            NodeProxy parentNode, List<NodeProxy> children ) {
        // try to find a rule for this element's FQCN
        IViewRule rule = loadRule(parentNode.getNode());

        if (rule != null) {
            try {
                mInsertType = InsertType.CREATE;
                rule.addLayoutActions(actions, parentNode, children);
            } catch (Exception e) {
                AdtPlugin.log(e, "%s.getContextMenu() failed: %s",
                        rule.getClass().getSimpleName(),
                        e.toString());
            }
        }

        return null;
    }

    /**
     * Invokes {@link IViewRule#getSelectionHint(INode, INode)}
     * on the rule matching the specified element.
     *
     * @param parentNode The parent of the node selected. Never null.
     * @param childNode The child node that was selected. Never null.
     * @return a list of strings to be displayed, or null or empty to display nothing
     */
    public List<String> callGetSelectionHint(NodeProxy parentNode, NodeProxy childNode) {
        // try to find a rule for this element's FQCN
        IViewRule rule = loadRule(parentNode.getNode());

        if (rule != null) {
            try {
                return rule.getSelectionHint(parentNode, childNode);

            } catch (Exception e) {
                AdtPlugin.log(e, "%s.getSelectionHint() failed: %s",
                        rule.getClass().getSimpleName(),
                        e.toString());
            }
        }

        return null;
    }

    public void callPaintSelectionFeedback(GCWrapper gcWrapper, NodeProxy parentNode,
            List<? extends INode> childNodes, Object view) {
        // try to find a rule for this element's FQCN
        IViewRule rule = loadRule(parentNode.getNode());

        if (rule != null) {
            try {
                rule.paintSelectionFeedback(gcWrapper, parentNode, childNodes, view);

            } catch (Exception e) {
                AdtPlugin.log(e, "%s.callPaintSelectionFeedback() failed: %s",
                        rule.getClass().getSimpleName(),
                        e.toString());
            }
        }
    }

    /**
     * Called when the d'n'd starts dragging over the target node.
     * If interested, returns a DropFeedback passed to onDrop/Move/Leave/Paint.
     * If not interested in drop, return false.
     * Followed by a paint.
     */
    public DropFeedback callOnDropEnter(NodeProxy targetNode,
            Object targetView, IDragElement[] elements) {
        // try to find a rule for this element's FQCN
        IViewRule rule = loadRule(targetNode.getNode());

        if (rule != null) {
            try {
                return rule.onDropEnter(targetNode, targetView, elements);

            } catch (Exception e) {
                AdtPlugin.log(e, "%s.onDropEnter() failed: %s",
                        rule.getClass().getSimpleName(),
                        e.toString());
            }
        }

        return null;
    }

    /**
     * Called after onDropEnter.
     * Returns a DropFeedback passed to onDrop/Move/Leave/Paint (typically same
     * as input one).
     */
    public DropFeedback callOnDropMove(NodeProxy targetNode,
            IDragElement[] elements,
            DropFeedback feedback,
            Point where) {
        // try to find a rule for this element's FQCN
        IViewRule rule = loadRule(targetNode.getNode());

        if (rule != null) {
            try {
                return rule.onDropMove(targetNode, elements, feedback, where);

            } catch (Exception e) {
                AdtPlugin.log(e, "%s.onDropMove() failed: %s",
                        rule.getClass().getSimpleName(),
                        e.toString());
            }
        }

        return null;
    }

    /**
     * Called when drop leaves the target without actually dropping
     */
    public void callOnDropLeave(NodeProxy targetNode,
            IDragElement[] elements,
            DropFeedback feedback) {
        // try to find a rule for this element's FQCN
        IViewRule rule = loadRule(targetNode.getNode());

        if (rule != null) {
            try {
                rule.onDropLeave(targetNode, elements, feedback);

            } catch (Exception e) {
                AdtPlugin.log(e, "%s.onDropLeave() failed: %s",
                        rule.getClass().getSimpleName(),
                        e.toString());
            }
        }
    }

    /**
     * Called when drop is released over the target to perform the actual drop.
     */
    public void callOnDropped(NodeProxy targetNode,
            IDragElement[] elements,
            DropFeedback feedback,
            Point where,
            InsertType insertType) {
        // try to find a rule for this element's FQCN
        IViewRule rule = loadRule(targetNode.getNode());

        if (rule != null) {
            try {
                mInsertType = insertType;
                rule.onDropped(targetNode, elements, feedback, where);

            } catch (Exception e) {
                AdtPlugin.log(e, "%s.onDropped() failed: %s",
                        rule.getClass().getSimpleName(),
                        e.toString());
            }
        }
    }

    /**
     * Called when a paint has been requested via DropFeedback.
     */
    public void callDropFeedbackPaint(IGraphics gc,
            NodeProxy targetNode,
            DropFeedback feedback) {
        if (gc != null && feedback != null && feedback.painter != null) {
            try {
                feedback.painter.paint(gc, targetNode, feedback);
            } catch (Exception e) {
                AdtPlugin.log(e, "DropFeedback.painter failed: %s",
                        e.toString());
            }
        }
    }

    /**
     * Called when pasting elements in an existing document on the selected target.
     *
     * @param targetNode The first node selected.
     * @param targetView The view object for the target node, or null if not known
     * @param pastedElements The elements being pasted.
     * @return the parent node the paste was applied into
     */
    public NodeProxy callOnPaste(NodeProxy targetNode, Object targetView,
            SimpleElement[] pastedElements) {

        // Find a target which accepts children. If you for example select a button
        // and attempt to paste, this will reselect the parent of the button as the paste
        // target. (This is a loop rather than just checking the direct parent since
        // we will soon ask each child whether they are *willing* to accept the new child.
        // A ScrollView for example, which only accepts one child, might also say no
        // and delegate to its parent in turn.
        INode parent = targetNode;
        while (parent instanceof NodeProxy) {
            NodeProxy np = (NodeProxy) parent;
            if (np.getNode() != null && np.getNode().getDescriptor() != null) {
                ElementDescriptor descriptor = np.getNode().getDescriptor();
                if (descriptor.hasChildren()) {
                    targetNode = np;
                    break;
                }
            }
            parent = parent.getParent();
        }

        // try to find a rule for this element's FQCN
        IViewRule rule = loadRule(targetNode.getNode());

        if (rule != null) {
            try {
                mInsertType = InsertType.PASTE;
                rule.onPaste(targetNode, targetView, pastedElements);

            } catch (Exception e) {
                AdtPlugin.log(e, "%s.onPaste() failed: %s",
                        rule.getClass().getSimpleName(),
                        e.toString());
            }
        }

        return targetNode;
    }

    // ---- Resize operations ----

    public DropFeedback callOnResizeBegin(NodeProxy child, NodeProxy parent, Rect newBounds,
            SegmentType horizontalEdge, SegmentType verticalEdge, Object childView,
            Object parentView) {
        IViewRule rule = loadRule(parent.getNode());

        if (rule != null) {
            try {
                return rule.onResizeBegin(child, parent, horizontalEdge, verticalEdge,
                        childView, parentView);
            } catch (Exception e) {
                AdtPlugin.log(e, "%s.onResizeBegin() failed: %s", rule.getClass().getSimpleName(),
                        e.toString());
            }
        }

        return null;
    }

    public void callOnResizeUpdate(DropFeedback feedback, NodeProxy child, NodeProxy parent,
            Rect newBounds, int modifierMask) {
        IViewRule rule = loadRule(parent.getNode());

        if (rule != null) {
            try {
                rule.onResizeUpdate(feedback, child, parent, newBounds, modifierMask);
            } catch (Exception e) {
                AdtPlugin.log(e, "%s.onResizeUpdate() failed: %s", rule.getClass().getSimpleName(),
                        e.toString());
            }
        }
    }

    public void callOnResizeEnd(DropFeedback feedback, NodeProxy child, NodeProxy parent,
            Rect newBounds) {
        IViewRule rule = loadRule(parent.getNode());

        if (rule != null) {
            try {
                rule.onResizeEnd(feedback, child, parent, newBounds);
            } catch (Exception e) {
                AdtPlugin.log(e, "%s.onResizeEnd() failed: %s", rule.getClass().getSimpleName(),
                        e.toString());
            }
        }
    }

    // ---- Creation customizations ----

    /**
     * Invokes the create hooks ({@link IViewRule#onCreate},
     * {@link IViewRule#onChildInserted} when a new child has been created/pasted/moved, and
     * is inserted into a given parent. The parent may be null (for example when rendering
     * top level items for preview).
     *
     * @param editor the XML editor to apply edits to the model for (performed by view
     *            rules)
     * @param parentNode the parent XML node, or null if unknown
     * @param childNode the XML node of the new node, never null
     * @param overrideInsertType If not null, specifies an explicit insert type to use for
     *            edits made during the customization
     */
    public void callCreateHooks(
        AndroidXmlEditor editor,
        NodeProxy parentNode, NodeProxy childNode,
        InsertType overrideInsertType) {
        IViewRule parentRule = null;

        if (parentNode != null) {
            UiViewElementNode parentUiNode = parentNode.getNode();
            parentRule = loadRule(parentUiNode);
        }

        if (overrideInsertType != null) {
            mInsertType = overrideInsertType;
        }

        UiViewElementNode newUiNode = childNode.getNode();
        IViewRule childRule = loadRule(newUiNode);
        if (childRule != null || parentRule != null) {
            callCreateHooks(editor, mInsertType, parentRule, parentNode,
                    childRule, childNode);
        }
    }

    private static void callCreateHooks(
            final AndroidXmlEditor editor, final InsertType insertType,
            final IViewRule parentRule, final INode parentNode,
            final IViewRule childRule, final INode newNode) {
        // Notify the parent about the new child in case it wants to customize it
        // (For example, a ScrollView parent can go and set all its children's layout params to
        // fill the parent.)
        if (!editor.isEditXmlModelPending()) {
            editor.wrapEditXmlModel(new Runnable() {
                @Override
                public void run() {
                    callCreateHooks(editor, insertType,
                            parentRule, parentNode, childRule, newNode);
                }
            });
            return;
        }

        if (parentRule != null) {
            parentRule.onChildInserted(newNode, parentNode, insertType);
        }

        // Look up corresponding IViewRule, and notify the rule about
        // this create action in case it wants to customize the new object.
        // (For example, a rule for TabHosts can go and create a default child tab
        // when you create it.)
        if (childRule != null) {
            childRule.onCreate(newNode, parentNode, insertType);
        }

        if (parentNode != null) {
            ((NodeProxy) parentNode).applyPendingChanges();
        }
    }

    /**
     * Set the type of insert currently in progress
     *
     * @param insertType the insert type to use for the next operation
     */
    public void setInsertType(InsertType insertType) {
        mInsertType = insertType;
    }

    /**
     * Return the type of insert currently in progress
     *
     * @return the type of insert currently in progress
     */
    public InsertType getInsertType() {
        return mInsertType;
    }

    // ---- Deletion ----

    public void callOnRemovingChildren(NodeProxy parentNode,
            List<INode> children) {
        if (parentNode != null) {
            UiViewElementNode parentUiNode = parentNode.getNode();
            IViewRule parentRule = loadRule(parentUiNode);
            if (parentRule != null) {
                try {
                    parentRule.onRemovingChildren(children, parentNode,
                            mInsertType == InsertType.MOVE_WITHIN);
                } catch (Exception e) {
                    AdtPlugin.log(e, "%s.onDispose() failed: %s",
                            parentRule.getClass().getSimpleName(),
                            e.toString());
                }
            }
        }
    }

    // ---- private ---

    /**
     * Returns the descriptor for the base View class.
     * This could be null if the SDK or the given platform target hasn't loaded yet.
     */
    private ViewElementDescriptor getBaseViewDescriptor() {
        Sdk currentSdk = Sdk.getCurrent();
        if (currentSdk != null) {
            IAndroidTarget target = currentSdk.getTarget(mProject);
            if (target != null) {
                AndroidTargetData data = currentSdk.getTargetData(target);
                return data.getLayoutDescriptors().getBaseViewDescriptor();
            }
        }
        return null;
    }

    /**
     * Clear the Rules cache. Calls onDispose() on each rule.
     */
    private void clearCache() {
        // The cache can contain multiple times the same rule instance for different
        // keys (e.g. the UiViewElementNode key vs. the FQCN string key.) So transfer
        // all values to a unique set.
        HashSet<IViewRule> rules = new HashSet<IViewRule>(mRulesCache.values());

        mRulesCache.clear();

        for (IViewRule rule : rules) {
            if (rule != null) {
                try {
                    rule.onDispose();
                } catch (Exception e) {
                    AdtPlugin.log(e, "%s.onDispose() failed: %s",
                            rule.getClass().getSimpleName(),
                            e.toString());
                }
            }
        }
    }

    /**
     * Checks whether the project class loader has changed, and if so
     * unregisters any view rules that use classes from the old class loader. It
     * then returns the class loader to be used.
     */
    private ClassLoader updateClassLoader() {
        ClassLoader classLoader = mRuleLoader.getClassLoader();
        if (mUserClassLoader != null && classLoader != mUserClassLoader) {
            // We have to unload all the IViewRules from the old class
            List<Object> dispose = new ArrayList<Object>();
            for (Map.Entry<Object, IViewRule> entry : mRulesCache.entrySet()) {
                IViewRule rule = entry.getValue();
                if (rule.getClass().getClassLoader() == mUserClassLoader) {
                    dispose.add(entry.getKey());
                }
            }
            for (Object object : dispose) {
                mRulesCache.remove(object);
            }
        }

        mUserClassLoader = classLoader;
        return mUserClassLoader;
    }

    /**
     * Load a rule using its descriptor. This will try to first load the rule using its
     * actual FQCN and if that fails will find the first parent that works in the view
     * hierarchy.
     */
    private IViewRule loadRule(UiViewElementNode element) {
        if (element == null) {
            return null;
        }

        String targetFqcn = null;
        ViewElementDescriptor targetDesc = null;

        ElementDescriptor d = element.getDescriptor();
        if (d instanceof ViewElementDescriptor) {
            targetDesc = (ViewElementDescriptor) d;
        }
        if (d == null || !(d instanceof ViewElementDescriptor)) {
            // This should not happen. All views should have some kind of *view* element
            // descriptor. Maybe the project is not complete and doesn't build or something.
            // In this case, we'll use the descriptor of the base android View class.
            targetDesc = getBaseViewDescriptor();
        }

        // Check whether any of the custom view .jar files have changed and if so
        // unregister previously cached view rules to force a new view rule to be loaded.
        updateClassLoader();

        // Return the rule if we find it in the cache, even if it was stored as null
        // (which means we didn't find it earlier, so don't look for it again)
        IViewRule rule = mRulesCache.get(targetDesc);
        if (rule != null || mRulesCache.containsKey(targetDesc)) {
            return rule;
        }

        // Get the descriptor and loop through the super class hierarchy
        for (ViewElementDescriptor desc = targetDesc;
                desc != null;
                desc = desc.getSuperClassDesc()) {

            // Get the FQCN of this View
            String fqcn = desc.getFullClassName();
            if (fqcn == null) {
                // Shouldn't be happening.
                return null;
            }

            // The first time we keep the FQCN around as it's the target class we were
            // initially trying to load. After, as we move through the hierarchy, the
            // target FQCN remains constant.
            if (targetFqcn == null) {
                targetFqcn = fqcn;
            }

            if (fqcn.indexOf('.') == -1) {
                // Deal with unknown descriptors; these lack the full qualified path and
                // elements in the layout without a package are taken to be in the
                // android.widget package.
                fqcn = ANDROID_WIDGET_PREFIX + fqcn;
            }

            // Try to find a rule matching the "real" FQCN. If we find it, we're done.
            // If not, the for loop will move to the parent descriptor.
            rule = loadRule(fqcn, targetFqcn);
            if (rule != null) {
                // We found one.
                // As a side effect, loadRule() also cached the rule using the target FQCN.
                return rule;
            }
        }

        // Memorize in the cache that we couldn't find a rule for this descriptor
        mRulesCache.put(targetDesc, null);
        return null;
    }

    /**
     * Try to load a rule given a specific FQCN. This looks for an exact match in either
     * the ADT scripts or the project scripts and does not look at parent hierarchy.
     * <p/>
     * Once a rule is found (or not), it is stored in a cache using its target FQCN
     * so we don't try to reload it.
     * <p/>
     * The real FQCN is the actual rule class we're loading, e.g. "android.view.View"
     * where target FQCN is the class we were initially looking for, which might be the same as
     * the real FQCN or might be a derived class, e.g. "android.widget.TextView".
     *
     * @param realFqcn The FQCN of the rule class actually being loaded.
     * @param targetFqcn The FQCN of the class actually processed, which might be different from
     *          the FQCN of the rule being loaded.
     */
    IViewRule loadRule(String realFqcn, String targetFqcn) {
        if (realFqcn == null || targetFqcn == null) {
            return null;
        }

        // Return the rule if we find it in the cache, even if it was stored as null
        // (which means we didn't find it earlier, so don't look for it again)
        IViewRule rule = mRulesCache.get(realFqcn);
        if (rule != null || mRulesCache.containsKey(realFqcn)) {
            return rule;
        }

        // Look for class via reflection
        try {
            // For now, we package view rules for the builtin Android views and
            // widgets with the tool in a special package, so look there rather
            // than in the same package as the widgets.
            String ruleClassName;
            ClassLoader classLoader;
            if (realFqcn.startsWith("android.") || //$NON-NLS-1$
                    realFqcn.equals(VIEW_MERGE) ||
                    realFqcn.endsWith(".GridLayout") || //$NON-NLS-1$ // Temporary special case
                    // FIXME: Remove this special case as soon as we pull
                    // the MapViewRule out of this code base and bundle it
                    // with the add ons
                    realFqcn.startsWith("com.google.android.maps.")) { //$NON-NLS-1$
                // This doesn't handle a case where there are name conflicts
                // (e.g. where there are multiple different views with the same
                // class name and only differing in package names, but that's a
                // really bad practice in the first place, and if that situation
                // should come up in the API we can enhance this algorithm.
                String packageName = ViewRule.class.getName();
                packageName = packageName.substring(0, packageName.lastIndexOf('.'));
                classLoader = RulesEngine.class.getClassLoader();
                int dotIndex = realFqcn.lastIndexOf('.');
                String baseName = realFqcn.substring(dotIndex+1);
                // Capitalize rule class name to match naming conventions, if necessary (<merge>)
                if (Character.isLowerCase(baseName.charAt(0))) {
                    if (baseName.equals(VIEW_TAG)) {
                        // Hack: ViewRule is generic for the "View" class, so we can't use it
                        // for the special XML "view" tag (lowercase); instead, the rule is
                        // named "ViewTagRule" instead.
                        baseName = "ViewTag"; //$NON-NLS-1$
                    }
                    baseName = Character.toUpperCase(baseName.charAt(0)) + baseName.substring(1);
                }
                ruleClassName = packageName + "." + //$NON-NLS-1$
                    baseName + "Rule"; //$NON-NLS-1$
            } else {
                // Initialize the user-classpath for 3rd party IViewRules, if necessary
                classLoader = updateClassLoader();
                if (classLoader == null) {
                    // The mUserClassLoader can be null; this is the typical scenario,
                    // when the user is only using builtin layout rules.
                    // This means however we can't resolve this fqcn since it's not
                    // in the name space of the builtin rules.
                    mRulesCache.put(realFqcn, null);
                    return null;
                }

                // For other (3rd party) widgets, look in the same package (though most
                // likely not in the same jar!)
                ruleClassName = realFqcn + "Rule"; //$NON-NLS-1$
            }

            Class<?> clz = Class.forName(ruleClassName, true, classLoader);
            rule = (IViewRule) clz.newInstance();
            return initializeRule(rule, targetFqcn);
        } catch (ClassNotFoundException ex) {
            // Not an unexpected error - this means that there isn't a helper for this
            // class.
        } catch (InstantiationException e) {
            // This is NOT an expected error: fail.
            AdtPlugin.log(e, "load rule error (%s): %s", realFqcn, e.toString());
        } catch (IllegalAccessException e) {
            // This is NOT an expected error: fail.
            AdtPlugin.log(e, "load rule error (%s): %s", realFqcn, e.toString());
        }

        // Memorize in the cache that we couldn't find a rule for this real FQCN
        mRulesCache.put(realFqcn, null);
        return null;
    }

    /**
     * Initialize a rule we just loaded. The rule has a chance to examine the target FQCN
     * and bail out.
     * <p/>
     * Contract: the rule is not in the {@link #mRulesCache} yet and this method will
     * cache it using the target FQCN if the rule is accepted.
     * <p/>
     * The real FQCN is the actual rule class we're loading, e.g. "android.view.View"
     * where target FQCN is the class we were initially looking for, which might be the same as
     * the real FQCN or might be a derived class, e.g. "android.widget.TextView".
     *
     * @param rule A rule freshly loaded.
     * @param targetFqcn The FQCN of the class actually processed, which might be different from
     *          the FQCN of the rule being loaded.
     * @return The rule if accepted, or null if the rule can't handle that FQCN.
     */
    private IViewRule initializeRule(IViewRule rule, String targetFqcn) {

        try {
            if (rule.onInitialize(targetFqcn, new ClientRulesEngine(this, targetFqcn))) {
                // Add it to the cache and return it
                mRulesCache.put(targetFqcn, rule);
                return rule;
            } else {
                rule.onDispose();
            }
        } catch (Exception e) {
            AdtPlugin.log(e, "%s.onInit() failed: %s",
                    rule.getClass().getSimpleName(),
                    e.toString());
        }

        return null;
    }
}
