/*
 * 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.ui.tree;

import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper.ManifestSectionPart;
import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
import com.android.ide.eclipse.adt.internal.sdk.Sdk.TargetChangeListener;

import org.eclipse.core.resources.IProject;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.forms.DetailsPart;
import org.eclipse.ui.forms.IDetailsPage;
import org.eclipse.ui.forms.IDetailsPageProvider;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.MasterDetailsBlock;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;

/**
 * {@link UiTreeBlock} is a {@link MasterDetailsBlock} which displays a tree view for
 * a specific set of {@link UiElementNode}.
 * <p/>
 * For a given UI element node, the tree view displays all first-level children that
 * match a given type (given by an {@link ElementDescriptor}. All children from these
 * nodes are also displayed.
 * <p/>
 * In the middle next to the tree are some controls to add or delete tree nodes.
 * On the left is a details part that displays all the visible UI attributes for a given
 * selected UI element node.
 */
public final class UiTreeBlock extends MasterDetailsBlock implements ICommitXml {

    /** Height hint for the tree view. Helps the grid layout resize properly on smaller screens. */
    private static final int TREE_HEIGHT_HINT = 50;

    /** Container editor */
    AndroidXmlEditor mEditor;
    /** The root {@link UiElementNode} which contains all the elements that are to be
     *  manipulated by this tree view. In general this is the manifest UI node. */
    private UiElementNode mUiRootNode;
    /** The descriptor of the elements to be displayed as root in this tree view. All elements
     *  of the same type in the root will be displayed. Can be null or empty to mean everything
     *  can be displayed. */
    private ElementDescriptor[] mDescriptorFilters;
    /** The title for the master-detail part (displayed on the top "tab" on top of the tree) */
    private String mTitle;
    /** The description for the master-detail part (displayed on top of the tree view) */
    private String mDescription;
    /** The master-detail part, composed of a main tree and an auxiliary detail part */
    private ManifestSectionPart mMasterPart;
    /** The tree viewer in the master-detail part */
    private TreeViewer mTreeViewer;
    /** The "add" button for the tree view */
    private Button mAddButton;
    /** The "remove" button for the tree view */
    private Button mRemoveButton;
    /** The "up" button for the tree view */
    private Button mUpButton;
    /** The "down" button for the tree view */
    private Button mDownButton;
    /** The Managed Form used to create the master part */
    private IManagedForm mManagedForm;
    /** Reference to the details part of the tree master block. */
    private DetailsPart mDetailsPart;
    /** Reference to the clipboard for copy-paste */
    private Clipboard mClipboard;
    /** Listener to refresh the tree viewer when the parent's node has been updated */
    private IUiUpdateListener mUiRefreshListener;
    /** Listener to enable/disable the UI based on the application node's presence */
    private IUiUpdateListener mUiEnableListener;
    /** An adapter/wrapper to use the add/remove/up/down tree edit actions. */
    private UiTreeActions mUiTreeActions;
    /**
     * True if the root node can be created on-demand (i.e. as needed as
     * soon as children exist). False if an external entity controls the existence of the
     * root node. In practise, this is false for the manifest application page (the actual
     * "application" node is managed by the ApplicationToggle part) whereas it is true
     * for all other tree pages.
     */
    private final boolean mAutoCreateRoot;


    /**
     * Creates a new {@link MasterDetailsBlock} that will display all UI nodes matching the
     * given filter in the given root node.
     *
     * @param editor The parent manifest editor.
     * @param uiRootNode The root {@link UiElementNode} which contains all the elements that are
     *        to be manipulated by this tree view. In general this is the manifest UI node or the
     *        application UI node. This cannot be null.
     * @param autoCreateRoot True if the root node can be created on-demand (i.e. as needed as
     *        soon as children exist). False if an external entity controls the existence of the
     *        root node. In practise, this is false for the manifest application page (the actual
     *        "application" node is managed by the ApplicationToggle part) whereas it is true
     *        for all other tree pages.
     * @param descriptorFilters A list of descriptors of the elements to be displayed as root in
     *        this tree view. Use null or an empty list to accept any kind of node.
     * @param title Title for the section
     * @param description Description for the section
     */
    public UiTreeBlock(AndroidXmlEditor editor,
            UiElementNode uiRootNode,
            boolean autoCreateRoot,
            ElementDescriptor[] descriptorFilters,
            String title,
            String description) {
        mEditor = editor;
        mUiRootNode = uiRootNode;
        mAutoCreateRoot = autoCreateRoot;
        mDescriptorFilters = descriptorFilters;
        mTitle = title;
        mDescription = description;
    }

