/*******************************************************************************
 * Copyright (c) 2000, 2023 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.jsdt.internal.ui.browsing;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.wst.jsdt.core.IClassFile;
import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
import org.eclipse.wst.jsdt.core.IJavaScriptElement;
import org.eclipse.wst.jsdt.core.IJavaScriptProject;
import org.eclipse.wst.jsdt.core.IPackageFragment;
import org.eclipse.wst.jsdt.core.IPackageFragmentRoot;
import org.eclipse.wst.jsdt.core.IType;
import org.eclipse.wst.jsdt.core.JavaScriptCore;
import org.eclipse.wst.jsdt.internal.corext.util.Messages;
import org.eclipse.wst.jsdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.wst.jsdt.internal.ui.IProductConstants;
import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin;
import org.eclipse.wst.jsdt.internal.ui.ProductProperties;
import org.eclipse.wst.jsdt.internal.ui.JavaPluginImages;
import org.eclipse.wst.jsdt.internal.ui.actions.MultiActionGroup;
import org.eclipse.wst.jsdt.internal.ui.actions.SelectAllAction;
import org.eclipse.wst.jsdt.internal.ui.filters.NonJavaElementFilter;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.DecoratingJavaLabelProvider;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.JavaUILabelProvider;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.LibraryFilter;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.ProblemTableViewer;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.ProblemTreeViewer;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.StatusBarUpdater;
import org.eclipse.wst.jsdt.ui.JavaScriptElementComparator;
import org.eclipse.wst.jsdt.ui.JavaScriptElementLabels;
import org.eclipse.wst.jsdt.ui.JavaScriptUI;
import org.eclipse.wst.jsdt.ui.PreferenceConstants;


public class PackagesView extends JavaBrowsingPart{

	private static final String TAG_VIEW_STATE= ".viewState"; //$NON-NLS-1$
	private static final int LIST_VIEW_STATE= 0;
	private static final int TREE_VIEW_STATE= 1;


	private static class StatusBarUpdater4LogicalPackage extends StatusBarUpdater {

		private StatusBarUpdater4LogicalPackage(IStatusLineManager statusLineManager) {
			super(statusLineManager);
		}

		protected String formatMessage(ISelection sel) {
			if (sel instanceof IStructuredSelection) {
				IStructuredSelection selection= (IStructuredSelection)sel;
				int nElements= selection.size();
				Object elem= selection.getFirstElement();
				if (nElements == 1 && (elem instanceof LogicalPackage))
					return formatLogicalPackageMessage((LogicalPackage) elem);
			}
			return super.formatMessage(sel);
		}

		private String formatLogicalPackageMessage(LogicalPackage logicalPackage) {
			IPackageFragment[] fragments= logicalPackage.getFragments();
			StringBuffer buf= new StringBuffer(logicalPackage.getElementName());
			buf.append(JavaScriptElementLabels.CONCAT_STRING);
			String message= ""; //$NON-NLS-1$
			boolean firstTime= true;
			for (int i= 0; i < fragments.length; i++) {
				IPackageFragment fragment= fragments[i];
				IJavaScriptElement element= fragment.getParent();
				if (element instanceof IPackageFragmentRoot) {
					IPackageFragmentRoot root= (IPackageFragmentRoot) element;
					String label= JavaScriptElementLabels.getElementLabel(root, JavaScriptElementLabels.DEFAULT_QUALIFIED | JavaScriptElementLabels.ROOT_QUALIFIED);
					if (firstTime) {
						buf.append(label);
						firstTime= false;
					}
					else
						message= Messages.format(JavaBrowsingMessages.StatusBar_concat, new String[] {message, label});
				}
			}
			buf.append(message);
			return buf.toString();
		}
	}


	private SelectAllAction fSelectAllAction;

	private int fCurrViewState;

	private PackageViewerWrapper fWrappedViewer;

	private MultiActionGroup fSwitchActionGroup;
	private boolean fLastInputWasProject;

	/**
	 * Adds filters the viewer of this part.
	 */
	protected void addFilters() {
		super.addFilters();
		getViewer().addFilter(createNonJavaElementFilter());
		getViewer().addFilter(new LibraryFilter());
	}


	/**
	 * Creates new NonJavaElementFilter and overrides method select to allow for
	 * LogicalPackages.
	 * @return NonJavaElementFilter
	 */
	protected NonJavaElementFilter createNonJavaElementFilter() {
		return new NonJavaElementFilter(){
			public boolean select(Viewer viewer, Object parent, Object element){
				return ((element instanceof IJavaScriptElement) || (element instanceof LogicalPackage) || (element instanceof IFolder));
			}
		};
	}

	public void init(IViewSite site, IMemento memento) throws PartInitException {
		super.init(site, memento);
		//this must be created before all actions and filters
		fWrappedViewer= new PackageViewerWrapper();
		restoreLayoutState(memento);
	}

	private void restoreLayoutState(IMemento memento) {
		if (memento == null) {
			//read state from the preference store
			IPreferenceStore store= JavaScriptPlugin.getDefault().getPreferenceStore();
			fCurrViewState= store.getInt(this.getViewSite().getId() + TAG_VIEW_STATE);
		} else {
			//restore from memento
			Integer integer= memento.getInteger(this.getViewSite().getId() + TAG_VIEW_STATE);
			if ((integer == null) || !isValidState(integer.intValue())) {
				fCurrViewState= LIST_VIEW_STATE;
			} else fCurrViewState= integer.intValue();
		}
	}

	private boolean isValidState(int state) {
		return (state==LIST_VIEW_STATE) || (state==TREE_VIEW_STATE);
	}



	/*
	 * @see org.eclipse.ui.IViewPart#saveState(org.eclipse.ui.IMemento)
	 */
	public void saveState(IMemento memento) {
		super.saveState(memento);
		memento.putInteger(this.getViewSite().getId()+TAG_VIEW_STATE,fCurrViewState);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.internal.ui.browsing.JavaBrowsingPart#createViewer(org.eclipse.swt.widgets.Composite)
	 */
	protected StructuredViewer createViewer(Composite parent) {
		//Creates the viewer of this part dependent on the current layout.
		StructuredViewer viewer;
		if(isInListState())
			viewer= createTableViewer(parent);
		else
			viewer= createTreeViewer(parent);

		fWrappedViewer.setViewer(viewer);
		return fWrappedViewer;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.internal.ui.browsing.JavaBrowsingPart#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class key) {
		if (key == IShowInTargetList.class) {
			return new IShowInTargetList() {
				public String[] getShowInTargetIds() {
					String explorerViewID = ProductProperties.getProperty(IProductConstants.PERSPECTIVE_EXPLORER_VIEW);
					if (explorerViewID != null) {
						return new String[] { explorerViewID, JavaScriptUI.ID_PACKAGES, IPageLayout.ID_PROJECT_EXPLORER };
					}
					else {
						return new String[] { JavaScriptUI.ID_PACKAGES, IPageLayout.ID_PROJECT_EXPLORER };
					}
				}
			};
		}
		return super.getAdapter(key);
	}

	protected boolean isInListState() {
		return fCurrViewState== LIST_VIEW_STATE;
	}

	private ProblemTableViewer createTableViewer(Composite parent) {
		return new PackagesViewTableViewer(parent, SWT.MULTI);
	}

	private ProblemTreeViewer createTreeViewer(Composite parent) {
		return new PackagesViewTreeViewer(parent, SWT.MULTI);
	}

	/**
	 * Overrides the createContentProvider from JavaBrowsingPart
	 * Creates the content provider of this part.
	 */
	protected IContentProvider createContentProvider() {
		if(isInListState())
			return new PackagesViewFlatContentProvider(fWrappedViewer.getViewer());
		else return new PackagesViewHierarchicalContentProvider(fWrappedViewer.getViewer());
	}

	protected JavaUILabelProvider createLabelProvider() {
		if(isInListState())
			return createListLabelProvider();
		else return createTreeLabelProvider();
	}

	private JavaUILabelProvider createTreeLabelProvider() {
		return new PackagesViewLabelProvider(PackagesViewLabelProvider.HIERARCHICAL_VIEW_STATE);
	}

	private JavaUILabelProvider createListLabelProvider() {
		return new PackagesViewLabelProvider(PackagesViewLabelProvider.FLAT_VIEW_STATE);
	}

	/**
	 * Returns the context ID for the Help system
	 *
	 * @return	the string used as ID for the Help context
	 */
	protected String getHelpContextId() {
		return IJavaHelpContextIds.PACKAGES_BROWSING_VIEW;
	}

	protected String getLinkToEditorKey() {
		return PreferenceConstants.LINK_BROWSING_PACKAGES_TO_EDITOR;
	}

	/**
	 * Answers if the given <code>element</code> is a valid
	 * input for this part.
	 *
	 * @param 	element	the object to test
	 * @return	<true> if the given element is a valid input
	 */
	protected boolean isValidInput(Object element) {
		if (element instanceof IJavaScriptProject || (element instanceof IPackageFragmentRoot && ((IJavaScriptElement)element).getElementName() != IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH))
			try {
				IJavaScriptProject jProject= ((IJavaScriptElement)element).getJavaScriptProject();
				if (jProject != null)
					return jProject.getProject().hasNature(JavaScriptCore.NATURE_ID);
			} catch (CoreException ex) {
				return false;
			}
		return false;
	}

	/**
	 * Answers if the given <code>element</code> is a valid
	 * element for this part.
	 *
	 * @param 	element	the object to test
	 * @return	<true> if the given element is a valid element
	 */
	protected boolean isValidElement(Object element) {
		if (element instanceof IPackageFragment) {
			IJavaScriptElement parent= ((IPackageFragment)element).getParent();
			if (parent != null)
				return super.isValidElement(parent) || super.isValidElement(parent.getJavaScriptProject());
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.internal.ui.browsing.JavaBrowsingPart#findElementToSelect(org.eclipse.wst.jsdt.core.IJavaScriptElement)
	 */
	protected IJavaScriptElement findElementToSelect(IJavaScriptElement je) {
		if (je == null)
			return null;

		switch (je.getElementType()) {
			case IJavaScriptElement.PACKAGE_FRAGMENT:
				return je;
			case IJavaScriptElement.JAVASCRIPT_UNIT:
				return ((IJavaScriptUnit)je).getParent();
			case IJavaScriptElement.CLASS_FILE:
				return ((IClassFile)je).getParent();
			case IJavaScriptElement.TYPE:
				return ((IType)je).getPackageFragment();
			default:
				return findElementToSelect(je.getParent());
		}
	}

	/*
	 * @see org.eclipse.wst.jsdt.internal.ui.browsing.JavaBrowsingPart#setInput(java.lang.Object)
	 */
	protected void setInput(Object input) {
		setViewerWrapperInput(input);
		super.updateTitle();
	}

	private void setViewerWrapperInput(Object input) {
		fWrappedViewer.setViewerInput(input);
	}

	/**
	 * @see org.eclipse.wst.jsdt.internal.ui.browsing.JavaBrowsingPart#fillActionBars(org.eclipse.ui.IActionBars)
	 */
	protected void fillActionBars(IActionBars actionBars) {
		super.fillActionBars(actionBars);
		fSwitchActionGroup.fillActionBars(actionBars);
	}



	private void setUpViewer(StructuredViewer viewer){
		Assert.isTrue(viewer != null);

		JavaUILabelProvider labelProvider= createLabelProvider();
		viewer.setLabelProvider(createDecoratingLabelProvider(labelProvider));

		viewer.setComparator(createJavaElementComparator());
		viewer.setUseHashlookup(true);

		createContextMenu();

		//disapears when control disposed
		addKeyListener();

		//this methods only adds listeners to the viewer,
		//these listenters disapear when the viewer is disposed
		hookViewerListeners();

		// Set content provider
		viewer.setContentProvider(createContentProvider());
		//Disposed when viewer's Control is disposed
		initDragAndDrop();

	}

	//alter sorter to include LogicalPackages
	protected JavaScriptElementComparator createJavaElementComparator() {
		return new JavaScriptElementComparator(){
			public int category(Object element) {
				if (element instanceof LogicalPackage) {
					LogicalPackage cp= (LogicalPackage) element;
					return super.category(cp.getFragments()[0]);
				} else return super.category(element);
			}
			public int compare(Viewer viewer, Object e1, Object e2){
				if (e1 instanceof LogicalPackage) {
					LogicalPackage cp= (LogicalPackage) e1;
					e1= cp.getFragments()[0];
				}
				if (e2 instanceof LogicalPackage) {
					LogicalPackage cp= (LogicalPackage) e2;
					e2= cp.getFragments()[0];
				}
				return super.compare(viewer, e1, e2);
			}
		};
	}

	protected StatusBarUpdater createStatusBarUpdater(IStatusLineManager slManager) {
		return new StatusBarUpdater4LogicalPackage(slManager);
	}

	protected void setSiteSelectionProvider(){
		getSite().setSelectionProvider(fWrappedViewer);
	}

	void adjustInputAndSetSelection(Object o) {
		if (!(o instanceof LogicalPackage)) {
			super.adjustInputAndSetSelection(o);
			return;
		}

		LogicalPackage lp= (LogicalPackage)o;
		if (!lp.getJavaProject().equals(getInput()))
			setInput(lp.getJavaProject());

		setSelection(new StructuredSelection(lp), true);
	}

	//do the same thing as the JavaBrowsingPart but with wrapper
	protected void createActions() {
		super.createActions();

		createSelectAllAction();

		//create the switch action group
		fSwitchActionGroup= createSwitchActionGroup();
	}

	private MultiActionGroup createSwitchActionGroup(){

		LayoutAction switchToFlatViewAction= new LayoutAction(JavaBrowsingMessages.PackagesView_flatLayoutAction_label,LIST_VIEW_STATE);
		LayoutAction switchToHierarchicalViewAction= new LayoutAction(JavaBrowsingMessages.PackagesView_HierarchicalLayoutAction_label, TREE_VIEW_STATE);
		JavaPluginImages.setLocalImageDescriptors(switchToFlatViewAction, "flatLayout.gif"); //$NON-NLS-1$
		JavaPluginImages.setLocalImageDescriptors(switchToHierarchicalViewAction, "hierarchicalLayout.gif"); //$NON-NLS-1$

		return new LayoutActionGroup(new IAction[]{switchToFlatViewAction,switchToHierarchicalViewAction}, fCurrViewState);
	}

	private static class LayoutActionGroup extends MultiActionGroup {

		LayoutActionGroup(IAction[] actions, int index) {
			super(actions, index);
		}

		public void fillActionBars(IActionBars actionBars) {
			//create new layout group
			IMenuManager manager= actionBars.getMenuManager();
			final IContributionItem groupMarker= new GroupMarker("layout"); //$NON-NLS-1$
			manager.add(groupMarker);
			IMenuManager newManager= new MenuManager(JavaBrowsingMessages.PackagesView_LayoutActionGroup_layout_label);
			manager.appendToGroup("layout", newManager); //$NON-NLS-1$
			super.addActions(newManager);
		}
	}


	/**
	 * Switches between flat and hierarchical state.
	 */
	private class LayoutAction extends Action {

		private int fState;

		public LayoutAction(String text, int state) {
			super(text, IAction.AS_RADIO_BUTTON);
			fState= state;
			if (state == PackagesView.LIST_VIEW_STATE)
				PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.LAYOUT_FLAT_ACTION);
			else
				PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.LAYOUT_HIERARCHICAL_ACTION);
		}

		public int getState() {
			return fState;
		}

		public void setRunnable(Runnable runnable) {
			Assert.isNotNull(runnable);
		}

		/*
		 * @see org.eclipse.jface.action.IAction#run()
		 */
		public void run() {
			switchViewer(fState);
		}
	}

	private void switchViewer(int state) {
		//Indicate which viewer is to be used
		if (fCurrViewState == state)
			return;
		else {
			fCurrViewState= state;
			IPreferenceStore store= JavaScriptPlugin.getDefault().getPreferenceStore();
			store.setValue(getViewSite().getId() + TAG_VIEW_STATE, state);
		}

		//get the information from the existing viewer
		StructuredViewer viewer= fWrappedViewer.getViewer();
		Object object= viewer.getInput();
		ISelection selection= viewer.getSelection();

		// create and set up the new viewer
		Control control= createViewer(fWrappedViewer.getControl().getParent()).getControl();

		setUpViewer(fWrappedViewer);

		createSelectAllAction();

		// add the selection information from old viewer
		fWrappedViewer.setViewerInput(object);
		fWrappedViewer.getControl().setFocus();
		fWrappedViewer.setSelection(selection, true);

		// dispose old viewer
		viewer.getContentProvider().dispose();
		viewer.getControl().dispose();

		// layout the new viewer
		if (control != null && !control.isDisposed()) {
			control.setVisible(true);
			control.getParent().layout(true);
		}
	}

	private void createSelectAllAction() {
		IActionBars actionBars= getViewSite().getActionBars();
		if (isInListState()) {
			fSelectAllAction= new SelectAllAction((TableViewer)fWrappedViewer.getViewer());
			actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), fSelectAllAction);
		} else {
			actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), null);
			fSelectAllAction= null;
		}
		actionBars.updateActionBars();
	}

	protected IJavaScriptElement findInputForJavaElement(IJavaScriptElement je) {
		// null check has to take place here as well (not only in
		// findInputForJavaElement(IJavaScriptElement, boolean) since we
		// are accessing the Java element
		if (je == null)
			return null;
		if(je.getElementType() == IJavaScriptElement.PACKAGE_FRAGMENT_ROOT || je.getElementType() == IJavaScriptElement.JAVASCRIPT_PROJECT)
			return findInputForJavaElement(je, true);
		else
			return findInputForJavaElement(je, false);

	}

	protected IJavaScriptElement findInputForJavaElement(IJavaScriptElement je, boolean canChangeInputType) {
		if (je == null || !je.exists())
			return null;

		if (isValidInput(je)) {

			//don't update if input must be project (i.e. project is used as source folder)
			if (canChangeInputType)
				fLastInputWasProject= je.getElementType() == IJavaScriptElement.JAVASCRIPT_PROJECT;
			return je;
		} else if (fLastInputWasProject) {
			IPackageFragmentRoot packageFragmentRoot= (IPackageFragmentRoot)je.getAncestor(IJavaScriptElement.PACKAGE_FRAGMENT_ROOT);
			if (!packageFragmentRoot.isExternal())
				return je.getJavaScriptProject();
		}

		return findInputForJavaElement(je.getParent(), canChangeInputType);
	}

	/**
	 * Override the getText and getImage methods for the DecoratingLabelProvider
	 * to handel the decoration of logical packages.
	 *
	 * @see org.eclipse.wst.jsdt.internal.ui.browsing.JavaBrowsingPart#createDecoratingLabelProvider(JavaUILabelProvider)
	 */
	protected DecoratingJavaLabelProvider createDecoratingLabelProvider(JavaUILabelProvider provider) {
		return new DecoratingJavaLabelProvider(provider, false, isInListState()) {

			public String getText(Object element){
				if (element instanceof LogicalPackage) {
					LogicalPackage el= (LogicalPackage) element;
					return super.getText(el.getFragments()[0]);
				} else return super.getText(element);
			}

			public Image getImage(Object element) {
				if(element instanceof LogicalPackage){
					LogicalPackage el= (LogicalPackage) element;
					ILabelDecorator decorator= getLabelDecorator();
					IPackageFragment[] fragments= el.getFragments();

					Image image= super.getImage(el);
					for (int i= 0; i < fragments.length; i++) {
						IPackageFragment fragment= fragments[i];
						Image decoratedImage= decorator.decorateImage(image, fragment);
						if(decoratedImage != null)
							image= decoratedImage;
					}
					return image;
				} else return super.getImage(element);
			}

		};
	}

	/*
	 * Overridden from JavaBrowsingPart to handel LogicalPackages and tree
	 * structure.
	 * @see org.eclipse.wst.jsdt.internal.ui.browsing.JavaBrowsingPart#adjustInputAndSetSelection(org.eclipse.wst.jsdt.core.IJavaScriptElement)
	 */
	void adjustInputAndSetSelection(IJavaScriptElement je) {

		IJavaScriptElement jElementToSelect= findElementToSelect(je);
		LogicalPackagesProvider p= (LogicalPackagesProvider) fWrappedViewer.getContentProvider();

		Object elementToSelect= jElementToSelect;
		if (jElementToSelect != null && jElementToSelect.getElementType() == IJavaScriptElement.PACKAGE_FRAGMENT) {
			IPackageFragment pkgFragment= (IPackageFragment)jElementToSelect;
			elementToSelect= p.findLogicalPackage(pkgFragment);
			if (elementToSelect == null)
				elementToSelect= pkgFragment;
		}

		IJavaScriptElement newInput= findInputForJavaElement(je);
		if (elementToSelect == null && !isValidInput(newInput))
			setInput(null);
		else if (elementToSelect == null || getViewer().testFindItem(elementToSelect) == null) {

			//optimization, if you are in the same project but expansion hasn't happened
			Object input= getViewer().getInput();
			if (elementToSelect != null && newInput != null) {
				if (newInput.equals(input)) {
					getViewer().reveal(elementToSelect);
				// Adjust input to selection
				} else {
					setInput(newInput);
					getViewer().reveal(elementToSelect);
				}
			} else
				setInput(newInput);

			if (elementToSelect instanceof IPackageFragment) {
				IPackageFragment pkgFragment= (IPackageFragment)elementToSelect;
				elementToSelect= p.findLogicalPackage(pkgFragment);
				if (elementToSelect == null)
					elementToSelect= pkgFragment;
			}
		}

		ISelection selection;
		if (elementToSelect != null)
			selection= new StructuredSelection(elementToSelect);
		else
			selection= StructuredSelection.EMPTY;
		setSelection(selection, true);
	}

}
