/*=============================================================================#
 # Copyright (c) 2009, 2018 Stephan Wahlbrink and others.
 # 
 # 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, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.internal.r.objectbrowser;

import static org.eclipse.statet.ecommons.ui.actions.UIActions.ADDITIONS_GROUP_ID;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler2;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
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.ViewerCell;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.commands.IElementUpdater;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.handlers.CollapseAllHandler;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.menus.CommandContributionItemParameter;
import org.eclipse.ui.menus.UIElement;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;

import org.eclipse.statet.ecommons.collections.FastList;
import org.eclipse.statet.ecommons.models.core.util.ElementPartition;
import org.eclipse.statet.ecommons.ts.core.Tool;
import org.eclipse.statet.ecommons.ts.core.ToolRunnable;
import org.eclipse.statet.ecommons.ui.actions.HandlerContributionItem;
import org.eclipse.statet.ecommons.ui.actions.SearchContributionItem;
import org.eclipse.statet.ecommons.ui.components.StatusInfo;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.util.ColumnHoverManager;
import org.eclipse.statet.ecommons.ui.util.ColumnHoverStickyManager;
import org.eclipse.statet.ecommons.ui.util.ColumnWidgetTokenOwner;
import org.eclipse.statet.ecommons.ui.util.InformationDispatchHandler;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.PostSelectionProviderProxy;
import org.eclipse.statet.ecommons.ui.util.StatusLineMessageManager;
import org.eclipse.statet.ecommons.ui.util.TreeSelectionProxy;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ecommons.ui.workbench.WorkbenchUIUtils;

import org.eclipse.statet.base.ui.StatetImages;
import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.internal.r.ui.rtools.RunPrintInR;
import org.eclipse.statet.ltk.core.IElementName;
import org.eclipse.statet.ltk.ui.IElementNameProvider;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditorCommandIds;
import org.eclipse.statet.ltk.ui.sourceediting.assist.IInfoHover;
import org.eclipse.statet.ltk.ui.util.ViewerDragSupport;
import org.eclipse.statet.nico.core.runtime.ToolProcess;
import org.eclipse.statet.nico.core.util.IToolProvider;
import org.eclipse.statet.nico.core.util.IToolRetargetable;
import org.eclipse.statet.nico.ui.IToolRegistry;
import org.eclipse.statet.nico.ui.IToolRegistryListener;
import org.eclipse.statet.nico.ui.NicoUI;
import org.eclipse.statet.nico.ui.ToolSessionUIData;
import org.eclipse.statet.nico.ui.actions.ToolRetargetableHandler;
import org.eclipse.statet.r.console.core.AbstractRDataRunnable;
import org.eclipse.statet.r.console.core.IRDataAdapter;
import org.eclipse.statet.r.console.core.RConsoleTool;
import org.eclipse.statet.r.console.core.RProcess;
import org.eclipse.statet.r.console.core.RProcessREnvironment;
import org.eclipse.statet.r.console.core.RWorkspace;
import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.core.model.RElementComparator;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.ui.RLabelProvider;
import org.eclipse.statet.r.ui.rtool.RElementInfoHoverCreator;
import org.eclipse.statet.r.ui.rtool.RElementInfoTask;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RReference;


public class ObjectBrowserView extends ViewPart implements IToolProvider {
	
	
	private static final String FILTER_USERSPACEONLY_SETTINGS_KEY = "filter.only_userspace.enabled"; //$NON-NLS-1$
	private static final String FILTER_INTERNALINCLUDE_SETTINGS_KEY = "filter.include_internal.enabled"; //$NON-NLS-1$
	private static final String SORT_BYTYPE_SETTINGS_KEY = "sort.by_name.enabled"; //$NON-NLS-1$
	
	static final RElementComparator ELEMENTNAME_COMPARATOR = new RElementComparator();
	private static final ViewerComparator TYPE_COMPARATOR = new SortByTypeComparator();
	
	private static final String OPEN_COMMAND_ID = "org.eclipse.jdt.ui.edit.text.java.open.editor"; //$NON-NLS-1$
	
	
	private class RefreshWorkspaceR extends AbstractRDataRunnable {
		
		public RefreshWorkspaceR() {
			super("r/objectbrowser/refreshWorkspace.force", "Update Object Browser"); //$NON-NLS-1$
		}
		
		@Override
		public boolean changed(final int event, final Tool tool) {
			if (event == MOVING_FROM) {
				return false;
			}
			return true;
		}
		
		@Override
		protected void run(final IRDataAdapter r,
				final IProgressMonitor monitor) throws CoreException {
			boolean current;
			synchronized (ObjectBrowserView.this.processLock) {
				current = (r.getTool() != getTool());
			}
			final IWorkbenchSiteProgressService progressService = getViewSite().getService(IWorkbenchSiteProgressService.class);
			if (current && progressService != null) {
				progressService.incrementBusy();
			}
			try {
				ObjectBrowserView.this.fInputUpdater.forceOnWorkspaceChange();
				r.refreshWorkspaceData(RWorkspace.REFRESH_COMPLETE, monitor);
			}
			finally {
				if (current && progressService != null) {
					progressService.decrementBusy();
				}
			}
		}
		
	}
	
	private class RefreshHandler extends ToolRetargetableHandler {
		
		private final ElementUpdater fUpdater = new ElementUpdater(IWorkbenchCommandConstants.FILE_REFRESH);
		
		public RefreshHandler() {
			super(ObjectBrowserView.this, getSite());
			init();
		}
		
		@Override
		protected Object doExecute(final ExecutionEvent event) {
			scheduleUpdateAll();
			return null;
		}
		
		@Override
		protected void doRefresh() {
			super.doRefresh();
			this.fUpdater.schedule();
		}
		
	}
	
	private class FilterUserspaceHandler extends AbstractHandler implements IElementUpdater {
		
		@Override
		public Object execute(final ExecutionEvent event) throws ExecutionException {
			ObjectBrowserView.this.fFilterUserspace = !ObjectBrowserView.this.fFilterUserspace;
			ObjectBrowserView.this.fSettings.put(FILTER_USERSPACEONLY_SETTINGS_KEY, ObjectBrowserView.this.fFilterUserspace);
			ObjectBrowserView.this.fInputUpdater.forceUpdate(ObjectBrowserView.this.process);
			ObjectBrowserView.this.fInputUpdater.schedule();
			return null;
		}
		
		@Override
		public void updateElement(final UIElement element, final Map parameters) {
			WorkbenchUIUtils.aboutToUpdateCommandsElements(this, element);
			try {
				element.setChecked(ObjectBrowserView.this.fFilterUserspace);
			}
			finally {
				WorkbenchUIUtils.finalizeUpdateCommandsElements(this);
			}
		}
		
	}
	
	private class FilterInternalHandler extends AbstractHandler implements IElementUpdater {
		
		@Override
		public Object execute(final ExecutionEvent event) throws ExecutionException {
			ObjectBrowserView.this.fFilterIncludeInternal = !ObjectBrowserView.this.fFilterIncludeInternal;
			ObjectBrowserView.this.fSettings.put(FILTER_INTERNALINCLUDE_SETTINGS_KEY, ObjectBrowserView.this.fFilterIncludeInternal);
			updateFilter();
			return null;
		}
		
		@Override
		public void updateElement(final UIElement element, final Map parameters) {
			WorkbenchUIUtils.aboutToUpdateCommandsElements(this, element);
			try {
				element.setChecked(ObjectBrowserView.this.fFilterIncludeInternal);
			}
			finally {
				WorkbenchUIUtils.finalizeUpdateCommandsElements(this);
			}
		}
		
	}
	
	private class SortByTypeHandler extends AbstractHandler implements IElementUpdater {
		
		@Override
		public Object execute(final ExecutionEvent event) throws ExecutionException {
			ObjectBrowserView.this.fSortByType = !ObjectBrowserView.this.fSortByType;
			ObjectBrowserView.this.fSettings.put(SORT_BYTYPE_SETTINGS_KEY, ObjectBrowserView.this.fSortByType);
			updateSorter();
			return null;
		}
		
		@Override
		public void updateElement(final UIElement element, final Map parameters) {
			WorkbenchUIUtils.aboutToUpdateCommandsElements(this, element);
			try {
				element.setChecked(ObjectBrowserView.this.fSortByType);
			}
			finally {
				WorkbenchUIUtils.finalizeUpdateCommandsElements(this);
			}
		}
		
	}
	
	private class TreeElementSelection extends TreeSelectionProxy implements IElementNameProvider {
		
		public TreeElementSelection(final ITreeSelection selection) {
			super(selection);
		}
		
		@Override
		public IElementName getElementName(final Object selectionElement) {
			if (selectionElement instanceof TreePath) { 
				return getFQElementName((TreePath) selectionElement);
			}
			return null;
		}
		
	}
	
	private class TreeSelectionProvider extends PostSelectionProviderProxy {
		
		public TreeSelectionProvider() {
			super(ObjectBrowserView.this.fTreeViewer);
		}
		
		@Override
		protected ISelection getSelection(final ISelection originalSelection) {
			return new TreeElementSelection((ITreeSelection) originalSelection);
		}
		
	}
	
	private class HoverManager extends ColumnHoverManager {
		
		HoverManager() {
			super(ObjectBrowserView.this.fTreeViewer, ObjectBrowserView.this.fTokenOwner, new RElementInfoHoverCreator(IInfoHover.MODE_TOOLTIP));
			
			final ColumnHoverStickyManager stickyManager = new ColumnHoverStickyManager(ObjectBrowserView.this.fTokenOwner, this);
			getInternalAccessor().setInformationControlReplacer(stickyManager);
		}
		
		@Override
		protected Object prepareHoverInformation(final ViewerCell cell) {
			final TreePath treePath = cell.getViewerRow().getTreePath();
			final RElementName elementName = getFQElementName(treePath);
			if (elementName != null && elementName.getScope() != null) {
				return elementName;
			}
			return null;
		}
		
		@Override
		protected Object getHoverInformation(final Object element) {
			if (element instanceof RElementName && ObjectBrowserView.this.process != null) {
				final RElementInfoTask updater = new RElementInfoTask((RElementName) element);
				return updater.load(getTool(), getSubjectControl(), ObjectBrowserView.this);
			}
			return null;
		}
		
	}
	
	
	private TreeViewer fTreeViewer;
	private TreeSelectionProvider fTreeSelectionProvider;
	private ColumnWidgetTokenOwner fTokenOwner;
	private Clipboard fClipboard;
	private StatusLineMessageManager statusLine;
	
	private IDialogSettings fSettings;
	
	final Object processLock = new Object();
	private RProcess process; // note: we write only in ui thread
	
	private IToolRegistryListener fToolRegistryListener;
	private final FastList<IToolRetargetable> fToolListenerList= new FastList<>(IToolRetargetable.class);
	
	private final RefreshWorkspaceR fManualRefreshRunnable = new RefreshWorkspaceR();
	
	private final ContentJob fInputUpdater = new ContentJob(this);
	
	private ContentProvider contentProvider;
	
	private boolean fFilterUserspace;
	private boolean fFilterIncludeInternal;
	private String fFilterText;
	private boolean fSortByType;
	
	private SearchContributionItem fSearchTextItem;
	
	private boolean fFilterUserspaceActivated;
	
	private CopyElementNameHandler fCopyElementNameHandler;
	private DeleteHandler fDeleteElementHandler;
	private PrintHandler fPrintElementHandler;
	private IHandler2 fOpenInEditorHandler;
	
	private Object fCurrentInfoObject;
	
	private ColumnHoverManager fHoveringController;
	
	private AbstractHandler fSearchStartHandler;
	
	private HandlerContributionItem fRefreshToolbarItem;
	private HandlerContributionItem fRefreshMenuItem;
	private boolean fRefreshDirtyIndicator;
	
	
	public ObjectBrowserView() {
	}
	
	@Override
	public void init(final IViewSite site, final IMemento memento) throws PartInitException {
		super.init(site, memento);
		
		this.statusLine = new StatusLineMessageManager(site.getActionBars().getStatusLineManager());
		
		this.fSettings = DialogUtils.getDialogSettings(RUIPlugin.getInstance(), "ObjectBrowser");
		
		this.fFilterUserspaceActivated = this.fFilterUserspace = this.fSettings.getBoolean(FILTER_USERSPACEONLY_SETTINGS_KEY);
		this.fFilterIncludeInternal = this.fSettings.getBoolean(FILTER_INTERNALINCLUDE_SETTINGS_KEY);
		this.fSortByType = this.fSettings.getBoolean(SORT_BYTYPE_SETTINGS_KEY);
	}
	
	@Override
	public void saveState(final IMemento memento) {
		super.saveState(memento);
		
		this.fSettings = DialogUtils.getDialogSettings(RUIPlugin.getInstance(), "ObjectBrowser");
	}
	
	
	@Override
	public void createPartControl(final Composite parent) {
		parent.setLayout(LayoutUtils.newSashGrid());
		
		this.fTreeViewer = new TreeViewer(parent, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI);
		this.fTreeViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 3));
		this.fTreeViewer.setUseHashlookup(true);
		
		this.fTreeSelectionProvider = new TreeSelectionProvider();
		
		this.fTreeViewer.setLabelProvider(new RLabelProvider(RLabelProvider.COUNT) {
			@Override
			protected String getEnvCountInfo(final RProcessREnvironment envir) {
				final StringBuilder textBuilder = getTextBuilder();
				textBuilder.append(" ("); //$NON-NLS-1$
				final ContentInput input = ObjectBrowserView.this.contentProvider.getInput();
				if (input != null && input.hasEnvFilter()) {
					final Object[] children = input.getEnvFilterChildren(envir);
					if (children != null) {
						textBuilder.append(children.length);
					}
					else {
						textBuilder.append('-');
					}
					textBuilder.append('/');
				}
				textBuilder.append(envir.getLength());
				textBuilder.append(')');
				return textBuilder.toString();
			}
		});
		this.fTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
			@Override
			public void doubleClick(final DoubleClickEvent event) {
				final IStructuredSelection selection = (IStructuredSelection) event.getSelection();
				if (selection.size() != 1) {
					return;
				}
				final Object element = selection.getFirstElement();
				if (element instanceof RObject) {
					final RObject object = (RObject) element;
					switch (object.getRObjectType()) {
					case RObject.TYPE_ENVIRONMENT:
					case RObject.TYPE_LIST:
					case RObject.TYPE_DATAFRAME:
					case RObject.TYPE_S4OBJECT:
					case RObject.TYPE_REFERENCE:
						ObjectBrowserView.this.fTreeViewer.setExpandedState(element, !ObjectBrowserView.this.fTreeViewer.getExpandedState(element));
					}
				}
			}
		});
		this.fTreeSelectionProvider.addPostSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(final SelectionChangedEvent event) {
				updateSelectionInfo((ITreeSelection) event.getSelection());
			}
		});
		this.contentProvider = new ContentProvider();
		this.fTreeViewer.setContentProvider(this.contentProvider);
		updateSorter();
		this.fTreeViewer.setInput(this);
		
		this.fTokenOwner = new ColumnWidgetTokenOwner(this.fTreeViewer);
		this.fHoveringController = new HoverManager();
		this.fHoveringController.setSizeConstraints(100, 12, false, true);
		this.fHoveringController.install(this.fTreeViewer.getTree());
		
		createActions();
		hookContextMenu();
		getSite().setSelectionProvider(this.fTreeSelectionProvider);
		
		final ViewerDragSupport dragSupport = new ViewerDragSupport(this.fTreeViewer);
		dragSupport.addDragSourceListener(new ViewerDragSupport.TextDragSourceListener(this.fTreeViewer));
		dragSupport.init();
		
		// listen on console changes
		final IToolRegistry toolRegistry = NicoUI.getToolRegistry();
		this.fToolRegistryListener = new IToolRegistryListener() {
			@Override
			public void toolSessionActivated(final ToolSessionUIData sessionData) {
				final ToolProcess process = sessionData.getProcess();
				UIAccess.getDisplay().syncExec(new Runnable() {
					@Override
					public void run() {
						connect(process);
					}
				});
			}
			@Override
			public void toolTerminated(final ToolSessionUIData sessionData) {
				final ToolProcess process = sessionData.getProcess();
				UIAccess.getDisplay().syncExec(new Runnable() {
					@Override
					public void run() {
						if (process == getTool()) {
							connect(null);
						}
					}
				});
			}
		};
		toolRegistry.addListener(this.fToolRegistryListener, getViewSite().getPage());
		connect(toolRegistry.getActiveToolSession(getViewSite().getPage()).getProcess());
	}
	
	TreeViewer getViewer() {
		return this.fTreeViewer;
	}
	
	private void createActions() {
		final IHandlerService handlerService = getSite().getService(IHandlerService.class);
		final IContextService contexts = getSite().getService(IContextService.class);
		
		contexts.activateContext("org.eclipse.statet.workbench.contexts.StructuredElementViewer"); //$NON-NLS-1$
		
		final RefreshHandler refreshHandler = new RefreshHandler();
		handlerService.activateHandler(IWorkbenchCommandConstants.FILE_REFRESH, refreshHandler);
		final CollapseAllHandler collapseAllHandler = new CollapseAllHandler(this.fTreeViewer);
		handlerService.activateHandler(CollapseAllHandler.COMMAND_ID, collapseAllHandler);
		this.fCopyElementNameHandler = new CopyElementNameHandler(this);
		handlerService.activateHandler(ISourceEditorCommandIds.COPY_ELEMENT_NAME, this.fCopyElementNameHandler);
		handlerService.activateHandler(IWorkbenchCommandConstants.EDIT_COPY, this.fCopyElementNameHandler);
		this.fDeleteElementHandler = new DeleteHandler(this);
		handlerService.activateHandler(IWorkbenchCommandConstants.EDIT_DELETE, this.fDeleteElementHandler);
		this.fPrintElementHandler = new PrintHandler(this);
		handlerService.activateHandler(RunPrintInR.COMMAND_ID, this.fPrintElementHandler);
		final InformationDispatchHandler infoHandler = new InformationDispatchHandler(this.fTokenOwner);
		handlerService.activateHandler(InformationDispatchHandler.COMMAND_ID, infoHandler);
		this.fOpenInEditorHandler = new OpenInEditorHandler();
		handlerService.activateHandler(OPEN_COMMAND_ID, this.fOpenInEditorHandler);
		
		this.fSearchTextItem = new SearchContributionItem("search.text", //$NON-NLS-1$
				SearchContributionItem.VIEW_TOOLBAR, true ) {
			@Override
			protected void search() {
				ObjectBrowserView.this.fFilterText = getText();
				updateFilter();
			}
		};
		this.fSearchTextItem.setToolTip("Filter Elements");
		this.fSearchTextItem.setSizeControl(this.fTreeViewer.getControl().getParent());
		this.fSearchTextItem.setResultControl(this.fTreeViewer.getTree());
		
		this.fSearchStartHandler = new AbstractHandler() {
			@Override
			public Object execute(final ExecutionEvent arg0) {
				ObjectBrowserView.this.fSearchTextItem.show();
				return null;
			}
		};
		handlerService.activateHandler(IWorkbenchCommandConstants.EDIT_FIND_AND_REPLACE, this.fSearchStartHandler);
		// add next/previous handler
		
		final ToggleAutoRefreshHandler autoRefreshHandler = new ToggleAutoRefreshHandler(this);
		
		final IActionBars actionBars = getViewSite().getActionBars();
		final IMenuManager viewMenu = actionBars.getMenuManager();
		final IToolBarManager viewToolbar = actionBars.getToolBarManager();
		
		viewMenu.add(new HandlerContributionItem(new CommandContributionItemParameter(getSite(),
				"Filter.OnlyUserspace", HandlerContributionItem.NO_COMMAND_ID, null, //$NON-NLS-1$
				null, null, null,
				"Show non-&package Variables only", null, null,
				HandlerContributionItem.STYLE_CHECK, null, false),
				new FilterUserspaceHandler() ));
		viewMenu.add(new HandlerContributionItem(new CommandContributionItemParameter(getSite(),
				"Filter.IncludeInternal", HandlerContributionItem.NO_COMMAND_ID, null, //$NON-NLS-1$
				null, null, null,
				"Show &Internal Variables ('.*')", null, null,
				HandlerContributionItem.STYLE_CHECK, null, false),
				new FilterInternalHandler() ));
		viewMenu.add(new HandlerContributionItem(new CommandContributionItemParameter(getSite(),
				"Sort.ByType", HandlerContributionItem.NO_COMMAND_ID, null, //$NON-NLS-1$
				null, null, null,
				"Sort by &Type", null, null,
				HandlerContributionItem.STYLE_CHECK, null, false),
				new SortByTypeHandler() ));
		
		viewMenu.add(new Separator());
		final HandlerContributionItem autoRefreshItem = new HandlerContributionItem(new CommandContributionItemParameter(getSite(),
				null, HandlerContributionItem.NO_COMMAND_ID, null, 
				null, null, null,
				"Refresh &automatically", null, null,
				HandlerContributionItem.STYLE_CHECK, null, false),
				autoRefreshHandler );
		viewMenu.add(autoRefreshItem);
		this.fRefreshMenuItem = new HandlerContributionItem(new CommandContributionItemParameter(getSite(),
				null, IWorkbenchCommandConstants.FILE_REFRESH, null, 
				StatetImages.getDescriptor(StatetImages.TOOL_REFRESH), StatetImages.getDescriptor(StatetImages.TOOLD_REFRESH), null,
				"&Refresh", null, null,
				HandlerContributionItem.STYLE_PUSH, null, false),
				refreshHandler );
		viewMenu.add(this.fRefreshMenuItem);
		
		viewMenu.addMenuListener(new IMenuListener() {
			@Override
			public void menuAboutToShow(final IMenuManager manager) {
				autoRefreshItem.update();
			}
		});
		
		viewToolbar.add(this.fSearchTextItem);
		viewToolbar.add(new Separator());
		this.fRefreshToolbarItem = new HandlerContributionItem(new CommandContributionItemParameter(getSite(),
				"Refresh", IWorkbenchCommandConstants.FILE_REFRESH, null, //$NON-NLS-1$
				StatetImages.getDescriptor(StatetImages.TOOL_REFRESH), StatetImages.getDescriptor(StatetImages.TOOLD_REFRESH), null,
				null, null, null,
				HandlerContributionItem.STYLE_PUSH, null, false),
				refreshHandler);
		this.fRefreshToolbarItem.setVisible(false);
		viewToolbar.add(this.fRefreshToolbarItem);
		viewToolbar.add(new HandlerContributionItem(new CommandContributionItemParameter(getSite(),
				"Collapse.All", CollapseAllHandler.COMMAND_ID, null, //$NON-NLS-1$
				null, null, null,
				null, null, null,
				HandlerContributionItem.STYLE_PUSH, null, false),
				collapseAllHandler));
	}
	
	void updateAutoRefresh(final boolean enabled) {
		if (this.process == null || this.process.isTerminated()) {
			return;
		}
		
		if (enabled) {
			updateDirty(false);
		}
		else {
			updateDirty(this.process.getWorkspaceData().isRObjectDBDirty());
		}
		
		if (this.fRefreshToolbarItem.isVisible() != enabled) {
			return;
		}
		this.fRefreshToolbarItem.setVisible(!enabled);
		final IContributionManager manager = this.fRefreshToolbarItem.getParent();
		manager.update(true);
		this.fSearchTextItem.resize();
	}
	
	void updateDirty(final boolean enabled) {
		if (this.fRefreshDirtyIndicator == enabled) {
			return;
		}
		final ImageDescriptor icon = (enabled) ?
				RUIPlugin.getInstance().getImageRegistry().getDescriptor(RUIPlugin.IMG_LOCTOOL_REFRESH_RECOMMENDED) :
				StatetImages.getDescriptor(StatetImages.TOOL_REFRESH);
		this.fRefreshToolbarItem.setIcon(icon);
		this.fRefreshMenuItem.setIcon(icon);
		this.fRefreshDirtyIndicator = enabled;
	}
	
	
	private void hookContextMenu() {
		final MenuManager menuManager = new MenuManager("ContextMenu", //$NON-NLS-1$
				"org.eclipse.statet.r.menus.RObjectBrowserContextMenu" ); //$NON-NLS-1$
		menuManager.setRemoveAllWhenShown(true);
		menuManager.addMenuListener(new IMenuListener() {
			@Override
			public void menuAboutToShow(final IMenuManager m) {
				contextMenuAboutToShow(m);
			}
		});
		final Menu contextMenu = menuManager.createContextMenu(this.fTreeViewer.getTree());
		this.fTreeViewer.getTree().setMenu(contextMenu);
		getSite().registerContextMenu(menuManager, this.fTreeViewer);
	}
	
	private void contextMenuAboutToShow(final IMenuManager m) {
		m.add(new HandlerContributionItem(new CommandContributionItemParameter(getSite(),
				null, OPEN_COMMAND_ID, null,
				null, null, null,
				"Open in Data &Viewer", null, null,
				HandlerContributionItem.STYLE_PUSH, null, true), this.fOpenInEditorHandler));
		
		m.add(new Separator("edit"));
		m.add(new HandlerContributionItem(new CommandContributionItemParameter(getSite(),
				"Copy.ElementName", ISourceEditorCommandIds.COPY_ELEMENT_NAME, null, //$NON-NLS-1$
				null, null, null,
				null, null, null,
				HandlerContributionItem.STYLE_PUSH, null, false),
				this.fCopyElementNameHandler));
		m.add(new HandlerContributionItem(new CommandContributionItemParameter(getSite(),
				"Delete", IWorkbenchCommandConstants.EDIT_DELETE, null, //$NON-NLS-1$
				null, null, null,
				null, null, null,
				HandlerContributionItem.STYLE_PUSH, null, false),
				this.fDeleteElementHandler));
		m.add(new Separator());
		m.add(new HandlerContributionItem(new CommandContributionItemParameter(getSite(),
				null, RunPrintInR.COMMAND_ID, null, 
				null, null, null,
				null, null, null,
				HandlerContributionItem.STYLE_PUSH, null, false),
				this.fPrintElementHandler));
		
		m.add(new Separator(ADDITIONS_GROUP_ID));
	}
	
	/** May only be called in UI thread */
	public void connect(final ToolProcess tool) {
		if (this.process == tool) {
			return;
		}
		final RProcess oldProcess = this.process;
		if (oldProcess != null) {
			oldProcess.getWorkspaceData().removePropertyListener(this.fInputUpdater);
		}
		synchronized (this.processLock) {
			this.process = (RProcess) 
					((tool != null && tool.isProvidingFeatureSet(RConsoleTool.R_DATA_FEATURESET_ID)) ?
							tool : null);
		}
		if (this.fHoveringController != null) {
			this.fHoveringController.stop();
		}
		if (oldProcess != null) {
			clearInfo();
			oldProcess.getQueue().remove(new ToolRunnable[] { this.fManualRefreshRunnable });
		}
		if (!UIAccess.isOkToUse(this.fTreeViewer)) {
			return;
		}
		for (final IToolRetargetable listener : this.fToolListenerList.toArray()) {
			listener.setTool(this.process);
		}
		this.fInputUpdater.forceUpdate(this.process);
		if (this.process != null) {
			this.process.getWorkspaceData().addPropertyListener(this.fInputUpdater);
			updateAutoRefresh(this.process.getWorkspaceData().isAutoRefreshEnabled());
		}
		this.fInputUpdater.schedule();
	}
	
	@Override
	public RProcess getTool() {
		return this.process;
	}
	
	public ITreeSelection getSelection() {
		return (ITreeSelection) this.fTreeViewer.getSelection();
	}
	
	
	public boolean getShowInternal() {
		return this.fFilterIncludeInternal;
	}
	
	public boolean getShowConsenseUserspace() {
		return this.fFilterUserspace;
	}
	
	public String getSearchText() {
		return this.fFilterText;
	}
	
	
	@Override
	public void addToolRetargetable(final IToolRetargetable action) {
		this.fToolListenerList.add(action);
	}
	
	@Override
	public void removeToolRetargetable(final IToolRetargetable action) {
		this.fToolListenerList.remove(action);
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public <T> T getAdapter(final Class<T> adapterType) {
		if (adapterType == Tool.class) {
			return (T) this.process;
		}
		return super.getAdapter(adapterType);
	}
	
	private void scheduleUpdateAll() {
		if (this.process != null) {
			this.process.getQueue().add(this.fManualRefreshRunnable);
		}
	}
	
	/** May only be called in UI thread (called by update job) */
	void updateViewer(final List<RProcessREnvironment> updateEnvirs, final ContentInput input) {
		if (!UIAccess.isOkToUse(this.fTreeViewer)) {
			return;
		}
		this.fHoveringController.stop();
		
		this.contentProvider.setInput(input);
		
		final boolean changed = input.processChanged;
		ISelection selection = null;
		if (changed) {
			input.processChanged = false;
		}
		/*else*/ if (input.showCondensedUserspace != this.fFilterUserspaceActivated) {
			// If filter is changed, we have to retain the selection manually
			selection = this.fTreeViewer.getSelection();
		}
		this.fFilterUserspaceActivated = input.showCondensedUserspace;
		
		final Set<RReference> previousReferences = this.contentProvider.resetUsedReferences();
		if (updateEnvirs != null) {
			for (final RProcessREnvironment entry : updateEnvirs) {
				this.fTreeViewer.refresh(entry, true);
			}
			if (!previousReferences.isEmpty()) {
				final Set<RReference> usedReferences = this.contentProvider.getUsedReferences();
				ITER_REFS: for (final RReference reference : previousReferences) {
					if (!usedReferences.contains(reference)) {
						// Update the envir copy in the viewer, if it refers to an updated envir
						for (final RProcessREnvironment entry : updateEnvirs) {
							if (entry.getHandle() == reference.getHandle()) {
								this.fTreeViewer.refresh(reference, true);
								// reference is readded automatically to new set, if necessary
								continue ITER_REFS;
							}
						}
						// Keep/readd the reference, if it refers to an envir in the search path
						for (final RProcessREnvironment entry : input.searchEnvirs) {
							if (entry.getHandle() == reference.getHandle()) {
								usedReferences.add(reference);
								continue ITER_REFS;
							}
						}
					}
				}
			}
		}
		else {
			this.fTreeViewer.refresh(true);
		}
		
		// Adapt and set selection
		if (selection != null && !selection.isEmpty()) {
			final ITreeSelection s = (ITreeSelection) selection;
			final TreePath[] paths = s.getPaths();
			int j = 0;
			for (int i = 0; i < paths.length; i++) {
				final TreePath oldPath = paths[i];
				final int count = oldPath.getSegmentCount();
				final int shift = (input.showCondensedUserspace) ? -1 : +1;
				if (count + shift < 1) {
					continue;
				}
				final Object[] newPath = new Object[count + shift];
				for (int k = (shift == -1) ? +1 : 0; k < count; k++) {
					newPath[k + shift] = oldPath.getSegment(k);
				}
				if (shift == +1) {
					newPath[0] = ContentProvider.getCombinedRElement(newPath[1]).getModelParent();
				}
				paths[j++] = new TreePath(newPath);
			}
			this.fTreeViewer.setSelection(new TreeSelection(
					(j < paths.length) ? Arrays.copyOf(paths, j) : paths),
					true );
		}
		
		// Expand Global_Env, if it is a new process and has valid input
		EXPAND_GLOBALENV : if (changed && !input.showCondensedUserspace 
				&& input.rootElements != null && input.rootElements.length > 0) {
			for (final Object element : input.rootElements) {
				if (this.fTreeViewer.getExpandedState(element)) {
					break EXPAND_GLOBALENV;
				}
			}
			this.fTreeViewer.expandToLevel(new TreePath(new Object[] { input.rootElements[0] }), 1);
		}
	}
	
	private void updateFilter() {
		this.fInputUpdater.schedule();
	}
	
	private void updateSorter() {
		this.fTreeViewer.setComparator(this.fSortByType ? TYPE_COMPARATOR : null);
	}
	
	private void updateSelectionInfo(final ITreeSelection selection) {
		final Object previousInfoObject = this.fCurrentInfoObject;
		this.fCurrentInfoObject = null;
		
		final RProcess tool = getTool();
		if (tool == null) {
			return;
		}
		if (selection.size() == 1) {
			this.fCurrentInfoObject = selection.getFirstElement();
			final TreePath treePath = selection.getPaths()[0];
			final IElementName elementName = getFQElementName(treePath);
			final String name = (elementName != null) ? elementName.getDisplayName() : null;
			if (name != null) {
				if (this.fCurrentInfoObject.equals(previousInfoObject)) {
					clearInfo();
				}
				this.statusLine.setSelectionMessage(new StatusInfo(IStatus.OK,
						NLS.bind("{0}  \u2012  {1}", name, tool.getLabel(Tool.DEFAULT_LABEL)) )); //$NON-NLS-1$
				return;
			}
		}
		clearInfo();
		if (selection.size() > 1) {
			this.statusLine.setSelectionMessage(new StatusInfo(IStatus.OK,
					NLS.bind("{0} items selected", selection.size()) ));
			return;
		}
		this.statusLine.setSelectionMessage(null);
	}
	
	private void clearInfo() {
	}
	
	/**
	 * Returns a shared clipboard resource, which can be used by actions of this view.
	 * 
	 * @return a clipboard object.
	 */
	Clipboard getClipboard() {
		if (this.fClipboard == null) {
			this.fClipboard = new Clipboard(Display.getCurrent());
		}
		return this.fClipboard;
	}
	
	StatusLineMessageManager getStatusLine() {
		return this.statusLine;
	}
	
	@Override
	public void setFocus() {
		this.fTreeViewer.getControl().setFocus();
	}
	
	@Override
	public void dispose() {
		if (this.fToolRegistryListener != null) {
			NicoUI.getToolRegistry().removeListener(this.fToolRegistryListener);
			this.fToolRegistryListener = null;
		}
		if (this.process != null) {
			this.process.getWorkspaceData().removePropertyListener(this.fInputUpdater);
			this.process.getQueue().remove(new ToolRunnable[] { this.fManualRefreshRunnable });
		}
		this.fInputUpdater.cancel();
		if (this.fHoveringController != null) {
			this.fHoveringController.dispose();
			this.fHoveringController = null;
		}
		if (this.fSearchStartHandler != null) {
			this.fSearchStartHandler.dispose();
			this.fSearchStartHandler = null;
		}
		if (this.fCopyElementNameHandler != null) {
			this.fCopyElementNameHandler.dispose();
			this.fCopyElementNameHandler = null;
		}
		if (this.fPrintElementHandler != null) {
			this.fPrintElementHandler.dispose();
			this.fPrintElementHandler = null;
		}
		
		for (final IToolRetargetable listener : this.fToolListenerList.toArray()) {
			listener.setTool(null);
		}
		
		super.dispose();
		
		if (this.fClipboard != null) {
			this.fClipboard.dispose();
			this.fClipboard = null;
		}
	}
	
	
	public RElementName getFQElementName(final TreePath treePath) {
		if (treePath.getSegmentCount() == 0) {
			return null;
		}
		int segmentIdx = 0;
		if (!this.fFilterUserspaceActivated) {
			if (treePath.getSegmentCount() == 1) { // search path item
				return ContentProvider.getCombinedRElement(treePath.getFirstSegment()).getElementName();
			}
			else { // main name at 1
				segmentIdx = 1;
			}
		}
		final List<RElementName> names= new ArrayList<>(treePath.getSegmentCount() - segmentIdx + 1);
		final CombinedRElement first= ContentProvider.getCombinedRElement(treePath.getSegment(segmentIdx++));
		names.add(first.getModelParent().getElementName());
		names.add(first.getElementName());
		while (segmentIdx < treePath.getSegmentCount()) {
			final Object object= treePath.getSegment(segmentIdx++);
			if (object instanceof ElementPartition) {
				continue;
			}
			final CombinedRElement rElement= ContentProvider.getCombinedRElement(object);
			names.add(rElement.getElementName());
		}
		return RElementName.create(names);
	}
	
}