    /** @returns The container editor */
    AndroidXmlEditor getEditor() {
        return mEditor;
    }

    /** @returns The reference to the clipboard for copy-paste */
    Clipboard getClipboard() {
        return mClipboard;
    }

    /** @returns The master-detail part, composed of a main tree and an auxiliary detail part */
    ManifestSectionPart getMasterPart() {
        return mMasterPart;
    }

    /**
     * Returns the {@link UiElementNode} for the current model.
     * <p/>
     * This is used by the content provider attached to {@link #mTreeViewer} since
     * the uiRootNode changes after each call to
     * {@link #changeRootAndDescriptors(UiElementNode, ElementDescriptor[], boolean)}.
     */
    public UiElementNode getRootNode() {
        return mUiRootNode;
    }

    @Override
    protected void createMasterPart(final IManagedForm managedForm, Composite parent) {
        FormToolkit toolkit = managedForm.getToolkit();

        mManagedForm = managedForm;
        mMasterPart = new ManifestSectionPart(parent, toolkit);
        Section section = mMasterPart.getSection();
        section.setText(mTitle);
        section.setDescription(mDescription);
        section.setLayout(new GridLayout());
        section.setLayoutData(new GridData(GridData.FILL_BOTH));

        Composite grid = SectionHelper.createGridLayout(section, toolkit, 2);

        Tree tree = createTreeViewer(toolkit, grid, managedForm);
        createButtons(toolkit, grid);
        createTreeContextMenu(tree);
        createSectionActions(section, toolkit);
    }

    private void createSectionActions(Section section, FormToolkit toolkit) {
        ToolBarManager manager = new ToolBarManager(SWT.FLAT);
        manager.removeAll();

        ToolBar toolbar = manager.createControl(section);
        section.setTextClient(toolbar);

        ElementDescriptor[] descs = mDescriptorFilters;
        if (descs == null && mUiRootNode != null) {
            descs = mUiRootNode.getDescriptor().getChildren();
        }

        if (descs != null && descs.length > 1) {
            for (ElementDescriptor desc : descs) {
                manager.add(new DescriptorFilterAction(desc));
            }
        }

        manager.add(new TreeSortAction());

        manager.update(true /*force*/);
    }

