/*
 * Copyright (C) 2007 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;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.annotations.VisibleForTesting;
import com.android.annotations.VisibleForTesting.Visibility;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.XmlEditorMultiOutline;
import com.android.ide.eclipse.adt.internal.editors.common.CommonXmlDelegate;
import com.android.ide.eclipse.adt.internal.editors.common.CommonXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.IUnknownDescriptorProvider;
import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.CustomViewDescriptorService;
import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors;
import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.LayoutActionBar;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.LayoutCanvas;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.OutlinePage;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SelectionManager;
import com.android.ide.eclipse.adt.internal.editors.layout.gre.RulesEngine;
import com.android.ide.eclipse.adt.internal.editors.layout.properties.PropertySheetPage;
import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.adt.internal.lint.EclipseLintClient;
import com.android.ide.eclipse.adt.internal.lint.EclipseLintRunner;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.resources.ResourceFolderType;
import com.android.sdklib.IAndroidTarget;
import com.android.tools.lint.client.api.IssueRegistry;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IShowEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.forms.editor.IFormPage;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Multi-page form editor for /res/layout XML files.
 */
public class LayoutEditorDelegate extends CommonXmlDelegate
         implements IShowEditorInput, CommonXmlDelegate.IActionContributorDelegate {

    /** The prefix for layout folders that are not the default layout folder */
    private static final String LAYOUT_FOLDER_PREFIX = "layout-"; //$NON-NLS-1$

    public static class Creator implements IDelegateCreator {
        @Override
        @SuppressWarnings("unchecked")
        public LayoutEditorDelegate createForFile(
                @NonNull CommonXmlEditor delegator,
                @Nullable ResourceFolderType type) {
            if (ResourceFolderType.LAYOUT == type) {
                return new LayoutEditorDelegate(delegator);
            }

            return null;
        }
    }

    /**
     * Old standalone-editor ID.
     * Use {@link CommonXmlEditor#ID} instead.
     */
    public static final String LEGACY_EDITOR_ID =
        AdtConstants.EDITORS_NAMESPACE + ".layout.LayoutEditor"; //$NON-NLS-1$

    /** Root node of the UI element hierarchy */
    private UiDocumentNode mUiDocRootNode;

    private GraphicalEditorPart mGraphicalEditor;
    private int mGraphicalEditorIndex;

    /** Implementation of the {@link IContentOutlinePage} for this editor */
    private OutlinePage mLayoutOutline;

    /** The XML editor outline */
    private IContentOutlinePage mEditorOutline;

    /** Multiplexing outline, used for multi-page editors that have their own outline */
    private XmlEditorMultiOutline mMultiOutline;

    /**
     * Temporary flag set by the editor caret listener which is used to cause
     * the next getAdapter(IContentOutlinePage.class) call to return the editor
     * outline rather than the multi-outline. See the {@link #delegateGetAdapter}
     * method for details.
     */
    private boolean mCheckOutlineAdapter;

    /** Custom implementation of {@link IPropertySheetPage} for this editor */
    private IPropertySheetPage mPropertyPage;

    private final HashMap<String, ElementDescriptor> mUnknownDescriptorMap =
        new HashMap<String, ElementDescriptor>();

    private EclipseLintClient mClient;

    /**
     * Flag indicating if the replacement file is due to a config change.
     * If false, it means the new file is due to an "open action" from the user.
     */
    private boolean mNewFileOnConfigChange = false;

    /**
     * Checks whether an editor part is an instance of {@link CommonXmlEditor}
     * with an associated {@link LayoutEditorDelegate} delegate.
     *
     * @param editorPart An editor part. Can be null.
     * @return The {@link LayoutEditorDelegate} delegate associated with the editor or null.
     */
    public static @Nullable LayoutEditorDelegate fromEditor(@Nullable IEditorPart editorPart) {
        if (editorPart instanceof CommonXmlEditor) {
            CommonXmlDelegate delegate = ((CommonXmlEditor) editorPart).getDelegate();
            if (delegate instanceof LayoutEditorDelegate) {
                return ((LayoutEditorDelegate) delegate);
            }
        } else if (editorPart instanceof GraphicalEditorPart) {
            GraphicalEditorPart part = (GraphicalEditorPart) editorPart;
            return part.getEditorDelegate();
        }
        return null;
    }

    /**
     * Creates the form editor for resources XML files.
     */
    @VisibleForTesting(visibility=Visibility.PRIVATE)
    protected LayoutEditorDelegate(CommonXmlEditor editor) {
        super(editor, new LayoutContentAssist());
        // Note that LayoutEditor has its own listeners and does not
        // need to call editor.addDefaultTargetListener().
    }

    /**
     * Returns the {@link RulesEngine} associated with this editor
     *
     * @return the {@link RulesEngine} associated with this editor.
     */
    public RulesEngine getRulesEngine() {
        return mGraphicalEditor.getRulesEngine();
    }

    /**
     * Returns the {@link GraphicalEditorPart} associated with this editor
     *
     * @return the {@link GraphicalEditorPart} associated with this editor
     */
    public GraphicalEditorPart getGraphicalEditor() {
        return mGraphicalEditor;
    }

    /**
     * @return The root node of the UI element hierarchy
     */
    @Override
    public UiDocumentNode getUiRootNode() {
        return mUiDocRootNode;
    }

    public void setNewFileOnConfigChange(boolean state) {
        mNewFileOnConfigChange = state;
    }

    // ---- Base Class Overrides ----

    @Override
    public void dispose() {
        super.dispose();
        if (mGraphicalEditor != null) {
            mGraphicalEditor.dispose();
            mGraphicalEditor = null;
        }
    }

    /**
     * Save the XML.
     * <p/>
     * Clients must NOT call this directly. Instead they should always
     * call {@link CommonXmlEditor#doSave(IProgressMonitor)} so that th
     * editor super class can commit the data properly.
     * <p/>
     * Here we just need to tell the graphical editor that the model has
     * been saved.
     */
    @Override
    public void delegateDoSave(IProgressMonitor monitor) {
        super.delegateDoSave(monitor);
        if (mGraphicalEditor != null) {
            mGraphicalEditor.doSave(monitor);
        }
    }

    /**
     * Create the various form pages.
     */
    @Override
    public void delegateCreateFormPages() {
        try {
            // get the file being edited so that it can be passed to the layout editor.
            IFile editedFile = null;
            IEditorInput input = getEditor().getEditorInput();
            if (input instanceof FileEditorInput) {
                FileEditorInput fileInput = (FileEditorInput)input;
                editedFile = fileInput.getFile();
                if (!editedFile.isAccessible()) {
                    return;
                }
            } else {
                AdtPlugin.log(IStatus.ERROR,
                        "Input is not of type FileEditorInput: %1$s",  //$NON-NLS-1$
                        input.toString());
            }

            // It is possible that the Layout Editor already exits if a different version
            // of the same layout is being opened (either through "open" action from
            // the user, or through a configuration change in the configuration selector.)
            if (mGraphicalEditor == null) {

                // Instantiate GLE v2
                mGraphicalEditor = new GraphicalEditorPart(this);

                mGraphicalEditorIndex = getEditor().addPage(mGraphicalEditor,
                                                            getEditor().getEditorInput());
                getEditor().setPageText(mGraphicalEditorIndex, mGraphicalEditor.getTitle());

                mGraphicalEditor.openFile(editedFile);
            } else {
                if (mNewFileOnConfigChange) {
                    mGraphicalEditor.changeFileOnNewConfig(editedFile);
                    mNewFileOnConfigChange = false;
                } else {
                    mGraphicalEditor.replaceFile(editedFile);
                }
            }
        } catch (PartInitException e) {
            AdtPlugin.log(e, "Error creating nested page"); //$NON-NLS-1$
        }
    }

    @Override
    public void delegatePostCreatePages() {
        // Optional: set the default page. Eventually a default page might be
        // restored by selectDefaultPage() later based on the last page used by the user.
        // For example, to make the last page the default one (rather than the first page),
        // uncomment this line:
        //   setActivePage(getPageCount() - 1);
    }

    /* (non-java doc)
     * Change the tab/title name to include the name of the layout.
     */
    @Override
    public void delegateSetInput(IEditorInput input) {
        handleNewInput(input);
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.ui.part.EditorPart#setInputWithNotify(org.eclipse.ui.IEditorInput)
     */
    public void delegateSetInputWithNotify(IEditorInput input) {
        handleNewInput(input);
    }

    /**
     * Called to replace the current {@link IEditorInput} with another one.
     * <p/>
     * This is used when {@link LayoutEditorMatchingStrategy} returned
     * <code>true</code> which means we're opening a different configuration of
     * the same layout.
     */
    @Override
    public void showEditorInput(IEditorInput editorInput) {
        if (getEditor().getEditorInput().equals(editorInput)) {
            return;
        }

        // Save the current editor input. This must be called on the editor itself
        // since it's the base editor that commits pending changes.
        getEditor().doSave(new NullProgressMonitor());

        // Get the current page
        int currentPage = getEditor().getActivePage();

        // Remove the pages, except for the graphical editor, which will be dynamically adapted
        // to the new model.
        // page after the graphical editor:
        int count = getEditor().getPageCount();
        for (int i = count - 1 ; i > mGraphicalEditorIndex ; i--) {
            getEditor().removePage(i);
        }
        // Pages before the graphical editor
        for (int i = mGraphicalEditorIndex - 1 ; i >= 0 ; i--) {
            getEditor().removePage(i);
        }

        // Set the current input. We're in the delegate, the input must
        // be set into the actual editor instance.
        getEditor().setInputWithNotify(editorInput);

        // Re-create or reload the pages with the default page shown as the previous active page.
        getEditor().createAndroidPages();
        getEditor().selectDefaultPage(Integer.toString(currentPage));

        // When changing an input file of an the editor, the titlebar is not refreshed to
        // show the new path/to/file being edited. So we force a refresh
        getEditor().firePropertyChange(IWorkbenchPart.PROP_TITLE);
    }

    /** Performs a complete refresh of the XML model */
    public void refreshXmlModel() {
        Document xmlDoc = mUiDocRootNode.getXmlDocument();

        delegateInitUiRootNode(true /*force*/);
        mUiDocRootNode.loadFromXmlNode(xmlDoc);

        // Update the model first, since it is used by the viewers.
        // No need to call AndroidXmlEditor.xmlModelChanged(xmlDoc) since it's
        // a no-op. Instead call onXmlModelChanged on the graphical editor.

        if (mGraphicalEditor != null) {
            mGraphicalEditor.onXmlModelChanged();
        }
    }

    /**
     * Processes the new XML Model, which XML root node is given.
     *
     * @param xml_doc The XML document, if available, or null if none exists.
     */
    @Override
    public void delegateXmlModelChanged(Document xml_doc) {
        // init the ui root on demand
        delegateInitUiRootNode(false /*force*/);

        mUiDocRootNode.loadFromXmlNode(xml_doc);

        // Update the model first, since it is used by the viewers.
        // No need to call AndroidXmlEditor.xmlModelChanged(xmlDoc) since it's
        // a no-op. Instead call onXmlModelChanged on the graphical editor.

        if (mGraphicalEditor != null) {
            mGraphicalEditor.onXmlModelChanged();
        }
    }

    /**
     * Tells the graphical editor to recompute its layout.
     */
    public void recomputeLayout() {
        mGraphicalEditor.recomputeLayout();
    }

    /**
     * Does this editor participate in the "format GUI editor changes" option?
     *
     * @return true since this editor supports automatically formatting XML
     *         affected by GUI changes
     */
    @Override
    public boolean delegateSupportsFormatOnGuiEdit() {
        return true;
    }

    /**
     * Returns one of the issues for the given node (there could be more than one)
     *
     * @param node the node to look up lint issues for
     * @return the marker for one of the issues found for the given node
     */
    @Nullable
    public IMarker getIssueForNode(@Nullable UiViewElementNode node) {
        if (node == null) {
            return null;
        }

        if (mClient != null) {
            return mClient.getIssueForNode(node);
        }

        return null;
    }

    /**
     * Returns a collection of nodes that have one or more lint warnings
     * associated with them (retrievable via
     * {@link #getIssueForNode(UiViewElementNode)})
     *
     * @return a collection of nodes, which should <b>not</b> be modified by the
     *         caller
     */
    @Nullable
    public Collection<Node> getLintNodes() {
        if (mClient != null) {
            return mClient.getIssueNodes();
        }

        return null;
    }

    @Override
    public Job delegateRunLint() {
        // We want to customize the {@link EclipseLintClient} created to run this
        // single file lint, in particular such that we can set the mode which collects
        // nodes on that lint job, such that we can quickly look up error nodes
        //Job job = super.delegateRunLint();

        Job job = null;
        IFile file = getEditor().getInputFile();
        if (file != null) {
            IssueRegistry registry = EclipseLintClient.getRegistry();
            List<IFile> resources = Collections.singletonList(file);
            mClient = new EclipseLintClient(registry,
                    resources, getEditor().getStructuredDocument(), false /*fatal*/);

            mClient.setCollectNodes(true);

            job = EclipseLintRunner.startLint(mClient, resources, file,
                    false /*show*/);
        }

        if (job != null) {
            GraphicalEditorPart graphicalEditor = getGraphicalEditor();
            if (graphicalEditor != null) {
                job.addJobChangeListener(new LintJobListener(graphicalEditor));
            }
        }
        return job;
    }

    private class LintJobListener extends JobChangeAdapter implements Runnable {
        private final GraphicalEditorPart mEditor;
        private final LayoutCanvas mCanvas;

        LintJobListener(GraphicalEditorPart editor) {
            mEditor = editor;
            mCanvas = editor.getCanvasControl();
        }

        @Override
        public void done(IJobChangeEvent event) {
            LayoutActionBar bar = mEditor.getLayoutActionBar();
            if (!bar.isDisposed()) {
                bar.updateErrorIndicator();
            }

            // Redraw
            if (!mCanvas.isDisposed()) {
                mCanvas.getDisplay().asyncExec(this);
            }
        }

        @Override
        public void run() {
            if (!mCanvas.isDisposed()) {
                mCanvas.redraw();

                OutlinePage outlinePage = mCanvas.getOutlinePage();
                if (outlinePage != null) {
                    outlinePage.refreshIcons();
                }
            }
        }
    }

    /**
     * Returns the custom IContentOutlinePage or IPropertySheetPage when asked for it.
     */
    @Override
    public Object delegateGetAdapter(Class<?> adapter) {
        if (adapter == IContentOutlinePage.class) {
            // Somebody has requested the outline. Eclipse can only have a single outline page,
            // even for a multi-part editor:
            //       https://bugs.eclipse.org/bugs/show_bug.cgi?id=1917
            // To work around this we use PDE's workaround of having a single multiplexing
            // outline which switches its contents between the outline pages we register
            // for it, and then on page switch we notify it to update itself.

            // There is one complication: The XML editor outline listens for the editor
            // selection and uses this to automatically expand its tree children and show
            // the current node containing the caret as selected. Unfortunately, this
            // listener code contains this:
            //
            //     /* Bug 136310, unless this page is that part's
            //      * IContentOutlinePage, ignore the selection change */
            //     if (part.getAdapter(IContentOutlinePage.class) == this) {
            //
            // This means that when we return the multiplexing outline from this getAdapter
            // method, the outline no longer updates to track the selection.
            // To work around this, we use the following hack^H^H^H^H technique:
            // - Add a selection listener *before* requesting the editor outline, such
            //   that the selection listener is told about the impending selection event
            //   right before the editor outline hears about it. Set the flag
            //   mCheckOutlineAdapter to true. (We also only set it if the editor view
            //   itself is active.)
            // - In this getAdapter method, when somebody requests the IContentOutline.class,
            //   see if mCheckOutlineAdapter to see if this request is *likely* coming
            //   from the XML editor outline. If so, make sure it is by actually looking
            //   at the signature of the caller. If it's the editor outline, then return
            //   the editor outline instance itself rather than the multiplexing outline.
            if (mCheckOutlineAdapter && mEditorOutline != null) {
                mCheckOutlineAdapter = false;
                // Make *sure* this is really the editor outline calling in case
                // future versions of Eclipse changes the sequencing or dispatch of selection
                // events:
                StackTraceElement[] frames = new Throwable().fillInStackTrace().getStackTrace();
                if (frames.length > 2) {
                    StackTraceElement frame = frames[2];
                    if (frame.getClassName().equals(
                            "org.eclipse.wst.sse.ui.internal.contentoutline." + //$NON-NLS-1$
                            "ConfigurableContentOutlinePage$PostSelectionServiceListener")) { //$NON-NLS-1$
                        return mEditorOutline;
                    }
                }
            }

            // Use a multiplexing outline: workaround for
            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=1917
            if (mMultiOutline == null || mMultiOutline.isDisposed()) {
                mMultiOutline = new XmlEditorMultiOutline();
                mMultiOutline.addSelectionChangedListener(new ISelectionChangedListener() {
                    @Override
                    public void selectionChanged(SelectionChangedEvent event) {
                        ISelection selection = event.getSelection();
                        getEditor().getSite().getSelectionProvider().setSelection(selection);
                        if (getEditor().getIgnoreXmlUpdate()) {
                            return;
                        }
                        SelectionManager manager =
                                mGraphicalEditor.getCanvasControl().getSelectionManager();
                        manager.setSelection(selection);
                    }
                });
                updateOutline(getEditor().getActivePageInstance());
            }

            return mMultiOutline;
        }

        if (IPropertySheetPage.class == adapter && mGraphicalEditor != null) {
            if (mPropertyPage == null) {
                mPropertyPage = new PropertySheetPage(mGraphicalEditor);
            }

            return mPropertyPage;
        }

        // return default
        return super.delegateGetAdapter(adapter);
    }

    /**
     * Update the contents of the outline to show either the XML editor outline
     * or the layout editor graphical outline depending on which tab is visible
     */
    private void updateOutline(IFormPage page) {
        if (mMultiOutline == null) {
            return;
        }

        IContentOutlinePage outline;
        CommonXmlEditor editor = getEditor();
        if (!editor.isEditorPageActive()) {
            outline = getGraphicalOutline();
        } else {
            // Use plain XML editor outline instead
            if (mEditorOutline == null) {
                StructuredTextEditor structuredTextEditor = editor.getStructuredTextEditor();
                if (structuredTextEditor != null) {
                    IWorkbenchWindow window = editor.getSite().getWorkbenchWindow();
                    ISelectionService service = window.getSelectionService();
                    service.addPostSelectionListener(new ISelectionListener() {
                        @Override
                        public void selectionChanged(IWorkbenchPart part, ISelection selection) {
                            if (getEditor().isEditorPageActive()) {
                                mCheckOutlineAdapter = true;
                            }
                        }
                    });

                    mEditorOutline = (IContentOutlinePage) structuredTextEditor.getAdapter(
                            IContentOutlinePage.class);
                }
            }

            outline = mEditorOutline;
        }

        mMultiOutline.setPageActive(outline);
    }

    /**
     * Returns the graphical outline associated with the layout editor
     *
     * @return the outline page, never null
     */
    @NonNull
    public OutlinePage getGraphicalOutline() {
        if (mLayoutOutline == null) {
            mLayoutOutline = new OutlinePage(mGraphicalEditor);
        }

        return mLayoutOutline;
    }

    @Override
    public void delegatePageChange(int newPageIndex) {
        if (getEditor().getCurrentPage() == getEditor().getTextPageIndex() &&
                newPageIndex == mGraphicalEditorIndex) {
            // You're switching from the XML editor to the WYSIWYG editor;
            // look at the caret position and figure out which node it corresponds to
            // (if any) and if found, select the corresponding visual element.
            ISourceViewer textViewer = getEditor().getStructuredSourceViewer();
            int caretOffset = textViewer.getTextWidget().getCaretOffset();
            if (caretOffset >= 0) {
                Node node = DomUtilities.getNode(textViewer.getDocument(), caretOffset);
                if (node != null && mGraphicalEditor != null) {
                    mGraphicalEditor.select(node);
                }
            }
        }

        super.delegatePageChange(newPageIndex);

        if (mGraphicalEditor != null) {
            if (newPageIndex == mGraphicalEditorIndex) {
                mGraphicalEditor.activated();
            } else {
                mGraphicalEditor.deactivated();
            }
        }
    }

    @Override
    public int delegateGetPersistenceCategory() {
        return AndroidXmlEditor.CATEGORY_LAYOUT;
    }

    @Override
    public void delegatePostPageChange(int newPageIndex) {
        super.delegatePostPageChange(newPageIndex);

        if (mGraphicalEditor != null) {
            LayoutCanvas canvas = mGraphicalEditor.getCanvasControl();
            if (canvas != null) {
                IActionBars bars = getEditor().getEditorSite().getActionBars();
                if (bars != null) {
                    canvas.updateGlobalActions(bars);
                }
            }
        }

        IFormPage page = getEditor().getActivePageInstance();
        updateOutline(page);
    }

    @Override
    public IFormPage delegatePostSetActivePage(IFormPage superReturned, String pageIndex) {
        IFormPage page = superReturned;
        if (page != null) {
            updateOutline(page);
        }

        return page;
    }

    // ----- IActionContributorDelegate methods ----

    @Override
    public void setActiveEditor(IEditorPart part, IActionBars bars) {
        if (mGraphicalEditor != null) {
            LayoutCanvas canvas = mGraphicalEditor.getCanvasControl();
            if (canvas != null) {
                canvas.updateGlobalActions(bars);
            }
        }
    }


    @Override
    public void delegateActivated() {
        if (mGraphicalEditor != null) {
            if (getEditor().getActivePage() == mGraphicalEditorIndex) {
                mGraphicalEditor.activated();
            } else {
                mGraphicalEditor.deactivated();
            }
        }
    }

    @Override
    public void delegateDeactivated() {
        if (mGraphicalEditor != null && getEditor().getActivePage() == mGraphicalEditorIndex) {
            mGraphicalEditor.deactivated();
        }
    }

    @Override
    public String delegateGetPartName() {
        IEditorInput editorInput = getEditor().getEditorInput();
        if (!AdtPrefs.getPrefs().isSharedLayoutEditor()
              && editorInput instanceof IFileEditorInput) {
            IFileEditorInput fileInput = (IFileEditorInput) editorInput;
            IFile file = fileInput.getFile();
            IContainer parent = file.getParent();
            if (parent != null) {
                String parentName = parent.getName();
                if  (parentName.startsWith(LAYOUT_FOLDER_PREFIX)) {
                    parentName = parentName.substring(LAYOUT_FOLDER_PREFIX.length());
                    return parentName + File.separatorChar + file.getName();
                }
            }
        }

        return super.delegateGetPartName();
    }

    // ---- Local Methods ----

    /**
     * Returns true if the Graphics editor page is visible. This <b>must</b> be
     * called from the UI thread.
     */
    public boolean isGraphicalEditorActive() {
        IWorkbenchPartSite workbenchSite = getEditor().getSite();
        IWorkbenchPage workbenchPage = workbenchSite.getPage();

        // check if the editor is visible in the workbench page
        if (workbenchPage.isPartVisible(getEditor())
                && workbenchPage.getActiveEditor() == getEditor()) {
            // and then if the page of the editor is visible (not to be confused with
            // the workbench page)
            return mGraphicalEditorIndex == getEditor().getActivePage();
        }

        return false;
    }

    @Override
    public void delegateInitUiRootNode(boolean force) {
        // The root UI node is always created, even if there's no corresponding XML node.
        if (mUiDocRootNode == null || force) {
            // get the target data from the opened file (and its project)
            AndroidTargetData data = getEditor().getTargetData();

            Document doc = null;
            if (mUiDocRootNode != null) {
                doc = mUiDocRootNode.getXmlDocument();
            }

            DocumentDescriptor desc;
            if (data == null) {
                desc = new DocumentDescriptor("temp", null /*children*/);
            } else {
                desc = data.getLayoutDescriptors().getDescriptor();
            }

            // get the descriptors from the data.
            mUiDocRootNode = (UiDocumentNode) desc.createUiNode();
            super.setUiRootNode(mUiDocRootNode);
            mUiDocRootNode.setEditor(getEditor());

            mUiDocRootNode.setUnknownDescriptorProvider(new IUnknownDescriptorProvider() {
                @Override
                public ElementDescriptor getDescriptor(String xmlLocalName) {
                    ElementDescriptor unknown = mUnknownDescriptorMap.get(xmlLocalName);
                    if (unknown == null) {
                        unknown = createUnknownDescriptor(xmlLocalName);
                        mUnknownDescriptorMap.put(xmlLocalName, unknown);
                    }

                    return unknown;
                }
            });

            onDescriptorsChanged(doc);
        }
    }

    /**
     * Creates a new {@link ViewElementDescriptor} for an unknown XML local name
     * (i.e. one that was not mapped by the current descriptors).
     * <p/>
     * Since we deal with layouts, we returns either a descriptor for a custom view
     * or one for the base View.
     *
     * @param xmlLocalName The XML local name to match.
     * @return A non-null {@link ViewElementDescriptor}.
     */
    private ViewElementDescriptor createUnknownDescriptor(String xmlLocalName) {
        ViewElementDescriptor desc = null;
        IEditorInput editorInput = getEditor().getEditorInput();
        if (editorInput instanceof IFileEditorInput) {
            IFileEditorInput fileInput = (IFileEditorInput)editorInput;
            IProject project = fileInput.getFile().getProject();

            // Check if we can find a custom view specific to this project.
            // This only works if there's an actual matching custom class in the project.
            if (xmlLocalName.indexOf('.') != -1) {
                desc = CustomViewDescriptorService.getInstance().getDescriptor(project,
                        xmlLocalName);
            }

            if (desc == null) {
                // If we didn't find a custom view, create a synthetic one using the
                // the base View descriptor as a model.
                // This is a layout after all, so every XML node should represent
                // a view.

                Sdk currentSdk = Sdk.getCurrent();
                if (currentSdk != null) {
                    IAndroidTarget target = currentSdk.getTarget(project);
                    if (target != null) {
                        AndroidTargetData data = currentSdk.getTargetData(target);
                        if (data != null) {
                            // data can be null when the target is still loading
                            ViewElementDescriptor viewDesc =
                                data.getLayoutDescriptors().getBaseViewDescriptor();

                            desc = new ViewElementDescriptor(
                                    xmlLocalName, // xml local name
                                    xmlLocalName, // ui_name
                                    xmlLocalName, // canonical class name
                                    null, // tooltip
                                    null, // sdk_url
                                    viewDesc.getAttributes(),
                                    viewDesc.getLayoutAttributes(),
                                    null, // children
                                    false /* mandatory */);
                            desc.setSuperClass(viewDesc);
                        }
                    }
                }
            }
        }

        if (desc == null) {
            // We can only arrive here if the SDK's android target has not finished
            // loading. Just create a dummy descriptor with no attributes to be able
            // to continue.
            desc = new ViewElementDescriptor(xmlLocalName, xmlLocalName);
        }
        return desc;
    }

    private void onDescriptorsChanged(Document document) {

        mUnknownDescriptorMap.clear();

        if (document != null) {
            mUiDocRootNode.loadFromXmlNode(document);
        } else {
            mUiDocRootNode.reloadFromXmlNode(mUiDocRootNode.getXmlDocument());
        }

        if (mGraphicalEditor != null) {
            mGraphicalEditor.onTargetChange();
            mGraphicalEditor.reloadPalette();
            mGraphicalEditor.getCanvasControl().syncPreviewMode();
        }
    }

    /**
     * Handles a new input, and update the part name.
     * @param input the new input.
     */
    private void handleNewInput(IEditorInput input) {
        if (input instanceof FileEditorInput) {
            FileEditorInput fileInput = (FileEditorInput) input;
            IFile file = fileInput.getFile();
            getEditor().setPartName(String.format("%1$s", file.getName()));
        }
    }

    /**
     * Helper method that returns a {@link ViewElementDescriptor} for the requested FQCN.
     * Will return null if we can't find that FQCN or we lack the editor/data/descriptors info.
     */
    public ViewElementDescriptor getFqcnViewDescriptor(String fqcn) {
        ViewElementDescriptor desc = null;

        AndroidTargetData data = getEditor().getTargetData();
        if (data != null) {
            LayoutDescriptors layoutDesc = data.getLayoutDescriptors();
            if (layoutDesc != null) {
                DocumentDescriptor docDesc = layoutDesc.getDescriptor();
                if (docDesc != null) {
                    desc = internalFindFqcnViewDescriptor(fqcn, docDesc.getChildren(), null);
                }
            }
        }

        if (desc == null) {
            // We failed to find a descriptor for the given FQCN.
            // Let's consider custom classes and create one as needed.
            desc = createUnknownDescriptor(fqcn);
        }

        return desc;
    }

    /**
     * Internal helper to recursively search for a {@link ViewElementDescriptor} that matches
     * the requested FQCN.
     *
     * @param fqcn The target View FQCN to find.
     * @param descriptors A list of children descriptors to iterate through.
     * @param visited A set we use to remember which descriptors have already been visited,
     *  necessary since the view descriptor hierarchy is cyclic.
     * @return Either a matching {@link ViewElementDescriptor} or null.
     */
    private ViewElementDescriptor internalFindFqcnViewDescriptor(String fqcn,
            ElementDescriptor[] descriptors,
            Set<ElementDescriptor> visited) {
        if (visited == null) {
            visited = new HashSet<ElementDescriptor>();
        }

        if (descriptors != null) {
            for (ElementDescriptor desc : descriptors) {
                if (visited.add(desc)) {
                    // Set.add() returns true if this a new element that was added to the set.
                    // That means we haven't visited this descriptor yet.
                    // We want a ViewElementDescriptor with a matching FQCN.
                    if (desc instanceof ViewElementDescriptor &&
                            fqcn.equals(((ViewElementDescriptor) desc).getFullClassName())) {
                        return (ViewElementDescriptor) desc;
                    }

                    // Visit its children
                    ViewElementDescriptor vd =
                        internalFindFqcnViewDescriptor(fqcn, desc.getChildren(), visited);
                    if (vd != null) {
                        return vd;
                    }
                }
            }
        }

        return null;
    }
}
