/*******************************************************************************
 * Copyright (c) 2021 1C-Soft LLC.
 *
 * This program and the accompanying materials are made available under
 * the terms of the Eclipse Public License 2.0 which is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Vladimir Piskarev (1C) - initial API and implementation
 *******************************************************************************/
package org.eclipse.handly.ui.typehierarchy;

import static org.eclipse.handly.context.Contexts.EMPTY_CONTEXT;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.handly.context.IContext;
import org.eclipse.handly.internal.ui.Activator;
import org.eclipse.handly.ui.DefaultEditorUtility;
import org.eclipse.handly.ui.EditorOpener;
import org.eclipse.handly.ui.EditorUtility;
import org.eclipse.handly.ui.PartListenerAdapter;
import org.eclipse.handly.ui.action.HistoryDropDownAction;
import org.eclipse.handly.ui.viewer.DelegatingSelectionProvider;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.OpenAndLinkWithEditorHelper;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.BaseSelectionListenerAction;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.part.ViewPart;

/**
 * An abstract base implementation of a type hierarchy view.
 *
 * @since 1.6
 */
public abstract class TypeHierarchyViewPart
    extends ViewPart
{
    /**
     * Pop-up menu: name of group for focus actions (value
     * <code>"group.focus"</code>).
     */
    protected static final String GROUP_FOCUS = "group.focus"; //$NON-NLS-1$

    private static final Object[] NO_ELEMENTS = new Object[0];

    private static final String KEY_HIERARCHY_KIND =
        "org.eclipse.handly.typehierarchy.view.hierarchyKind"; //$NON-NLS-1$
    private static final String KEY_LAYOUT_MODE =
        "org.eclipse.handly.typehierarchy.view.layoutMode"; //$NON-NLS-1$
    private static final String KEY_HORIZONTAL_WEIGHTS =
        "org.eclipse.handly.typehierarchy.view.horizontalWeights"; //$NON-NLS-1$
    private static final String KEY_VERTICAL_WEIGHTS =
        "org.eclipse.handly.typehierarchy.view.verticalWeights"; //$NON-NLS-1$

    private static final int LAYOUT_AUTOMATIC = SWT.HORIZONTAL | SWT.VERTICAL;

    private final Set<TypeHierarchyKind> supportedHierarchyKinds;
    private Set<TypeHierarchyKind> enabledHierarchyKinds;
    private TypeHierarchyKind hierarchyKind;
    private int layoutMode = getDefaultLayoutMode();
    private boolean layoutAdjusted;
    private int[] horizontalWeights, verticalWeights;
    private Object[] inputElements = NO_ELEMENTS;
    private final List<HistoryEntry> history = new ArrayList<>();
    private PageBook pageBook, hierarchyPageBook;
    private Control noHierarchyPage;
    private SashForm sashForm;
    private final Map<TypeHierarchyKind, TreeViewer> hierarchyViewers =
        new HashMap<>();
    private EditorOpener editorOpener;
    private SetHierarchyKindAction[] setHierarchyKindActions =
        new SetHierarchyKindAction[0];
    private SetLayoutModeAction[] setLayoutModeActions =
        new SetLayoutModeAction[0];
    private final FocusOnSelectionAction focusOnSelectionAction =
        new FocusOnSelectionAction();
    private HistoryDropDownAction<HistoryEntry> historyDropDownAction;
    private final RefreshAction refreshAction = new RefreshAction();

    private final IPartListener partListener = new PartListenerAdapter()
    {
        @Override
        public void partOpened(IWorkbenchPart part)
        {
            if (part != TypeHierarchyViewPart.this)
                return;

            refresh();
        };
    };

    /**
     * Constructs a type hierarchy view that supports all of the
     * type hierarchy kinds.
     *
     * @see TypeHierarchyKind
     * @see #TypeHierarchyViewPart(Set)
     */
    public TypeHierarchyViewPart()
    {
        this(EnumSet.allOf(TypeHierarchyKind.class));
    }

    /**
     * Constructs a type hierarchy view that supports the given
     * type hierarchy kinds. Clients <b>must not</b> modify the given set
     * afterwards.
     *
     * @param supportedHierarchyKinds not <code>null</code> and not empty
     */
    public TypeHierarchyViewPart(Set<TypeHierarchyKind> supportedHierarchyKinds)
    {
        if (supportedHierarchyKinds.isEmpty())
            throw new IllegalArgumentException();

        this.supportedHierarchyKinds = supportedHierarchyKinds;
        this.enabledHierarchyKinds = supportedHierarchyKinds;
        this.hierarchyKind = supportedHierarchyKinds.iterator().next();

        makeSetHierarchyKindActions();
        makeSetLayoutModeActions();
        refreshAction.setEnabled(false);
    }

    /**
     * Returns whether the given elements are possible input elements for this view.
     * <p>
     * Default implementation invokes {@link #isPossibleInputElement(Object)} for
     * each of the given elements until <code>false</code> is returned for an element
     * (in which case this method will return <code>false</code>) or all elements
     * have been checked (in which case it will return <code>true</code>).
     * </p>
     *
     * @param elements may be <code>null</code> or may contain null elements,
     *  in which case <code>false</code> will be returned; may be empty,
     *  in which case <code>true</code> will be returned
     * @return <code>true</code> if the given elements are possible input elements
     *  for this view, and <code>false</code> otherwise
     */
    public boolean arePossibleInputElements(Object[] elements)
    {
        if (elements == null)
            return false;
        for (Object element : elements)
        {
            if (!isPossibleInputElement(element))
                return false;
        }
        return true;
    }

    /**
     * Sets the current input elements for this view. Clients <b>must not</b>
     * modify the given array afterwards.
     *
     * @param elements not <code>null</code>, must not contain null elements;
     *  may be empty
     * @throws IllegalArgumentException if {@link #arePossibleInputElements(Object[])}
     *  returns <code>false</code> for the given elements
     */
    public void setInputElements(Object[] elements)
    {
        if (!arePossibleInputElements(elements))
            throw new IllegalArgumentException(Arrays.toString(elements));

        Object[] oldInputElements = inputElements;

        inputElements = elements;

        refreshAction.setEnabled(elements.length > 0);

        if (elements.length > 0)
            addHistoryEntry(createHistoryEntry(elements));

        onInputElementsChanged(oldInputElements, elements);
    }

    /**
     * Returns the current input elements for this view.
     *
     * @return the current input elements (never <code>null</code>,
     *  may be empty). Clients <b>must not</b> modify the returned array.
     */
    public final Object[] getInputElements()
    {
        return inputElements;
    }

    /**
     * Returns whether the given hierarchy kind is currently enabled for this view.
     *
     * @param kind may be <code>null</code>, in which case <code>false</code>
     *  will be returned
     * @return <code>true</code> if the given kind is currently enabled,
     *  and <code>false</code> otherwise
     */
    public final boolean isEnabledHierarchyKind(TypeHierarchyKind kind)
    {
        return enabledHierarchyKinds.contains(kind);
    }

    /**
     * Sets the current hierarchy kind for this view.
     *
     * @param kind not <code>null</code>
     * @throws IllegalArgumentException if the given kind is not currently {@link
     *  #isEnabledHierarchyKind(TypeHierarchyKind) enabled} for this view
     */
    public void setHierarchyKind(TypeHierarchyKind kind)
    {
        if (!isEnabledHierarchyKind(kind))
            throw new IllegalArgumentException();

        if (kind == hierarchyKind)
            return;

        TypeHierarchyKind oldKind = hierarchyKind;

        hierarchyKind = kind;

        for (SetHierarchyKindAction action : setHierarchyKindActions)
            action.setChecked(action.kind == kind);

        onHierarchyKindChanged(oldKind, kind);
    }

    /**
     * Returns the current hierarchy kind for this view.
     *
     * @return the current hierarchy kind (never <code>null</code>)
     * @see #setHierarchyKind(TypeHierarchyKind)
     */
    public final TypeHierarchyKind getHierarchyKind()
    {
        return hierarchyKind;
    }

    /**
     * Sets layout mode for this view, which may be one of the constants
     * {@link SWT#HORIZONTAL} or {@link SWT#VERTICAL}; this method may also
     * be called with <code>SWT.HORIZONTAL|SWT.VERTICAL</code> for automatic
     * layout or {@link SWT#NONE} for hierarchy-only layout.
     * <p>
     * Note that only a subset of the allowed values for layout mode may be
     * {@link #supportsLayoutMode(int) supported} by the view.
     * </p>
     *
     * @param layoutMode the given layout mode
     * @throws IllegalArgumentException if the given layout mode is not
     *  {@link #supportsLayoutMode(int) supported} by the view
     */
    public void setLayoutMode(int layoutMode)
    {
        if (!supportsLayoutMode(layoutMode))
            throw new IllegalArgumentException();

        if (layoutMode == this.layoutMode)
            return;

        int oldLayoutMode = this.layoutMode;

        this.layoutMode = layoutMode;

        for (SetLayoutModeAction action : setLayoutModeActions)
            action.setChecked(action.layoutMode == layoutMode);

        onLayoutModeChanged(oldLayoutMode, layoutMode);
    }

    /**
     * Returns the current layout mode for this view.
     *
     * @return the current layout mode
     * @see #setLayoutMode(int)
     */
    public final int getLayoutMode()
    {
        return layoutMode;
    }

    /**
     * Returns <code>true</code> if the given value represents a supported
     * layout mode for this view, and <code>false</code> otherwise.
     * The set of the supported layout mode values does not change over
     * the lifetime of the view and is never empty.
     * <p>
     * Default implementation only supports {@link SWT#NONE}, which represents
     * hierarchy-only layout.
     * </p>
     *
     * @param layoutMode the layout mode to check
     * @return <code>true</code> if the given value represents a supported
     *  layout mode for this view, and <code>false</code> otherwise
     */
    public boolean supportsLayoutMode(int layoutMode)
    {
        return layoutMode == SWT.NONE;
    }

    /**
     * Performs a full refresh of the content of this view.
     */
    public final void refresh()
    {
        refresh(EMPTY_CONTEXT);
    }

    @Override
    public void init(IViewSite site, IMemento memento) throws PartInitException
    {
        super.init(site, memento);
        if (memento != null)
        {
            if (supportedHierarchyKinds.size() > 1)
            {
                String value = memento.getString(KEY_HIERARCHY_KIND);
                if (value != null)
                {
                    TypeHierarchyKind kind = null;
                    try
                    {
                        kind = TypeHierarchyKind.valueOf(value);
                    }
                    catch (IllegalArgumentException e)
                    {
                    }
                    if (supportedHierarchyKinds.contains(kind))
                        setHierarchyKind(kind);
                }
            }

            Integer layoutMode = memento.getInteger(KEY_LAYOUT_MODE);
            if (layoutMode != null)
            {
                int value = layoutMode.intValue();
                if (supportsLayoutMode(value))
                    setLayoutMode(value);
            }

            try
            {
                horizontalWeights = toIntArray(memento.getString(
                    KEY_HORIZONTAL_WEIGHTS));
            }
            catch (NumberFormatException e)
            {
            }

            try
            {
                verticalWeights = toIntArray(memento.getString(
                    KEY_VERTICAL_WEIGHTS));
            }
            catch (NumberFormatException e)
            {
            }
        }
    }

    @Override
    public void saveState(IMemento memento)
    {
        super.saveState(memento);
        if (supportedHierarchyKinds.size() > 1)
            memento.putString(KEY_HIERARCHY_KIND, hierarchyKind.name());
        memento.putInteger(KEY_LAYOUT_MODE, layoutMode);
        saveSashFormWeights();
        memento.putString(KEY_HORIZONTAL_WEIGHTS, toString(horizontalWeights));
        memento.putString(KEY_VERTICAL_WEIGHTS, toString(verticalWeights));
    }

    @Override
    public void createPartControl(Composite parent)
    {
        getSite().getPage().addPartListener(partListener);

        parent.addControlListener(new ControlAdapter()
        {
            @Override
            public void controlResized(ControlEvent e)
            {
                if (!layoutAdjusted || layoutMode == LAYOUT_AUTOMATIC)
                    adjustLayout(layoutMode);
            }
        });

        DelegatingSelectionProvider selectionProvider =
            new DelegatingSelectionProvider();

        getSite().setSelectionProvider(selectionProvider);

        selectionProvider.addSelectionChangedListener(e ->
        {
            ISelection selection = e.getSelection();
            if (selection instanceof IStructuredSelection)
                updateStatusLine(
                    getViewSite().getActionBars().getStatusLineManager(),
                    (IStructuredSelection)selection);
        });

        pageBook = new PageBook(parent, SWT.NONE);

        noHierarchyPage = createNoHierarchyPage(pageBook);

        sashForm = new SashForm(pageBook, SWT.NONE);

        hierarchyPageBook = new PageBook(sashForm, SWT.NONE);

        if (layoutMode == SWT.NONE)
            sashForm.setMaximizedControl(hierarchyPageBook);

        for (TypeHierarchyKind kind : supportedHierarchyKinds)
        {
            TreeViewer hierarchyViewer = createHierarchyViewer(
                hierarchyPageBook, kind);

            configureHierarchyViewer(hierarchyViewer, kind);

            initContextMenu(hierarchyViewer.getControl(), (
                IMenuManager manager) ->
            {
                createHierarchyViewerMenuGroups(manager, kind);
                fillHierarchyViewerMenu(manager, kind);
            }, getSite().getId(), selectionProvider);

            new OpenEditorHelper(hierarchyViewer);

            hierarchyViewer.getControl().addFocusListener(new FocusListener()
            {
                @Override
                public void focusGained(FocusEvent e)
                {
                    selectionProvider.setDelegate(hierarchyViewer);
                    onHierarchySelectionChanged(hierarchyViewer.getSelection(),
                        kind);
                }

                @Override
                public void focusLost(FocusEvent e)
                {
                    selectionProvider.setDelegate(null);
                }
            });

            hierarchyViewer.addSelectionChangedListener(
                e -> onHierarchySelectionChanged(e.getSelection(), kind));

            hierarchyViewers.put(kind, hierarchyViewer);
        }

        editorOpener = createEditorOpener();

        selectionProvider.addSelectionChangedListener(focusOnSelectionAction);

        addRefreshAction(refreshAction);

        getViewSite().getActionBars().setGlobalActionHandler(
            ActionFactory.REFRESH.getId(), refreshAction);

        for (SetHierarchyKindAction action : setHierarchyKindActions)
            addSetHierarchyKindAction(action, action.kind);

        for (SetLayoutModeAction action : setLayoutModeActions)
            addSetLayoutModeAction(action, action.layoutMode);

        historyDropDownAction = createHistoryDropDownAction(
            new HistoryDropDownAction.History<HistoryEntry>()
            {
                @Override
                public List<HistoryEntry> getHistoryEntries()
                {
                    return getHistory();
                }

                @Override
                public void setHistoryEntries(List<HistoryEntry> entries)
                {
                    List<HistoryEntry> history = getHistory();
                    history.clear();
                    history.addAll(entries);
                    onHistoryChanged();
                }

                @Override
                public HistoryEntry getActiveEntry()
                {
                    Object[] inputElements = getInputElements();
                    if (inputElements.length == 0)
                        return null;
                    return createHistoryEntry(inputElements);
                }

                @Override
                public void setActiveEntry(HistoryEntry entry)
                {
                    setInputElements(entry.getInputElements());
                }

                @Override
                public String getLabel(HistoryEntry entry)
                {
                    return entry.getLabel();
                }

                @Override
                public ImageDescriptor getImageDescriptor(HistoryEntry entry)
                {
                    return entry.getImageDescriptor();
                }
            });
        historyDropDownAction.setEnabled(!getHistory().isEmpty());
        addHistoryDropDownAction(historyDropDownAction);
    }

    @Override
    public void dispose()
    {
        getSite().getPage().removePartListener(partListener);

        super.dispose();
    }

    @Override
    public void setFocus()
    {
        pageBook.setFocus();
    }

    /**
     * Returns whether the given element is a possible input element for this view.
     *
     * @param element may be <code>null</code>, in which case <code>false</code>
     *  will be returned
     * @return <code>true</code> if the given element is a possible input element
     *  for this view, and <code>false</code> otherwise
     * @see #arePossibleInputElements(Object[])
     */
    protected abstract boolean isPossibleInputElement(Object element);

    /**
     * Creates and returns a history entry for the given input elements.
     *
     * @param inputElements never <code>null</code>; never empty
     * @return the created history entry (not <code>null</code>)
     */
    protected abstract HistoryEntry createHistoryEntry(Object[] inputElements);

    /**
     * Computes the content description for this view.
     *
     * @return the computed content description (not <code>null</code>)
     * @see #getContentDescription()
     */
    protected abstract String computeContentDescription();

    /**
     * Returns whether the view has already been opened and has not yet been
     * closed.
     *
     * @return <code>true</code> if the view is currently open,
     *  and <code>false</code> otherwise
     */
    protected final boolean isOpen()
    {
        return pageBook != null && !pageBook.isDisposed();
    }

    /**
     * Performs a refresh of the content of this view according to options
     * specified in the given context.
     *
     * @param context the operation context (never <code>null</code>)
     */
    protected void refresh(IContext context)
    {
        if (!isOpen())
            return;

        setContentDescription(computeContentDescription());

        for (Map.Entry<TypeHierarchyKind, TreeViewer> entry : hierarchyViewers.entrySet())
            setHierarchyViewerInput(entry.getValue(), entry.getKey());

        updateHierarchyPage();
    }

    /**
     * Ensures that the appropriate hierarchy page is shown by this view.
     * <p>
     * This method may only be called after the SWT controls for this view
     * have been created and before they have been disposed.
     * </p>
     */
    protected void updateHierarchyPage()
    {
        if (inputElements.length > 0)
        {
            TreeViewer hierarchyViewer = hierarchyViewers.get(hierarchyKind);
            Control hierarchyPage = hierarchyViewer.getControl();
            pageBook.showPage(sashForm);
            hierarchyPageBook.showPage(hierarchyPage);
            hierarchyPage.setFocus();
        }
        else
        {
            pageBook.showPage(noHierarchyPage);
            pageBook.setFocus();
        }
    }

    /**
     * A callback that is invoked when the view input elements change.
     *
     * @param oldInputElements never <code>null</code>
     * @param newInputElements never <code>null</code>
     */
    protected void onInputElementsChanged(Object[] oldInputElements,
        Object[] newInputElements)
    {
        refresh();
    }

    /**
     * A callback that is invoked when the current hierarchy kind changes.
     *
     * @param oldKind never <code>null</code>
     * @param newKind never <code>null</code>
     */
    protected void onHierarchyKindChanged(TypeHierarchyKind oldKind,
        TypeHierarchyKind newKind)
    {
        if (!isOpen())
            return;

        updateHierarchyPage();
    }

    /**
     * Returns a set of the supported hierarchy kinds for this view.
     *
     * @return the supported hierarchy kinds (never <code>null</code>,
     *  never empty)
     */
    protected final Set<TypeHierarchyKind> getSupportedHierarchyKinds()
    {
        return supportedHierarchyKinds;
    }

    /**
     * Sets the enabled hierarchy kinds for this view. Note that at least one
     * hierarchy kind must be enabled. Clients <b>must not</b> modify the given
     * set afterwards.
     *
     * @param kinds not <code>null</code> and not empty
     */
    protected void setEnabledHierarchyKinds(Set<TypeHierarchyKind> kinds)
    {
        if (kinds.isEmpty())
            throw new IllegalArgumentException();

        if (!supportedHierarchyKinds.containsAll(kinds))
            throw new IllegalArgumentException();

        if (enabledHierarchyKinds.equals(kinds))
            return;

        Set<TypeHierarchyKind> oldKinds = enabledHierarchyKinds;

        enabledHierarchyKinds = kinds;

        for (SetHierarchyKindAction action : setHierarchyKindActions)
            action.setEnabled(kinds.contains(action.kind));

        if (!kinds.contains(hierarchyKind))
            setHierarchyKind(kinds.iterator().next());

        onEnabledHierarchyKindsChanged(oldKinds, kinds);
    }

    /**
     * A callback that is invoked when the set of enabled hierarchy kinds changes.
     *
     * @param oldKinds never <code>null</code>
     * @param newKinds never <code>null</code>
     */
    protected void onEnabledHierarchyKindsChanged(
        Set<TypeHierarchyKind> oldKinds, Set<TypeHierarchyKind> newKinds)
    {
        if (!isOpen())
            return;

        for (TypeHierarchyKind kind : symmetricDifference(oldKinds, newKinds))
            setHierarchyViewerInput(hierarchyViewers.get(kind), kind);
    }

    /**
     * A callback that is invoked when the view layout mode changes.
     *
     * @param oldLayoutMode the old layout mode
     * @param newLayoutMode the new layout mode
     */
    protected void onLayoutModeChanged(int oldLayoutMode, int newLayoutMode)
    {
        if (!isOpen())
            return;

        sashForm.setMaximizedControl(newLayoutMode == SWT.NONE
            ? hierarchyPageBook : null);
        adjustLayout(newLayoutMode);
    }

    /**
     * Updates the status line based on the given selection in this view.
     * <p>
     * Default implementation clears the status line message if the selection
     * is empty or if exactly one element is selected; sets a generic message
     * of the form "(x) items selected" otherwise. It always clears the error
     * message.
     * </p>
     *
     * @param manager the status line manager (never <code>null</code>)
     * @param selection the current selection (never <code>null</code>)
     */
    protected void updateStatusLine(IStatusLineManager manager,
        IStructuredSelection selection)
    {
        String message = null;
        int size = selection.size();
        if (size > 1)
        {
            message = MessageFormat.format(
                Messages.TypeHierarchyViewPart_0__items_selected, size);
        }
        manager.setMessage(message);
        manager.setErrorMessage(null);
    }

    /**
     * Creates and returns a control for the 'no hierarchy' page.
     * This method is called once, when the part's control is created.
     * <p>
     * Default implementation returns a <code>Label</code> telling,
     * in general terms, that there is no type hierarchy to display.
     * Subclasses may override this method (e.g., to give details
     * on what the user needs to do to display a type hierarchy).
     * </p>
     *
     * @param parent the parent composite (never <code>null</code>)
     * @return the created control (not <code>null</code>)
     */
    protected Control createNoHierarchyPage(Composite parent)
    {
        Label label = new Label(parent, SWT.LEAD + SWT.WRAP);
        label.setText(Messages.TypeHierarchyViewPart_No_hierarchy_to_display);
        return label;
    }

    /**
     * Returns the {@link SashForm} created for this view.
     *
     * @return the <code>SashForm</code>,
     *  or <code>null</code> if it has yet to be created
     */
    protected final SashForm getSashForm()
    {
        return sashForm;
    }

    /**
     * Returns the hierarchy tree viewer for the given hierarchy kind.
     *
     * @param kind the type hierarchy kind (never <code>null</code>)
     * @return the hierarchy tree viewer,
     *  or <code>null</code> if it has yet to be created
     * @see #createHierarchyViewer(Composite, TypeHierarchyKind)
     */
    protected final TreeViewer getHierarchyViewer(TypeHierarchyKind kind)
    {
        return hierarchyViewers.get(kind);
    }

    /**
     * Creates and returns a tree viewer that will be used for displaying
     * the type hierarchy of the given kind. This method only creates the viewer;
     * it does not configure it. This method is called once, when the part's
     * control is created.
     *
     * @param parent the parent composite (never <code>null</code>)
     * @param kind the type hierarchy kind (never <code>null</code>)
     * @return the created viewer (not <code>null</code>)
     * @see #configureHierarchyViewer(TreeViewer, TypeHierarchyKind)
     */
    protected TreeViewer createHierarchyViewer(Composite parent,
        TypeHierarchyKind kind)
    {
        return new TreeViewer(parent, SWT.SINGLE);
    }

    /**
     * Configures the newly created hierarchy viewer for the given hierarchy kind.
     * This method has to set as least a content provider and a label provider.
     * This method is called once, just after the viewer is created.
     *
     * @param viewer the viewer to configure (never <code>null</code>)
     * @param kind the type hierarchy kind (never <code>null</code>)
     */
    protected abstract void configureHierarchyViewer(TreeViewer viewer,
        TypeHierarchyKind kind);

    /**
     * Sets the input for the hierarchy viewer for the given hierarchy kind.
     *
     * @param viewer the viewer to set the input for (never <code>null</code>)
     * @param kind the type hierarchy kind (never <code>null</code>)
     */
    protected void setHierarchyViewerInput(TreeViewer viewer,
        TypeHierarchyKind kind)
    {
        viewer.setInput(inputElements.length > 0 && isEnabledHierarchyKind(kind)
            ? inputElements : null);
    }

    /**
     * Creates the menu groups for the pop-up menu of the hierarchy viewer of
     * the given hierarchy kind. This method is called each time the pop-up menu
     * is about to show, just before {@link #fillHierarchyViewerMenu} is called.
     * <p>
     * Default implementation adds groups named {@link #GROUP_FOCUS} and
     * {@link IWorkbenchActionConstants#MB_ADDITIONS}. Subclasses may extend
     * or override this method, but should usually keep the default groups.
     * <p>
     *
     * @param manager the menu manager (never <code>null</code>)
     * @param kind the type hierarchy kind (never <code>null</code>)
     */
    protected void createHierarchyViewerMenuGroups(IMenuManager manager,
        TypeHierarchyKind kind)
    {
        manager.add(new Separator(GROUP_FOCUS));
        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
    }

    /**
     * Fills the pop-menu for the hierarchy viewer for the given hierarchy kind
     * using the menu groups created by {@link #createHierarchyViewerMenuGroups}.
     * This method is called each time the pop-up menu is about to show.
     * <p>
     * Default implementation adds generic actions such as 'focus on selection'.
     * Subclasses may extend or override this method.
     * </p>
     *
     * @param manager the menu manager (never <code>null</code>)
     * @param kind the type hierarchy kind (never <code>null</code>)
     */
    protected void fillHierarchyViewerMenu(IMenuManager manager,
        TypeHierarchyKind kind)
    {
        if (focusOnSelectionAction.isEnabled())
            manager.appendToGroup(GROUP_FOCUS, focusOnSelectionAction);
    }

    /**
     * A callback that is invoked when selection changes in the hierarchy viewer
     * for the given hierarchy kind.
     * <p>
     * Default implementation tries to reveal the selected hierarchy node in an
     * open editor with {@link #revealInEditor(Object, boolean, boolean)
     * revealInEditor}.
     * </p>
     *
     * @param selection the new selection (never <code>null</code>)
     * @param kind the type hierarchy kind (never <code>null</code>)
     */
    protected void onHierarchySelectionChanged(ISelection selection,
        TypeHierarchyKind kind)
    {
        Object element = getSelectedElement(selection);
        if (element != null)
        {
            if (hierarchyViewers.get(kind).getControl().isFocusControl())
            {
                try
                {
                    revealInEditor(element, false, false);
                }
                catch (PartInitException e)
                {
                    // cannot happen: may not open a new editor
                }
            }
        }
    }

    /**
     * Reveals the given element in an appropriate editor on a best effort basis.
     * <p>
     * Default implementation uses the {@link #getEditorOpener() editor opener}.
     * </p>
     *
     * @param element not <code>null</code>
     * @param activate whether to activate the editor
     * @param mayOpenNewEditor whether a new editor may be opened
     *  when the element cannot be revealed in an existing editor
     * @throws PartInitException if a new editor could not be created
     *  or initialized
     */
    protected void revealInEditor(Object element, boolean activate,
        boolean mayOpenNewEditor) throws PartInitException
    {
        EditorUtility editorUtility = editorOpener.getEditorUtility();
        if (editorUtility.getEditorInput(element) == null)
            return;

        if (mayOpenNewEditor)
            editorOpener.open(element, activate, true);
        else
        {
            IWorkbenchPage page = editorOpener.getWorkbenchPage();
            IEditorReference editorRef = editorUtility.findEditor(page,
                element);
            if (editorRef != null)
            {
                IEditorPart editor = editorRef.getEditor(true);
                if (editor != null)
                {
                    if (activate)
                        page.activate(editor);
                    else
                        page.bringToTop(editor);
                    editorUtility.revealElement(editor, element);
                }
            }
        }
    }

    /**
     * Returns the editor opener used by this view.
     *
     * @return the editor opener,
     *  or <code>null</code> if it has yet to be created
     * @see #createEditorOpener()
     */
    protected final EditorOpener getEditorOpener()
    {
        return editorOpener;
    }

    /**
     * Creates and returns an editor opener for this view.
     * This method is called once, when the part's control is created.
     * <p>
     * Subclasses may override this method if they require a specific
     * editor opener.
     * </p>
     *
     * @return the created editor opener (not <code>null</code>)
     */
    protected EditorOpener createEditorOpener()
    {
        return new EditorOpener(getSite().getPage(),
            DefaultEditorUtility.INSTANCE);
    }

    /**
     * Returns the 'focus on selection' action used by this view.
     *
     * @return the 'focus on selection' action
     */
    protected final IAction getFocusOnSelectionAction()
    {
        return focusOnSelectionAction;
    }

    /**
     * Contributes the 'refresh' action to this view.
     * This method is called once, when the part's control is created.
     * <p>
     * Default implementation adds the given action to the view tool bar.
     * Subclasses may extend or override this method.
     * </p>
     *
     * @param action the 'refresh' action (never <code>null</code>)
     */
    protected void addRefreshAction(IAction action)
    {
        getViewSite().getActionBars().getToolBarManager().add(action);
    }

    /**
     * Contributes a 'set hierarchy kind' action to this view. This method
     * is called once for each of the 'set hierarchy kind' actions, when the
     * part's control is created. If this view supports only one hierarchy kind,
     * no 'set hierarchy kind' action is created and this method is not called.
     * <p>
     * Default implementation adds the given action to the view tool bar
     * as well as to the view menu. Subclasses may extend or override
     * this method.
     * </p>
     *
     * @param action a 'set hierarchy kind' action
     *  (never <code>null</code>)
     * @param kind the hierarchy kind set by the given action
     *  (never <code>null</code>)
     * @see #setHierarchyKind(TypeHierarchyKind)
     */
    protected void addSetHierarchyKindAction(IAction action,
        TypeHierarchyKind kind)
    {
        IActionBars actionBars = getViewSite().getActionBars();
        actionBars.getToolBarManager().add(action);
        actionBars.getMenuManager().add(action);
    }

    /**
     * Contributes a 'set layout mode' action to this view. This method
     * is called once for each of the 'set layout mode' actions, when the
     * part's control is created. If this view supports only one layout mode,
     * no 'set layout mode' action is created and this method is not called.
     * <p>
     * Default implementation adds the given action to the 'Layout' sub-menu
     * of the view menu. The sub-menu is created if necessary. Subclasses may
     * extend or override this method.
     * </p>
     *
     * @param action a 'set layout mode' action
     *  (never <code>null</code>)
     * @param layoutMode the layout mode set by the given action
     * @see #setLayoutMode(int)
     */
    protected void addSetLayoutModeAction(IAction action, int layoutMode)
    {
        IActionBars actionBars = getViewSite().getActionBars();
        IMenuManager viewMenu = actionBars.getMenuManager();
        String id = "layout"; //$NON-NLS-1$
        IMenuManager layoutSubMenu = viewMenu.findMenuUsingPath(id);
        if (layoutSubMenu == null)
        {
            viewMenu.add(new Separator());
            layoutSubMenu = new MenuManager(
                Messages.TypeHierarchyViewPart_Layout_menu, id);
            viewMenu.add(layoutSubMenu);
        }
        layoutSubMenu.add(action);
    }

    /**
     * Creates and returns a 'show history list' action for this view.
     * This method is called once, when the part's control is created.
     * <p>
     * Subclasses need to override this method if they extend
     * {@link HistoryDropDownAction}.
     * </p>
     *
     * @param history never <code>null</code>
     * @return the created action (not <code>null</code>)
     */
    protected HistoryDropDownAction<HistoryEntry> createHistoryDropDownAction(
        HistoryDropDownAction.History<HistoryEntry> history)
    {
        return new HistoryDropDownAction<>(history);
    }

    /**
     * Contributes the 'show history list' action to this view.
     * This method is called once, when the part's control is created.
     * <p>
     * Default implementation adds the given action to the view tool bar.
     * Subclasses may extend or override this method.
     * </p>
     *
     * @param action the 'show history list' action (never <code>null</code>)
     */
    protected void addHistoryDropDownAction(IAction action)
    {
        getViewSite().getActionBars().getToolBarManager().add(action);
    }

    /**
     * Returns the history used by this view; the history is represented by
     * a "live" list of history entries.
     *
     * @return the view history (never <code>null</code>)
     */
    protected List<HistoryEntry> getHistory()
    {
        return history;
    }

    /**
     * A callback that is invoked when the history has been updated.
     * <p>
     * Default implementation sets the enabled state of the 'show history list'
     * action according to whether the history is empty and, if the history
     * is empty, clears the view input.
     * </p>
     *
     * @see #getHistory()
     */
    protected void onHistoryChanged()
    {
        boolean empty = getHistory().isEmpty();
        historyDropDownAction.setEnabled(!empty);
        if (empty)
            setInputElements(NO_ELEMENTS);
    }

    private void addHistoryEntry(HistoryEntry entry)
    {
        List<HistoryEntry> history = getHistory();
        history.remove(entry);
        history.add(0, entry);
        onHistoryChanged();
    }

    private void makeSetHierarchyKindActions()
    {
        int size = supportedHierarchyKinds.size();
        if (size > 1)
        {
            setHierarchyKindActions = new SetHierarchyKindAction[size];
            int i = 0;
            for (TypeHierarchyKind kind : supportedHierarchyKinds)
                setHierarchyKindActions[i++] = new SetHierarchyKindAction(kind);
        }
    }

    private void makeSetLayoutModeActions()
    {
        List<SetLayoutModeAction> actions = new ArrayList<>();
        if (supportsLayoutMode(SWT.VERTICAL))
            actions.add(new SetLayoutModeAction(SWT.VERTICAL));
        if (supportsLayoutMode(SWT.HORIZONTAL))
            actions.add(new SetLayoutModeAction(SWT.HORIZONTAL));
        if (supportsLayoutMode(LAYOUT_AUTOMATIC))
            actions.add(new SetLayoutModeAction(LAYOUT_AUTOMATIC));
        if (supportsLayoutMode(SWT.NONE))
            actions.add(new SetLayoutModeAction(SWT.NONE));
        int size = actions.size();
        if (size > 1)
            setLayoutModeActions = actions.toArray(
                new SetLayoutModeAction[size]);
    }

    private int getDefaultLayoutMode()
    {
        if (supportsLayoutMode(LAYOUT_AUTOMATIC))
            return LAYOUT_AUTOMATIC;
        if (supportsLayoutMode(SWT.VERTICAL))
            return SWT.VERTICAL;
        if (supportsLayoutMode(SWT.HORIZONTAL))
            return SWT.HORIZONTAL;
        if (supportsLayoutMode(SWT.NONE))
            return SWT.NONE;
        throw new AssertionError();
    }

    private void adjustLayout(int layoutMode)
    {
        if (layoutMode == SWT.NONE)
            return;

        Point size = sashForm.getParent().getParent().getSize();
        if (size.x == 0 || size.y == 0)
            return;

        int orientation = (layoutMode == LAYOUT_AUTOMATIC) ? (size.x > size.y
            ? SWT.HORIZONTAL : SWT.VERTICAL) : layoutMode;

        if (sashForm.getOrientation() == orientation && layoutAdjusted)
            return;

        if (sashForm.getOrientation() != orientation)
        {
            saveSashFormWeights();
            sashForm.setOrientation(orientation);
        }

        restoreSashFormWeights();
        layoutAdjusted = true;
    }

    private void saveSashFormWeights()
    {
        if (!layoutAdjusted)
            return;

        int[] weights = sashForm.getWeights();
        if (weights.length < 2)
            return;

        if (sashForm.getOrientation() == SWT.HORIZONTAL)
            horizontalWeights = weights;
        else
            verticalWeights = weights;
    }

    private void restoreSashFormWeights()
    {
        int[] weights = (sashForm.getOrientation() == SWT.HORIZONTAL)
            ? horizontalWeights : verticalWeights;
        if (weights != null)
            sashForm.setWeights(weights);
    }

    private void initContextMenu(Control parent, IMenuListener listener,
        String menuId, ISelectionProvider selectionProvider)
    {
        MenuManager manager = new MenuManager();
        manager.setRemoveAllWhenShown(true);
        manager.addMenuListener(listener);
        Menu menu = manager.createContextMenu(parent);
        parent.setMenu(menu);
        getSite().registerContextMenu(menuId, manager, selectionProvider);
    }

    private static Object getSelectedElement(ISelection selection)
    {
        if (selection instanceof IStructuredSelection)
        {
            IStructuredSelection ss = (IStructuredSelection)selection;
            if (ss.size() == 1)
                return ss.getFirstElement();
        }
        return null;
    }

    private static Set<TypeHierarchyKind> symmetricDifference(
        Set<TypeHierarchyKind> kindsA, Set<TypeHierarchyKind> kindsB)
    {
        Set<TypeHierarchyKind> result = EnumSet.copyOf(kindsA);
        for (TypeHierarchyKind kind : kindsB)
        {
            if (!result.add(kind))
                result.remove(kind);
        }
        return result;
    }

    private static String toString(int[] values)
    {
        if (values == null)
            return null;
        StringBuilder sb = new StringBuilder();
        int length = values.length;
        for (int i = 0; i < length; i++)
        {
            sb.append(values[i]);
            if (i < length - 1)
                sb.append(',');
        }
        return sb.toString();
    }

    private static int[] toIntArray(String s) throws NumberFormatException
    {
        if (s == null)
            return null;
        String[] values = s.split(","); //$NON-NLS-1$
        int length = values.length;
        int[] result = new int[length];
        for (int i = 0; i < length; i++)
        {
            result[i] = Integer.parseInt(values[i]);
        }
        return result;
    }

    /**
     * Represents an entry of the type hierarchy view history list.
     */
    protected abstract static class HistoryEntry
    {
        private final Object[] inputElements;

        /**
         * Constructs a history entry for the given input elements.
         * Clients <b>must not</b> modify the given array afterwards.
         *
         * @param inputElements never <code>null</code>; never empty
         */
        protected HistoryEntry(Object[] inputElements)
        {
            if (inputElements.length == 0)
                throw new AssertionError();
            this.inputElements = inputElements;
        }

        /**
         * Returns the input elements for this history entry.
         *
         * @return the input elements (never <code>null</code>; never empty).
         *  Clients <b>must not</b> modify the returned array.
         */
        public final Object[] getInputElements()
        {
            return inputElements;
        }

        @Override
        public boolean equals(Object obj)
        {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            HistoryEntry other = (HistoryEntry)obj;
            if (!Arrays.equals(inputElements, other.inputElements))
                return false;
            return true;
        }

        @Override
        public int hashCode()
        {
            return Arrays.hashCode(inputElements);
        }

        /**
         * Returns a user-readable text label for this history entry.
         * <p>
         * Default implementation composes a label based on labels for
         * input elements. It invokes {@link #getElementLabel(Object)}
         * to obtain a label for an input element.
         * </p>
         *
         * @return the text label of the history entry (never <code>null</code>)
         */
        public String getLabel()
        {
            switch (inputElements.length)
            {
            case 1:
                return MessageFormat.format(
                    Messages.TypeHierarchyViewPart_History_entry_label__0,
                    getElementLabel(inputElements[0]));
            case 2:
                return MessageFormat.format(
                    Messages.TypeHierarchyViewPart_History_entry_label__0__1,
                    getElementLabel(inputElements[0]), getElementLabel(
                        inputElements[1]));
            default:
                return MessageFormat.format(
                    Messages.TypeHierarchyViewPart_History_entry_label__0__1_more,
                    getElementLabel(inputElements[0]), getElementLabel(
                        inputElements[1]));
            }
        }

        /**
         * Returns a user-readable text label for the given element.
         *
         * @param element the given element
         * @return the text label of the element (never <code>null</code>)
         */
        protected abstract String getElementLabel(Object element);

        /**
         * Returns an image descriptor for this history entry.
         * <p>
         * Default implementation always returns <code>null</code>.
         * </p>
         *
         * @return the image descriptor of the history entry
         *  (may be <code>null</code>)
         */
        public ImageDescriptor getImageDescriptor()
        {
            return null;
        }
    }

    /**
     * Helper for opening editors on the viewer's selection.
     */
    protected class OpenEditorHelper
        extends OpenAndLinkWithEditorHelper
    {
        /**
         * Creates a new helper for the given viewer.
         *
         * @param viewer the viewer
         */
        public OpenEditorHelper(StructuredViewer viewer)
        {
            super(viewer);
        }

        @Override
        protected void activate(ISelection selection)
        {
            Object element = getSelectedElement(selection);
            if (element != null)
            {
                try
                {
                    revealInEditor(element, true, false);
                }
                catch (PartInitException e)
                {
                    // cannot happen: may not open a new editor
                }
            }
        }

        @Override
        protected void open(ISelection selection, boolean activate)
        {
            Object element = getSelectedElement(selection);
            if (element != null)
            {
                try
                {
                    revealInEditor(element, activate, true);
                }
                catch (PartInitException e)
                {
                    ErrorDialog.openError(getSite().getShell(),
                        Messages.TypeHierarchyViewPart_Open_selected_element,
                        Messages.TypeHierarchyViewPart_Error_opening_editor,
                        e.getStatus());
                }
            }
        }
    }

    private class FocusOnSelectionAction
        extends BaseSelectionListenerAction
    {
        FocusOnSelectionAction()
        {
            super(
                Messages.TypeHierarchyViewPart_Focus_on_selection_action_text);
            setToolTipText(
                Messages.TypeHierarchyViewPart_Focus_on_selection_action_tooltip);
        }

        @Override
        public void run()
        {
            setInputElements(getStructuredSelection().toArray());
        }

        @Override
        protected boolean updateSelection(IStructuredSelection selection)
        {
            return !selection.isEmpty() && arePossibleInputElements(
                selection.toArray());
        }
    }

    private class RefreshAction
        extends Action
    {
        RefreshAction()
        {
            setText(Messages.TypeHierarchyViewPart_Refresh_action_text);
            setToolTipText(
                Messages.TypeHierarchyViewPart_Refresh_action_tooltip);
            setImageDescriptor(Activator.getImageDescriptor(
                Activator.IMG_ELCL_REFRESH));
            setDisabledImageDescriptor(Activator.getImageDescriptor(
                Activator.IMG_DLCL_REFRESH));
        }

        @Override
        public void run()
        {
            refresh();
        }
    }

    private class SetHierarchyKindAction
        extends Action
    {
        final TypeHierarchyKind kind;

        SetHierarchyKindAction(TypeHierarchyKind kind)
        {
            super(null, AS_RADIO_BUTTON);
            this.kind = kind;
            switch (kind)
            {
            case TYPES:
                setText(
                    Messages.TypeHierarchyViewPart_Show_type_hierarchy_action_text);
                setToolTipText(
                    Messages.TypeHierarchyViewPart_Show_type_hierarchy_action_tooltip);
                setImageDescriptor(Activator.getImageDescriptor(
                    Activator.IMG_ELCL_TH_TYPES));
                break;
            case SUPERTYPES:
                setText(
                    Messages.TypeHierarchyViewPart_Show_supertype_hierarchy_action_text);
                setToolTipText(
                    Messages.TypeHierarchyViewPart_Show_supertype_hierarchy_action_tooltip);
                setImageDescriptor(Activator.getImageDescriptor(
                    Activator.IMG_ELCL_TH_SUPERTYPES));
                break;
            case SUBTYPES:
                setText(
                    Messages.TypeHierarchyViewPart_Show_subtype_hierarchy_action_text);
                setToolTipText(
                    Messages.TypeHierarchyViewPart_Show_subtype_hierarchy_action_tooltip);
                setImageDescriptor(Activator.getImageDescriptor(
                    Activator.IMG_ELCL_TH_SUBTYPES));
                break;
            }
            if (kind == getHierarchyKind())
                setChecked(true);
        }

        @Override
        public void run()
        {
            setHierarchyKind(kind);
        }
    }

    private class SetLayoutModeAction
        extends Action
    {
        final int layoutMode;

        SetLayoutModeAction(int layoutMode)
        {
            super(null, AS_RADIO_BUTTON);
            this.layoutMode = layoutMode;
            switch (layoutMode)
            {
            case SWT.VERTICAL:
                setText(
                    Messages.TypeHierarchyViewPart_Layout_vertical_action_text);
                setToolTipText(
                    Messages.TypeHierarchyViewPart_Layout_vertical_action_tooltip);
                setImageDescriptor(Activator.getImageDescriptor(
                    Activator.IMG_ELCL_LAYOUT_VERTICAL));
                break;
            case SWT.HORIZONTAL:
                setText(
                    Messages.TypeHierarchyViewPart_Layout_horizontal_action_text);
                setToolTipText(
                    Messages.TypeHierarchyViewPart_Layout_horizontal_action_tooltip);
                setImageDescriptor(Activator.getImageDescriptor(
                    Activator.IMG_ELCL_LAYOUT_HORIZONTAL));
                break;
            case LAYOUT_AUTOMATIC:
                setText(
                    Messages.TypeHierarchyViewPart_Layout_automatic_action_text);
                setToolTipText(
                    Messages.TypeHierarchyViewPart_Layout_automatic_action_tooltip);
                setImageDescriptor(Activator.getImageDescriptor(
                    Activator.IMG_ELCL_LAYOUT_AUTOMATIC));
                break;
            case SWT.NONE:
                setText(
                    Messages.TypeHierarchyViewPart_Layout_single_action_text);
                setToolTipText(
                    Messages.TypeHierarchyViewPart_Layout_single_action_tooltip);
                setImageDescriptor(Activator.getImageDescriptor(
                    Activator.IMG_ELCL_LAYOUT_SINGLE));
                break;
            default:
                throw new IllegalArgumentException();
            }
            if (layoutMode == getLayoutMode())
                setChecked(true);
        }

        @Override
        public void run()
        {
            setLayoutMode(layoutMode);
        }
    }
}