    /**
     * Creates the tree and its viewer
     * @return The tree control
     */
    private Tree createTreeViewer(FormToolkit toolkit, Composite grid,
            final IManagedForm managedForm) {
        // Note: we *could* use a FilteredTree instead of the Tree+TreeViewer here.
        // However the class must be adapted to create an adapted toolkit tree.
        final Tree tree = toolkit.createTree(grid, SWT.MULTI);
        GridData gd = new GridData(GridData.FILL_BOTH);
        gd.widthHint = AndroidXmlEditor.TEXT_WIDTH_HINT;
        gd.heightHint = TREE_HEIGHT_HINT;
        tree.setLayoutData(gd);

        mTreeViewer = new TreeViewer(tree);
        mTreeViewer.setContentProvider(new UiModelTreeContentProvider(mUiRootNode, mDescriptorFilters));
        mTreeViewer.setLabelProvider(new UiModelTreeLabelProvider());
        mTreeViewer.setInput("unused"); //$NON-NLS-1$

        // Create a listener that reacts to selections on the tree viewer.
        // When a selection is made, ask the managed form to propagate an event to
        // all parts in the managed form.
        // This is picked up by UiElementDetail.selectionChanged().
        mTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                managedForm.fireSelectionChanged(mMasterPart, event.getSelection());
                adjustTreeButtons(event.getSelection());
            }
        });

        // Create three listeners:
        // - One to refresh the tree viewer when the parent's node has been updated
        // - One to refresh the tree viewer when the framework resources have changed
        // - One to enable/disable the UI based on the application node's presence.
        mUiRefreshListener = new IUiUpdateListener() {
            @Override
            public void uiElementNodeUpdated(UiElementNode ui_node, UiUpdateState state) {
                mTreeViewer.refresh();
            }
        };

        mUiEnableListener = new IUiUpdateListener() {
            @Override
            public void uiElementNodeUpdated(UiElementNode ui_node, UiUpdateState state) {
                // The UiElementNode for the application XML node always exists, even
                // if there is no corresponding XML node in the XML file.
                //
                // Normally, we enable the UI here if the XML node is not null.
                //
                // However if mAutoCreateRoot is true, the root node will be created on-demand
                // so the tree/block is always enabled.
                boolean exists = mAutoCreateRoot || (ui_node.getXmlNode() != null);
                if (mMasterPart != null) {
                    Section section = mMasterPart.getSection();
                    if (section.getEnabled() != exists) {
                        section.setEnabled(exists);
                        for (Control c : section.getChildren()) {
                            c.setEnabled(exists);
                        }
                    }
                }
            }
        };

        /** Listener to update the root node if the target of the file is changed because of a
         * SDK location change or a project target change */
        final ITargetChangeListener targetListener = new TargetChangeListener() {
            @Override
            public IProject getProject() {
                if (mEditor != null) {
                    return mEditor.getProject();
                }

                return null;
            }

            @Override
            public void reload() {
                // If a details part has been created, we need to "refresh" it too.
                if (mDetailsPart != null) {
                    // The details part does not directly expose access to its internal
                    // page book. Instead it is possible to resize the page book to 0 and then
                    // back to its original value, which has the side effect of removing all
                    // existing cached pages.
                    int limit = mDetailsPart.getPageLimit();
                    mDetailsPart.setPageLimit(0);
                    mDetailsPart.setPageLimit(limit);
                }
                // Refresh the tree, preserving the selection if possible.
                mTreeViewer.refresh();
            }
        };

        // Setup the listeners
        changeRootAndDescriptors(mUiRootNode, mDescriptorFilters, false /* refresh */);

        // Listen on resource framework changes to refresh the tree
        AdtPlugin.getDefault().addTargetListener(targetListener);

        // Remove listeners when the tree widget gets disposed.
        tree.addDisposeListener(new DisposeListener() {
            @Override
            public void widgetDisposed(DisposeEvent e) {
                if (mUiRootNode != null) {
                    UiElementNode node = mUiRootNode.getUiParent() != null ?
                                            mUiRootNode.getUiParent() :
                                            mUiRootNode;

                    if (node != null) {
                        node.removeUpdateListener(mUiRefreshListener);
                    }
                    mUiRootNode.removeUpdateListener(mUiEnableListener);
                }

                AdtPlugin.getDefault().removeTargetListener(targetListener);
                if (mClipboard != null) {
                    mClipboard.dispose();
                    mClipboard = null;
                }
            }
        });

        // Get a new clipboard reference. It is disposed when the tree is disposed.
        mClipboard = new Clipboard(tree.getDisplay());

        return tree;
    }

    /**
     * Changes the UI root node and the descriptor filters of the tree.
     * <p/>
     * This removes the listeners attached to the old root node and reattaches them to the
     * new one.
     *
     * @param uiRootNode The root {@link UiElementNode} which contains all the elements that are
     *        to be manipulated by this tree view. In general this is the manifest UI node or the
     *        application UI node. This cannot be null.
     * @param descriptorFilters A list of descriptors of the elements to be displayed as root in
     *        this tree view. Use null or an empty list to accept any kind of node.
     * @param forceRefresh If tree, forces the tree to refresh
     */
    public void changeRootAndDescriptors(UiElementNode uiRootNode,
            ElementDescriptor[] descriptorFilters, boolean forceRefresh) {
        UiElementNode node;

        // Remove previous listeners if any
        if (mUiRootNode != null) {
            node = mUiRootNode.getUiParent() != null ? mUiRootNode.getUiParent() : mUiRootNode;
            node.removeUpdateListener(mUiRefreshListener);
            mUiRootNode.removeUpdateListener(mUiEnableListener);
        }

        mUiRootNode = uiRootNode;
        mDescriptorFilters = descriptorFilters;

        mTreeViewer.setContentProvider(
                new UiModelTreeContentProvider(mUiRootNode, mDescriptorFilters));

        // Listen on structural changes on the root node of the tree
        // If the node has a parent, listen on the parent instead.
        if (mUiRootNode != null) {
            node = mUiRootNode.getUiParent() != null ? mUiRootNode.getUiParent() : mUiRootNode;

            if (node != null) {
                node.addUpdateListener(mUiRefreshListener);
            }

            // Use the root node to listen to its presence.
            mUiRootNode.addUpdateListener(mUiEnableListener);

            // Initialize the enabled/disabled state
            mUiEnableListener.uiElementNodeUpdated(mUiRootNode, null /* state, not used */);
        }

        if (forceRefresh) {
            mTreeViewer.refresh();
        }

        createSectionActions(mMasterPart.getSection(), mManagedForm.getToolkit());
    }

    /**
     * Creates the buttons next to the tree.
     */
    private void createButtons(FormToolkit toolkit, Composite grid) {

        mUiTreeActions = new UiTreeActions();

        Composite button_grid = SectionHelper.createGridLayout(grid, toolkit, 1);
        button_grid.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
        mAddButton = toolkit.createButton(button_grid, "Add...", SWT.PUSH);
        SectionHelper.addControlTooltip(mAddButton, "Adds a new element.");
        mAddButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL |
                GridData.VERTICAL_ALIGN_BEGINNING));

        mAddButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                super.widgetSelected(e);
                doTreeAdd();
            }
        });

        mRemoveButton = toolkit.createButton(button_grid, "Remove...", SWT.PUSH);
        SectionHelper.addControlTooltip(mRemoveButton, "Removes an existing selected element.");
        mRemoveButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        mRemoveButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                super.widgetSelected(e);
                doTreeRemove();
            }
        });

        mUpButton = toolkit.createButton(button_grid, "Up", SWT.PUSH);
        SectionHelper.addControlTooltip(mRemoveButton, "Moves the selected element up.");
        mUpButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        mUpButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                super.widgetSelected(e);
                doTreeUp();
            }
        });

        mDownButton = toolkit.createButton(button_grid, "Down", SWT.PUSH);
        SectionHelper.addControlTooltip(mRemoveButton, "Moves the selected element down.");
        mDownButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        mDownButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                super.widgetSelected(e);
                doTreeDown();
            }
        });

        adjustTreeButtons(TreeSelection.EMPTY);
    }

    private void createTreeContextMenu(Tree tree) {
        MenuManager menuManager = new MenuManager();
        menuManager.setRemoveAllWhenShown(true);
        menuManager.addMenuListener(new IMenuListener() {
            /**
             * The menu is about to be shown. The menu manager has already been
             * requested to remove any existing menu item. This method gets the
             * tree selection and if it is of the appropriate type it re-creates
             * the necessary actions.
             */
           @Override
        public void menuAboutToShow(IMenuManager manager) {
               ISelection selection = mTreeViewer.getSelection();
               if (!selection.isEmpty() && selection instanceof ITreeSelection) {
                   ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
                   doCreateMenuAction(manager, selected);
                   return;
               }
               doCreateMenuAction(manager, null /* ui_node */);
            }
        });
        Menu contextMenu = menuManager.createContextMenu(tree);
        tree.setMenu(contextMenu);
    }

    /**
     * Adds the menu actions to the context menu when the given UI node is selected in
     * the tree view.
     *
     * @param manager The context menu manager
     * @param selected The UI nodes selected in the tree. Can be null, in which case the root
     *                is to be modified.
     */
    private void doCreateMenuAction(IMenuManager manager, ArrayList<UiElementNode> selected) {
        if (selected != null) {
            boolean hasXml = false;
            for (UiElementNode uiNode : selected) {
                if (uiNode.getXmlNode() != null) {
                    hasXml = true;
                    break;
                }
            }

            if (hasXml) {
                manager.add(new CopyCutAction(getEditor(), getClipboard(),
                        null, selected, true /* cut */));
                manager.add(new CopyCutAction(getEditor(), getClipboard(),
                        null, selected, false /* cut */));

                // Can't paste with more than one element selected (the selection is the target)
                if (selected.size() <= 1) {
                    // Paste is not valid if it would add a second element on a terminal element
                    // which parent is a document -- an XML document can only have one child. This
                    // means paste is valid if the current UI node can have children or if the
                    // parent is not a document.
                    UiElementNode ui_root = selected.get(0).getUiRoot();
                    if (ui_root.getDescriptor().hasChildren() ||
                            !(ui_root.getUiParent() instanceof UiDocumentNode)) {
                        manager.add(new PasteAction(getEditor(), getClipboard(), selected.get(0)));
                    }
                }
                manager.add(new Separator());
            }
        }

        // Append "add" and "remove" actions. They do the same thing as the add/remove
        // buttons on the side.
        IconFactory factory = IconFactory.getInstance();

        // "Add" makes sense only if there's 0 or 1 item selected since the
        // one selected item becomes the target.
        if (selected == null || selected.size() <= 1) {
            manager.add(new Action("Add...", factory.getImageDescriptor("add")) { //$NON-NLS-1$
                @Override
                public void run() {
                    super.run();
                    doTreeAdd();
                }
            });
        }

        if (selected != null) {
            if (selected != null) {
                manager.add(new Action("Remove", factory.getImageDescriptor("delete")) { //$NON-NLS-1$
                    @Override
                    public void run() {
                        super.run();
                        doTreeRemove();
                    }
                });
            }
            manager.add(new Separator());

            manager.add(new Action("Up", factory.getImageDescriptor("up")) { //$NON-NLS-1$
                @Override
                public void run() {
                    super.run();
                    doTreeUp();
                }
            });
            manager.add(new Action("Down", factory.getImageDescriptor("down")) { //$NON-NLS-1$
                @Override
                public void run() {
                    super.run();
                    doTreeDown();
                }
            });
        }
    }


    /**
     * This is called by the tree when a selection is made.
     * It enables/disables the buttons associated with the tree depending on the current
     * selection.
     *
     * @param selection The current tree selection (same as mTreeViewer.getSelection())
     */
    private void adjustTreeButtons(ISelection selection) {
        mRemoveButton.setEnabled(!selection.isEmpty() && selection instanceof ITreeSelection);
        mUpButton.setEnabled(canDoTreeUp(selection));
        mDownButton.setEnabled(canDoTreeDown(selection));
    }

    /**
     * An adapter/wrapper to use the add/remove/up/down tree edit actions.
     */
    private class UiTreeActions extends UiActions {
        @Override
        protected UiElementNode getRootNode() {
            return mUiRootNode;
        }

        @Override
        protected void selectUiNode(UiElementNode uiNodeToSelect) {
            // Select the new item
            if (uiNodeToSelect != null) {
                LinkedList<UiElementNode> segments = new LinkedList<UiElementNode>();
                for (UiElementNode ui_node = uiNodeToSelect; ui_node != mUiRootNode;
                        ui_node = ui_node.getUiParent()) {
                    segments.add(0, ui_node);
                }
                if (segments.size() > 0) {
                    mTreeViewer.setSelection(new TreeSelection(new TreePath(segments.toArray())));
                } else {
                    mTreeViewer.setSelection(null);
                }
            }
        }

        @Override
        public void commitPendingXmlChanges() {
            commitManagedForm();
        }
    }

    /**
     * Filters an ITreeSelection to only keep the {@link UiElementNode}s (in case there's
     * something else in there).
     *
     * @return A new list of {@link UiElementNode} with at least one item or null.
     */
    private ArrayList<UiElementNode> filterSelection(ITreeSelection selection) {
        ArrayList<UiElementNode> selected = new ArrayList<UiElementNode>();

        for (Iterator<Object> it = selection.iterator(); it.hasNext(); ) {
            Object selectedObj = it.next();

            if (selectedObj instanceof UiElementNode) {
                selected.add((UiElementNode) selectedObj);
            }
        }

        return selected.size() > 0 ? selected : null;
    }

    /**
     * Called when the "Add..." button next to the tree view is selected.
     *
     * Displays a selection dialog that lets the user select which kind of node
     * to create, depending on the current selection.
     */
    private void doTreeAdd() {
        UiElementNode ui_node = mUiRootNode;
        ISelection selection = mTreeViewer.getSelection();
        if (!selection.isEmpty() && selection instanceof ITreeSelection) {
            ITreeSelection tree_selection = (ITreeSelection) selection;
            Object first = tree_selection.getFirstElement();
            if (first != null && first instanceof UiElementNode) {
                ui_node = (UiElementNode) first;
            }
        }

        mUiTreeActions.doAdd(
                ui_node,
                mDescriptorFilters,
                mTreeViewer.getControl().getShell(),
                (ILabelProvider) mTreeViewer.getLabelProvider());
    }

    /**
     * Called when the "Remove" button is selected.
     *
     * If the tree has a selection, remove it.
     * This simply deletes the XML node attached to the UI node: when the XML model fires the
     * update event, the tree will get refreshed.
     */
    protected void doTreeRemove() {
        ISelection selection = mTreeViewer.getSelection();
        if (!selection.isEmpty() && selection instanceof ITreeSelection) {
            ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
            mUiTreeActions.doRemove(selected, mTreeViewer.getControl().getShell());
        }
    }

    /**
     * Called when the "Up" button is selected.
     * <p/>
     * If the tree has a selection, move it up, either in the child list or as the last child
     * of the previous parent.
     */
    protected void doTreeUp() {
        ISelection selection = mTreeViewer.getSelection();
        if (!selection.isEmpty() && selection instanceof ITreeSelection) {
            ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
            mUiTreeActions.doUp(selected, mDescriptorFilters);
        }
    }

    /**
     * Checks whether the "up" action can be done on the current selection.
     *
     * @param selection The current tree selection.
     * @return True if all the selected nodes can be moved up.
     */
    protected boolean canDoTreeUp(ISelection selection) {
        if (!selection.isEmpty() && selection instanceof ITreeSelection) {
            ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
            return mUiTreeActions.canDoUp(selected, mDescriptorFilters);
        }

        return false;
    }

    /**
     * Called when the "Down" button is selected.
     *
     * If the tree has a selection, move it down, either in the same child list or as the
     * first child of the next parent.
     */
    protected void doTreeDown() {
        ISelection selection = mTreeViewer.getSelection();
        if (!selection.isEmpty() && selection instanceof ITreeSelection) {
            ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
            mUiTreeActions.doDown(selected, mDescriptorFilters);
        }
    }

    /**
     * Checks whether the "down" action can be done on the current selection.
     *
     * @param selection The current tree selection.
     * @return True if all the selected nodes can be moved down.
     */
    protected boolean canDoTreeDown(ISelection selection) {
        if (!selection.isEmpty() && selection instanceof ITreeSelection) {
            ArrayList<UiElementNode> selected = filterSelection((ITreeSelection) selection);
            return mUiTreeActions.canDoDown(selected, mDescriptorFilters);
        }

        return false;
    }

    /**
     * Commits the current managed form (the one associated with our master part).
     * As a side effect, this will commit the current UiElementDetails page.
     */
    void commitManagedForm() {
        if (mManagedForm != null) {
            mManagedForm.commit(false /* onSave */);
        }
    }

    /* Implements ICommitXml for CopyCutAction */
    @Override
    public void commitPendingXmlChanges() {
        commitManagedForm();
    }

    @Override
    protected void createToolBarActions(IManagedForm managedForm) {
        // Pass. Not used, toolbar actions are defined by createSectionActions().
    }

    @Override
    protected void registerPages(DetailsPart inDetailsPart) {
        // Keep a reference on the details part (the super class doesn't provide a getter
        // for it.)
        mDetailsPart = inDetailsPart;

        // The page selection mechanism does not use pages registered by association with
        // a node class. Instead it uses a custom details page provider that provides a
        // new UiElementDetail instance for each node instance. A limit of 5 pages is
        // then set (the value is arbitrary but should be reasonable) for the internal
        // page book.
        inDetailsPart.setPageLimit(5);

        final UiTreeBlock tree = this;

        inDetailsPart.setPageProvider(new IDetailsPageProvider() {
            @Override
            public IDetailsPage getPage(Object key) {
                if (key instanceof UiElementNode) {
                    return new UiElementDetail(tree);
                }
                return null;
            }

            @Override
            public Object getPageKey(Object object) {
                return object;  // use node object as key
            }
        });
    }

    /**
     * An alphabetic sort action for the tree viewer.
     */
    private class TreeSortAction extends Action {

        private ViewerComparator mComparator;

        public TreeSortAction() {
            super("Sorts elements alphabetically.", AS_CHECK_BOX);
            setImageDescriptor(IconFactory.getInstance().getImageDescriptor("az_sort")); //$NON-NLS-1$

            if (mTreeViewer != null) {
                boolean is_sorted = mTreeViewer.getComparator() != null;
                setChecked(is_sorted);
            }
        }

        /**
         * Called when the button is selected. Toggles the tree viewer comparator.
         */
        @Override
        public void run() {
            if (mTreeViewer == null) {
                notifyResult(false /*success*/);
                return;
            }

            ViewerComparator comp = mTreeViewer.getComparator();
            if (comp != null) {
                // Tree is currently sorted.
                // Save currently comparator and remove it
                mComparator = comp;
                mTreeViewer.setComparator(null);
            } else {
                // Tree is not currently sorted.
                // Reuse or add a new comparator.
                if (mComparator == null) {
                    mComparator = new ViewerComparator();
                }
                mTreeViewer.setComparator(mComparator);
            }

            notifyResult(true /*success*/);
        }
    }

    /**
     * A filter on descriptor for the tree viewer.
     * <p/>
     * The tree viewer will contain many of these actions and only one can be enabled at a
     * given time. When no action is selected, everything is displayed.
     * <p/>
     * Since "radio"-like actions do not allow for unselecting all of them, we manually
     * handle the exclusive radio button-like property: when an action is selected, it manually
     * removes all other actions as needed.
     */
    private class DescriptorFilterAction extends Action {

        private final ElementDescriptor mDescriptor;
        private ViewerFilter mFilter;

        public DescriptorFilterAction(ElementDescriptor descriptor) {
            super(String.format("Displays only %1$s elements.", descriptor.getUiName()),
                    AS_CHECK_BOX);

            mDescriptor = descriptor;
            setImageDescriptor(descriptor.getImageDescriptor());
        }

        /**
         * Called when the button is selected.
         * <p/>
         * Find any existing {@link DescriptorFilter}s and remove them. Install ours.
         */
        @Override
        public void run() {
            super.run();

            if (isChecked()) {
                if (mFilter == null) {
                    // create filter when required
                    mFilter = new DescriptorFilter(this);
                }

                // we add our filter first, otherwise the UI might show the full list
                mTreeViewer.addFilter(mFilter);

                // Then remove the any other filters except ours. There should be at most
                // one other filter, since that's how the actions are made to look like
                // exclusive radio buttons.
                for (ViewerFilter filter : mTreeViewer.getFilters()) {
                    if (filter instanceof DescriptorFilter && filter != mFilter) {
                        DescriptorFilterAction action = ((DescriptorFilter) filter).getAction();
                        action.setChecked(false);
                        mTreeViewer.removeFilter(filter);
                    }
                }
            } else if (mFilter != null){
                mTreeViewer.removeFilter(mFilter);
            }
        }

        /**
         * Filters the tree viewer for the given descriptor.
         * <p/>
         * The filter is linked to the action so that an action can iterate through the list
         * of filters and un-select the actions.
         */
        private class DescriptorFilter extends ViewerFilter {

            private final DescriptorFilterAction mAction;

            public DescriptorFilter(DescriptorFilterAction action) {
                mAction = action;
            }

            public DescriptorFilterAction getAction() {
                return mAction;
            }

            /**
             * Returns true if an element should be displayed, that if the element or
             * any of its parent matches the requested descriptor.
             */
            @Override
            public boolean select(Viewer viewer, Object parentElement, Object element) {
                while (element instanceof UiElementNode) {
                    UiElementNode uiNode = (UiElementNode)element;
                    if (uiNode.getDescriptor() == mDescriptor) {
                        return true;
                    }
                    element = uiNode.getUiParent();
                }
                return false;
            }
        }
    }

}
