/*=============================================================================#
 # Copyright (c) 2005, 2020 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.ltk.ui.sourceediting;

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

import org.eclipse.core.commands.IHandler2;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ISynchronizable;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.link.ILinkedModeListener;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.projection.IProjectionListener;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.services.IServiceLocator;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
import org.eclipse.ui.texteditor.templates.ITemplatesPage;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImIdentityList;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.text.core.BasicTextRegion;
import org.eclipse.statet.jcommons.text.core.TextRegion;

import org.eclipse.statet.ecommons.preferences.PreferencesUtil;
import org.eclipse.statet.ecommons.preferences.SettingsChangeNotifier;
import org.eclipse.statet.ecommons.preferences.core.Preference;
import org.eclipse.statet.ecommons.preferences.core.util.PreferenceUtils;
import org.eclipse.statet.ecommons.text.ICharPairMatcher;
import org.eclipse.statet.ecommons.text.core.JFaceTextRegion;
import org.eclipse.statet.ecommons.text.core.sections.DocContentSections;
import org.eclipse.statet.ecommons.text.ui.TextHandlerUtil;
import org.eclipse.statet.ecommons.ui.ISettingsChangedHandler;
import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.internal.ltk.ui.EditingMessages;
import org.eclipse.statet.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.core.IModelTypeDescriptor;
import org.eclipse.statet.ltk.core.LTK;
import org.eclipse.statet.ltk.model.core.IDocumentModelProvider;
import org.eclipse.statet.ltk.model.core.IModelManager;
import org.eclipse.statet.ltk.model.core.elements.IModelElement;
import org.eclipse.statet.ltk.model.core.elements.ISourceStructElement;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnitModelInfo;
import org.eclipse.statet.ltk.ui.ElementInfoController;
import org.eclipse.statet.ltk.ui.IModelElementInputProvider;
import org.eclipse.statet.ltk.ui.ISelectionWithElementInfoListener;
import org.eclipse.statet.ltk.ui.LTKInputData;
import org.eclipse.statet.ltk.ui.LTKUI;
import org.eclipse.statet.ltk.ui.PostSelectionCancelExtension;
import org.eclipse.statet.ltk.ui.PostSelectionWithElementInfoController;
import org.eclipse.statet.ltk.ui.PostSelectionWithElementInfoController.IgnoreActivation;
import org.eclipse.statet.ltk.ui.sourceediting.actions.DeleteNextWordHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.DeletePreviousWordHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.GotoMatchingBracketHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.GotoNextWordHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.GotoPreviousWordHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.SelectNextWordHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.SelectPreviousWordHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.SpecificContentAssistHandler;
import org.eclipse.statet.ltk.ui.sourceediting.actions.ToggleCommentHandler;


/**
 * Abstract LTK based source editor.
 */
public abstract class SourceEditor1 extends TextEditor implements ISourceEditor,
			SettingsChangeNotifier.ChangeListener, IPreferenceChangeListener,
			IShowInSource, IShowInTargetList {
	
	
	protected static final ImList<String> ACTION_SET_CONTEXT_IDS= ImCollections.newIdentityList(
			"org.eclipse.statet.ltk.contexts.EditSource1MenuSet", //$NON-NLS-1$
			"org.eclipse.ui.edit.text.actionSet.presentation" ); //$NON-NLS-1$
	
	private static final ImList<String> CONTEXT_IDS= ImCollections.addElement(
			ACTION_SET_CONTEXT_IDS,
			"org.eclipse.statet.workbench.contexts.TextEditor" ); //$NON-NLS-1$
	
	
/*- Static utility methods --------------------------------------------------*/
	
	@Deprecated
	protected static IProjectNature getProject(final IEditorInput input, final String projectNatureId) {
		if (input != null && input instanceof IFileEditorInput) {
			final IProject project= ((IFileEditorInput) input).getFile().getProject();
			try {
				if (project != null && project.hasNature(projectNatureId)) {
					return project.getNature(projectNatureId);
				}
			}
			catch (final CoreException ignore) {}
		}
		return null;
	}
	
	/**
	 * Returns the lock object for the given annotation model.
	 * 
	 * @param annotationModel the annotation model
	 * @return the annotation model's lock object
	 */
	protected static final Object getLockObject(final IAnnotationModel annotationModel) {
		if (annotationModel instanceof ISynchronizable) {
			final Object lock= ((ISynchronizable) annotationModel).getLockObject();
			if (lock != null) {
				return lock;
			}
		}
		return annotationModel;
	}
	
	private TextRegion expand(final TextRegion region, final @Nullable TextRegion regionOpt) {
		return (regionOpt != null) ? region.expansion(regionOpt) : region;
	}
	
	
/*- Inner classes -----------------------------------------------------------*/
	
	protected class PostSelectionEditorCancel extends PostSelectionCancelExtension {
		
		public PostSelectionEditorCancel() {
		}
		
		@Override
		public void init() {
			final ISourceViewer viewer= getSourceViewer();
			if (viewer != null) {
				viewer.addTextInputListener(this);
				viewer.getDocument().addDocumentListener(this);
			}
		}
		
		@Override
		public void dispose() {
			final ISourceViewer viewer= getSourceViewer();
			if (viewer != null) {
				viewer.removeTextInputListener(this);
				final IDocument document= viewer.getDocument();
				if (document != null) {
					document.removeDocumentListener(this);
				}
			}
		}
	}
	
	private class EffectSynchonizer implements ITextEditToolSynchronizer, ILinkedModeListener {
		
		private EffectSynchonizer() {
		}
		
		@Override
		public void install(final LinkedModeModel model) {
			SourceEditor1.this.effectSynchonizerCounter++;
			if (SourceEditor1.this.markOccurrencesProvider != null) {
				SourceEditor1.this.markOccurrencesProvider.uninstall();
			}
			model.addLinkingListener(this);
		}
		
		@Override
		public void left(final LinkedModeModel model, final int flags) {
			SourceEditor1.this.effectSynchonizerCounter--;
			updateMarkOccurrencesEnablement();
		}
		
		@Override
		public void resume(final LinkedModeModel model, final int flags) {
		}
		
		@Override
		public void suspend(final LinkedModeModel model) {
		}
		
	}
	
	
/*- Fields -----------------------------------------------------------------*/
	
	private final IContentType contentType;
	private final IModelTypeDescriptor modelType;
	
	private SourceEditorViewerConfigurator configurator;
	private boolean lazySetup;
	private ISourceUnit sourceUnit;
	private ElementInfoController modelProvider;
	private PostSelectionWithElementInfoController modelPostSelection;
	protected volatile Point currentSelection;
	
	/** The outline page of this editor */
	private SourceEditor1OutlinePage outlinePage;
	
	/** The templates page of this editor */
	private ITemplatesPage templatesPage;
	
	private StructureSelectionHistory selectionHistory;
	private Preference<Boolean> foldingEnablement;
	private ProjectionSupport foldingSupport;
	private ISourceEditorAddon foldingProvider;
	private FoldingActionGroup foldingActionGroup;
	private Preference<Boolean> markOccurrencesEnablement;
	private ISourceEditorAddon markOccurrencesProvider;
	
	private EffectSynchonizer effectSynchronizer;
	private int effectSynchonizerCounter;
	
	private final CopyOnWriteIdentityListSet<IUpdate> contentUpdateables= new CopyOnWriteIdentityListSet<>();
	private final CopyOnWriteIdentityListSet<IHandler2> stateUpdateables= new CopyOnWriteIdentityListSet<>();
	
	private boolean inputChange;
	private int inputUpdate= Integer.MAX_VALUE;
	
	private ImageDescriptor imageDescriptor;
	
	
/*- Contructors ------------------------------------------------------------*/
	
	public SourceEditor1(final IContentType contentType) {
		super();
		this.contentType= contentType;
		this.modelType= LTK.getExtContentTypeManager().getModelTypeForContentType(contentType.getId());
	}
	
	
/*- Methods ----------------------------------------------------------------*/
	
	@Override
	public IContentType getContentType() {
		return this.contentType;
	}
	
	/**
	 * Returns the model type of source units of the editor.
	 * The value must not change for an editor instance and all source units
	 * in the editor must be of the same type.
	 * 
	 * @return id of the model type
	 */
	public String getModelTypeId() {
		return this.modelType.getId();
	}
	
	@Override
	protected void initializeEditor() {
		this.configurator= createConfiguration();
		super.initializeEditor();
		setCompatibilityMode(false);
		final SourceEditorViewerConfiguration configuration= this.configurator.getSourceViewerConfiguration();
		setPreferenceStore(configuration.getPreferences());
		setSourceViewerConfiguration(configuration);
		if (configuration.isSmartInsertSupported()) {
			configureInsertMode(SMART_INSERT, true);
		}
		
		PreferencesUtil.getSettingsChangeNotifier().addChangeListener(this);
	}
	
	protected abstract SourceEditorViewerConfigurator createConfiguration();
	
	protected SourceEditorViewerConfigurator createInfoConfigurator() {
		return null;
	}
	
	
	protected void enableStructuralFeatures(final IModelManager modelManager,
			final Preference<Boolean> codeFoldingEnablement,
			final Preference<Boolean> markOccurrencesEnablement) {
		this.modelProvider= new ElementInfoController(modelManager, LTK.EDITOR_CONTEXT);
		this.foldingEnablement= codeFoldingEnablement;
		this.markOccurrencesEnablement= markOccurrencesEnablement;
	}
	
	/**
	 * Overwrites the default title image (editor icon) during the initialization of the editor
	 * input.
	 * 
	 * The image is created and disposed automatically.
	 * 
	 * For example, it can be used to overwrite the default image using the image descriptor of 
	 * the editor input in {@link #setDocumentProvider(IEditorInput)}
	 * 
	 * @param descriptor the image description of the icon or <code>null</code>
	 */
	protected void overwriteTitleImage(final ImageDescriptor descriptor) {
		if (this.imageDescriptor == descriptor || (this.imageDescriptor == null && descriptor == null) ) {
			return;
		}
		if (this.imageDescriptor != null) {
			JFaceResources.getResources().destroyImage(this.imageDescriptor);
		}
		this.imageDescriptor= descriptor;
		if (this.imageDescriptor != null) {
			super.setTitleImage(JFaceResources.getResources().createImage(descriptor));
		}
	}
	
	@Override
	protected void setTitleImage(final Image titleImage) {
		if (this.imageDescriptor == null) {
			super.setTitleImage(titleImage);
		}
	}
	
	protected Collection<String> getContextIds() {
		return CONTEXT_IDS;
	}
	
	@Override
	protected void initializeKeyBindingScopes() {
		final Collection<String> ids= getContextIds();
		setKeyBindingScopes(ids.toArray(new String[ids.size()]));
	}
	
	@Override
	protected String[] collectContextMenuPreferencePages() {
		final List<String> list= new ArrayList<>();
		collectContextMenuPreferencePages(list);
		list.addAll(Arrays.asList(super.collectContextMenuPreferencePages()));
		return list.toArray(new String[list.size()]);
	}
	
	protected void collectContextMenuPreferencePages(final List<String> pageIds) {
	}
	
	
	@Override
	protected void doSetInput(final IEditorInput input) throws CoreException {
		if (this.modelProvider != null && this.sourceUnit != null) {
			this.modelProvider.setInput(null);
		}
		
		// project has changed
		final ISourceViewer sourceViewer= getSourceViewer();
		if (sourceViewer != null) {
			this.configurator.unconfigureTarget();
		}
		else {
			this.lazySetup= true;
		}
		
		this.inputChange= true;
		this.inputUpdate= 1;
		super.doSetInput(input);
		// setup in 
		//   1) setDocumentProvider -> setupConfiguration(..., input)
		//   2) handleInsertModeChanged -> setupConfiguration(..., input, SourceViewer)
		this.inputChange= false;
		this.inputUpdate= Integer.MAX_VALUE;
		
		initSmartInsert();
		
		if (input != null && this.outlinePage != null) {
			updateOutlinePageInput(this.outlinePage);
		}
	}
	
	private void initSmartInsert() {
		final SourceEditorViewerConfiguration config= this.configurator.getSourceViewerConfiguration();
		if (config.isSmartInsertSupported()) {
			if (config.isSmartInsertByDefault()) {
				setInsertMode(SMART_INSERT);
			}
			else {
				setInsertMode(INSERT);
			}
		}
	}
	
	@Override
	protected void setPartName(final String partName) {
		super.setPartName(partName);
		
		// see doSetInput
		if (this.inputChange) {
			if (this.inputUpdate != 1) {
				return;
			}
			this.inputUpdate= 2;
			final IEditorInput input= getEditorInput();
			setupConfiguration(input);
		}
	}
	
	@Override
	protected void handleInsertModeChanged() {
		// see doSetInput
		if (this.inputChange && !this.lazySetup) {
			if (this.inputUpdate != 2) {
				return;
			}
			this.inputUpdate= 3;
			final IEditorInput input= getEditorInput();
			final ISourceViewer sourceViewer= getSourceViewer();
			if (input != null && sourceViewer != null) {
				setupConfiguration(input, sourceViewer);
				this.configurator.configureTarget();
			}
			this.inputChange= false;
		}
		
		super.handleInsertModeChanged();
	}
	
	/**
	 * Subclasses should setup the SourceViewerConfiguration.
	 */
	protected void setupConfiguration(final IEditorInput newInput) {
		final IDocumentProvider documentProvider= getDocumentProvider();
		if (documentProvider instanceof IDocumentModelProvider) {
			this.sourceUnit= ((IDocumentModelProvider) documentProvider).getWorkingCopy(newInput);
			if (this.modelProvider != null) {
				this.modelProvider.setInput(this.sourceUnit);
			}
		}
	}
	
	/**
	 * Subclasses should setup the SourceViewerConfiguration.
	 */
	protected void setupConfiguration(final IEditorInput newInput, final ISourceViewer sourceViewer) {
		updateStateDependentActions();
	}
	
	@Override
	public ISourceUnit getSourceUnit() {
		return this.sourceUnit;
	}
	
	
	@Override
	public SourceViewer getViewer() {
		return (SourceViewer) super.getSourceViewer();
	}
	
	@Override
	public DocContentSections getDocumentContentInfo() {
		return this.configurator.getDocumentContentInfo();
	}
	
	@Override
	public IWorkbenchPart getWorkbenchPart() {
		return this;
	}
	
	@Override
	public IServiceLocator getServiceLocator() {
		return getSite();
	}
	
	@Override
	public boolean isEditable(final boolean validate) {
		if (validate) {
			return SourceEditor1.this.validateEditorInputState();
		}
		return SourceEditor1.this.isEditorInputModifiable();
	}
	
	public IModelElementInputProvider getModelInputProvider() {
		return this.modelProvider;
	}
	
	public void addPostSelectionWithElementInfoListener(final ISelectionWithElementInfoListener listener) {
		if (this.modelPostSelection != null) {
			this.modelPostSelection.addListener(listener);
		}
	}
	
	public void removePostSelectionWithElementInfoListener(final ISelectionWithElementInfoListener listener) {
		if (this.modelPostSelection != null) {
			this.modelPostSelection.removeListener(listener);
		}
	}
	
	
	@Override
	public void createPartControl(final Composite parent) {
		super.createPartControl(parent);
		
		if (this.modelProvider != null) {
			this.modelPostSelection= new PostSelectionWithElementInfoController(this.modelProvider,
					(IPostSelectionProvider) getSelectionProvider(), new PostSelectionEditorCancel());
			this.modelPostSelection.addListener(new ISelectionWithElementInfoListener() {
				@Override
				public void inputChanged() {
				}
				@Override
				public void stateChanged(final LTKInputData state) {
					final TextRegion toHighlight= getRangeToHighlight(state);
					if (toHighlight != null) {
						setHighlightRange(toHighlight.getStartOffset(), toHighlight.getLength(), false);
					}
					else {
						resetHighlightRange();
					}
				}
			});
		}
		if (this.foldingEnablement != null) {
			final ProjectionViewer viewer= (ProjectionViewer) getSourceViewer();
			
			this.foldingSupport= new ProjectionSupport(viewer, getAnnotationAccess(), getSharedColors());
			final SourceEditorViewerConfigurator config= createInfoConfigurator();
			if (config != null) {
				final IInformationControlCreator presentationCreator= new IInformationControlCreator() {
					@Override
					public IInformationControl createInformationControl(final Shell parent) {
						return new SourceViewerInformationControl(parent, createInfoConfigurator(), getOrientation());
					}
				};
				this.foldingSupport.setHoverControlCreator(new IInformationControlCreator() {
					@Override
					public IInformationControl createInformationControl(final Shell parent) {
						return new SourceViewerInformationControl(parent, createInfoConfigurator(), getOrientation(), presentationCreator);
					}
				});
				this.foldingSupport.setInformationPresenterControlCreator(presentationCreator);
			}
			this.foldingSupport.install();
			viewer.addProjectionListener(new IProjectionListener() {
				@Override
				public void projectionEnabled() {
					installFoldingProvider();
				}
				@Override
				public void projectionDisabled() {
					uninstallFoldingProvider();
				}
			});
			PreferenceUtils.getInstancePrefs().addPreferenceNodeListener(
					this.foldingEnablement.getQualifier(), this);
			updateFoldingEnablement();
		}
		if (this.markOccurrencesEnablement != null) {
			PreferenceUtils.getInstancePrefs().addPreferenceNodeListener(
					this.markOccurrencesEnablement.getQualifier(), this);
			updateMarkOccurrencesEnablement();
		}
		
		if (this.lazySetup) {
			this.lazySetup= false;
			setupConfiguration(getEditorInput(), getSourceViewer());
			this.configurator.setTarget(this);
		}
		
		{	final IContextService contextService= getServiceLocator().getService(IContextService.class);
			for (final String id : getContextIds()) {
				contextService.activateContext(id);
			}
		}
	}
	
	@Override
	protected ISourceViewer createSourceViewer(final Composite parent, final IVerticalRuler ruler, final int styles) {
		this.fAnnotationAccess= getAnnotationAccess();
		this.fOverviewRuler= createOverviewRuler(getSharedColors());
		
		final ISourceViewer viewer= new SourceEditorViewer(parent,
				ruler, getOverviewRuler(), isOverviewRulerVisible(), styles,
				getSourceViewerFlags() );
		// ensure decoration support has been created and configured.
		getSourceViewerDecorationSupport(viewer);
		
		return viewer;
	}
	
	protected int getSourceViewerFlags() {
		return 0;
	}
	
	protected IRegion getRangeToReveal(final ISourceUnitModelInfo modelInfo, final ISourceStructElement element) {
		return null;
	}
	
	protected TextRegion getRangeToHighlight(final LTKInputData state) {
		final ISourceUnitModelInfo info= state.getInputInfo();
		if (info == null) {
			return null;
		}
		
		final TextRegion region= getRangeToHighlight(info, state.getModelSelection());
		if (region != null) {
			return region;
		}
		
		final AstNode root= info.getAst().getRoot();
		TRY_AST: if (root != null) {
			final ITextSelection selection= (ITextSelection) state.getSelection();
			final int n= root.getChildCount();
			for (int i= 0; i < n; i++) {
				final AstNode child= root.getChild(i);
				if (selection.getOffset() >= child.getStartOffset()) {
					if (selection.getOffset()+selection.getLength() <= child.getEndOffset()) {
						return child;
					}
				}
				else {
					break TRY_AST;
				}
			}
		}
		return null;
	}
	
	protected TextRegion getRangeToHighlight(final ISourceUnitModelInfo info, ISourceStructElement element) {
		while (element != null) {
			switch (element.getElementType() & IModelElement.MASK_C1) {
			case IModelElement.C1_CLASS:
			case IModelElement.C1_METHOD:
				return expand(element.getSourceRange(), element.getDocumentationRange());
			case IModelElement.C1_SOURCE:
				if ((element.getElementType() & IModelElement.MASK_C2) == IModelElement.C2_SOURCE_CHUNK) {
					return expand(element.getSourceRange(), element.getDocumentationRange());
				}
				return null;
			case IModelElement.C1_VARIABLE:
				if ((element.getSourceParent().getElementType() & IModelElement.MASK_C2) == IModelElement.C2_SOURCE_FILE) {
					return expand(element.getSourceRange(), element.getDocumentationRange());
				}
				//$FALL-THROUGH$
			default:
				element= element.getSourceParent();
				continue;
			}
		}
		return null;
	}
	
	
	protected ISourceEditorAddon createCodeFoldingProvider() {
		return null;
	}
	
	private void installFoldingProvider() {
		uninstallFoldingProvider();
		this.foldingProvider= createCodeFoldingProvider();
		if (this.foldingProvider != null) {
			this.foldingProvider.install(this);
		}
	}
	
	private void uninstallFoldingProvider() {
		if (this.foldingProvider != null) {
			this.foldingProvider.uninstall();
			this.foldingProvider= null;
		}
	}
	
	private void updateFoldingEnablement() {
		if (this.foldingEnablement != null) {
			UIAccess.getDisplay().asyncExec(new Runnable() {
				@Override
				public void run() {
					final Boolean enable= PreferenceUtils.getInstancePrefs().getPreferenceValue(SourceEditor1.this.foldingEnablement);
					final ProjectionViewer viewer= (ProjectionViewer) getSourceViewer();
					if (enable != null && UIAccess.isOkToUse(viewer)) {
						if (enable != viewer.isProjectionMode()) {
							viewer.doOperation(ProjectionViewer.TOGGLE);
						}
					}
				}
			});
		}
	}
	
	
	protected ISourceEditorAddon createMarkOccurrencesProvider() {
		return null;
	}
	
	private void uninstallMarkOccurrencesProvider() {
		if (this.markOccurrencesProvider != null) {
			this.markOccurrencesProvider.uninstall();
			this.markOccurrencesProvider= null;
		}
	}
	
	private void updateMarkOccurrencesEnablement() {
		if (this.markOccurrencesEnablement != null) {
			UIAccess.getDisplay().asyncExec(new Runnable() {
				@Override
				public void run() {
					final Boolean enable= PreferenceUtils.getInstancePrefs().getPreferenceValue(SourceEditor1.this.markOccurrencesEnablement);
					if (enable) {
						if (SourceEditor1.this.markOccurrencesProvider == null) {
							SourceEditor1.this.markOccurrencesProvider= createMarkOccurrencesProvider();
						}
						if (SourceEditor1.this.markOccurrencesProvider != null && SourceEditor1.this.effectSynchonizerCounter == 0) {
							SourceEditor1.this.markOccurrencesProvider.install(SourceEditor1.this);
						}
					}
					else {
						uninstallMarkOccurrencesProvider();
					}
				}
			});
		}
	}
	
	
	@Override
	protected void configureSourceViewerDecorationSupport(final SourceViewerDecorationSupport support) {
		super.configureSourceViewerDecorationSupport(support);
		this.configurator.configureSourceViewerDecorationSupport(support);
	}
	
	@Override
	protected void createActions() {
		super.createActions();
		final IHandlerService handlerService= getServiceLocator().getService(IHandlerService.class);
		final StyledText textWidget= getViewer().getTextWidget();
		
		{	final IHandler2 handler= new GotoNextWordHandler(this);
			setAction(ITextEditorActionDefinitionIds.WORD_NEXT, null);
			TextHandlerUtil.disable(textWidget, ITextEditorActionDefinitionIds.WORD_NEXT);
			handlerService.activateHandler(ITextEditorActionDefinitionIds.WORD_NEXT, handler);
		}
		{	final IHandler2 handler= new GotoPreviousWordHandler(this);
			setAction(ITextEditorActionDefinitionIds.WORD_PREVIOUS, null);
			TextHandlerUtil.disable(textWidget, ITextEditorActionDefinitionIds.WORD_NEXT);
			handlerService.activateHandler(ITextEditorActionDefinitionIds.WORD_PREVIOUS, handler);
		}
		{	final IHandler2 handler= new SelectNextWordHandler(this);
			setAction(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT, null);
			TextHandlerUtil.disable(textWidget, ITextEditorActionDefinitionIds.SELECT_WORD_NEXT);
			handlerService.activateHandler(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT, handler);
		}
		{	final IHandler2 handler= new SelectPreviousWordHandler(this);
			setAction(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS, null);
			TextHandlerUtil.disable(textWidget, ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS);
			handlerService.activateHandler(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS, handler);
		}
		{	final IHandler2 handler= new DeleteNextWordHandler(this);
			setAction(ITextEditorActionDefinitionIds.DELETE_NEXT_WORD, null);
			TextHandlerUtil.disable(textWidget, ITextEditorActionDefinitionIds.DELETE_NEXT_WORD);
			handlerService.activateHandler(ITextEditorActionDefinitionIds.DELETE_NEXT_WORD, handler);
			markAsStateDependentHandler(handler, true);
		}
		{	final IHandler2 handler= new DeletePreviousWordHandler(this);
			setAction(ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD, null);
			TextHandlerUtil.disable(textWidget, ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD);
			handlerService.activateHandler(ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD, handler);
			markAsStateDependentHandler(handler, true);
		}
		
		final ICharPairMatcher matcher= this.configurator.getSourceViewerConfiguration().getPairMatcher();
		if (matcher != null) {
			handlerService.activateHandler(ISourceEditorCommandIds.GOTO_MATCHING_BRACKET,
					new GotoMatchingBracketHandler(matcher, this));
		}
		{	final IHandler2 handler= new SpecificContentAssistHandler(this,
					this.configurator.getSourceViewerConfiguration().getContentAssist() );
			handlerService.activateHandler(ISourceEditorCommandIds.SPECIFIC_CONTENT_ASSIST_COMMAND_ID, handler);
		}
		
		{	final IHandler2 handler= createToggleCommentHandler();
			if (handler != null) {
				handlerService.activateHandler(ISourceEditorCommandIds.TOGGLE_COMMENT, handler);
			}
		}
		{	final IHandler2 handler= createCorrectIndentHandler();
			if (handler != null) {
				handlerService.activateHandler(LTKUI.CORRECT_INDENT_COMMAND_ID, handler);
			}
		}
		
		if (this.foldingEnablement != null) {
			this.foldingActionGroup= createFoldingActionGroup();
		}
		if (this.modelProvider != null) {
			this.selectionHistory= new StructureSelectionHistory(this);
			handlerService.activateHandler(ISourceEditorCommandIds.SELECT_ENCLOSING,
					new StructureSelectHandler.Enclosing(this, this.selectionHistory));
			handlerService.activateHandler(ISourceEditorCommandIds.SELECT_PREVIOUS,
					new StructureSelectHandler.Previous(this, this.selectionHistory));
			handlerService.activateHandler(ISourceEditorCommandIds.SELECT_NEXT,
					new StructureSelectHandler.Next(this, this.selectionHistory));
			final StructureSelectionHistoryBackHandler backHandler= new StructureSelectionHistoryBackHandler(this, this.selectionHistory);
			handlerService.activateHandler(ISourceEditorCommandIds.SELECT_LAST, backHandler);
			this.selectionHistory.addUpdateListener(backHandler);
		}
		
		//WorkbenchHelp.setHelp(action, IJavaHelpContextIds.TOGGLE_COMMENT_ACTION);
	}
	
	protected FoldingActionGroup createFoldingActionGroup() {
		return new FoldingActionGroup(this, (ProjectionViewer) getSourceViewer());
	}
	
	protected IHandler2 createToggleCommentHandler() {
		final IHandler2 commentHandler= new ToggleCommentHandler(this);
		markAsStateDependentHandler(commentHandler, true);
		return commentHandler;
	}
	
	protected IHandler2 createCorrectIndentHandler() {
		return null;
	}
	
	protected void markAsContentDependentHandler(final IUpdate handler, final boolean mark) {
		if (mark) {
			this.contentUpdateables.add(handler);
		}
		else {
			this.contentUpdateables.remove(handler);
		}
	}
	
	protected void markAsStateDependentHandler(final IHandler2 handler, final boolean mark) {
		if (mark) {
			this.stateUpdateables.add(handler);
		}
		else {
			this.stateUpdateables.remove(handler);
		}
	}
	
	@Override
	protected void updateContentDependentActions() {
		super.updateContentDependentActions();
		for (final IUpdate handler : this.contentUpdateables.toList()) {
			handler.update();
		}
	}
	
	@Override
	protected void updateStateDependentActions() {
		super.updateStateDependentActions();
		final ImIdentityList<IHandler2> listeners= this.stateUpdateables.toList();
		for (final IHandler2 handler : listeners) {
			handler.setEnabled(this);
		}
	}
	
	@Override
	protected void rulerContextMenuAboutToShow(final IMenuManager menu) {
		super.rulerContextMenuAboutToShow(menu);
		if (this.foldingActionGroup != null) {
			final IMenuManager foldingMenu= new MenuManager(EditingMessages.CodeFolding_label, "projection"); //$NON-NLS-1$
			menu.appendToGroup(ITextEditorActionConstants.GROUP_RULERS, foldingMenu);
			this.foldingActionGroup.fillMenu(foldingMenu);
		}
	}
	
	
	@Override
	public ITextEditToolSynchronizer getTextEditToolSynchronizer() {
		if (this.effectSynchronizer == null) {
			this.effectSynchronizer= new EffectSynchonizer();
		}
		return this.effectSynchronizer;
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public <T> @Nullable T getAdapter(final Class<T> adapterType) {
		if (adapterType == ISourceEditor.class) {
			return (T) this;
		}
		if (adapterType == ISourceViewer.class) {
			return (T) getSourceViewer();
		}
		
		if (adapterType == IContentType.class) {
			return (T) this.contentType;
		}
		
		if (adapterType == IContentOutlinePage.class) {
			if (this.outlinePage == null) {
				this.outlinePage= createOutlinePage();
				if (this.outlinePage != null) {
					updateOutlinePageInput(this.outlinePage);
				}
			}
			return (T) this.outlinePage;
		}
		if (adapterType == ITemplatesPage.class) {
			if (this.templatesPage == null) {
				this.templatesPage= createTemplatesPage();
			}
			return (T) this.templatesPage;
		}
		if (this.foldingSupport != null) {
			final Object adapter= this.foldingSupport.getAdapter(getSourceViewer(), adapterType);
			if (adapter != null) {
				return (T) adapter;
			}
		}
		
		return super.getAdapter(adapterType);
	}
	
	
	@Override
	public void settingsChanged(final Set<String> groupIds) {
		final Map<String, Object> options= new HashMap<>();
		UIAccess.getDisplay().syncExec(new Runnable() {
			@Override
			public void run() {
				handleSettingsChanged(groupIds, options);
			}
		});
	}
	
	/**
	 * @see ISettingsChangedHandler#handleSettingsChanged(Set, Map)
	 */
	protected void handleSettingsChanged(final Set<String> groupIds, final Map<String, Object> options) {
		if (this.configurator != null) {
			this.configurator.handleSettingsChanged(groupIds, options);
		}
	}
	
	@Override
	public void preferenceChange(final PreferenceChangeEvent event) {
		if (this.foldingEnablement != null && event.getKey().equals(this.foldingEnablement.getKey())) {
			updateFoldingEnablement();
		}
		if (this.markOccurrencesEnablement != null && event.getKey().equals(this.markOccurrencesEnablement.getKey())) {
			updateMarkOccurrencesEnablement();
		}
	}
	
	protected void updateIndentSettings() {
		updateIndentPrefixes();
	}
	
	
	@Override
	protected void handleCursorPositionChanged() {
		this.currentSelection= getSourceViewer().getSelectedRange();
		super.handleCursorPositionChanged();
	}
	
	
	protected SourceEditor1OutlinePage createOutlinePage() {
		return null;
	}
	
	protected void updateOutlinePageInput(final SourceEditor1OutlinePage page) {
	}
	
	void handleOutlinePageClosed() {
		if (this.outlinePage != null) {
			this.outlinePage= null;
			resetHighlightRange();
		}
	}
	
	protected ITemplatesPage createTemplatesPage() {
		return null;
	}
	
	
	@Override
	// inject annotation painter workaround
	protected SourceViewerDecorationSupport getSourceViewerDecorationSupport(final ISourceViewer viewer) {
		if (this.fSourceViewerDecorationSupport == null) {
			this.fSourceViewerDecorationSupport= new org.eclipse.statet.ltk.ui.sourceediting.SourceViewerDecorationSupport(viewer, getOverviewRuler(), getAnnotationAccess(), getSharedColors());
			configureSourceViewerDecorationSupport(this.fSourceViewerDecorationSupport);
		}
		return this.fSourceViewerDecorationSupport;
	}
	
	@Override
	public void selectAndReveal(final int start, final int length) {
		selectAndReveal(start, length, start, length);
	}
	
	@Override
	protected void selectAndReveal(final int selectionStart, final int selectionLength, final int revealStart, final int revealLength) {
		if (this.modelPostSelection != null) {
			this.modelPostSelection.setUpdateOnSelection(true);
			try {
				super.selectAndReveal(selectionStart, selectionLength, revealStart, revealLength);
			}
			finally {
				this.modelPostSelection.setUpdateOnSelection(false);
			}
		}
		else {
			super.selectAndReveal(selectionStart, selectionLength, revealStart, revealLength);
		}
	}
	
	public void setSelection(final ISelection selection, final ISelectionWithElementInfoListener listener) {
		if (this.modelPostSelection != null && listener != null) {
			final IgnoreActivation activation= this.modelPostSelection.ignoreNext(listener);
			doSetSelection(selection);
			activation.deleteNext();
		}
		else {
			doSetSelection(selection);
		}
	}
	
	@Override
	protected void doSetSelection(final ISelection selection) {
		if (selection instanceof IStructuredSelection) {
			final IStructuredSelection structured= (IStructuredSelection) selection;
			if (!structured.isEmpty()) {
				final Object first= structured.getFirstElement();
				TextRegion region= null;
				if (first instanceof ISourceStructElement) {
					final ISourceStructElement sourceElement= (ISourceStructElement) first;
					region= sourceElement.getNameSourceRange();
					if (region == null) {
						region= sourceElement.getSourceRange();
						if (region != null) {
							region= new BasicTextRegion(region.getStartOffset());
						}
					}
					
					final ISourceUnit sourceUnit= sourceElement.getSourceUnit();
					final ISourceUnitModelInfo modelInfo= sourceUnit.getModelInfo(getModelTypeId(), 0, null);
					if (modelInfo != null) {
						final IRegion toReveal= getRangeToReveal(modelInfo, sourceElement);
						if (toReveal != null) {
							final SourceViewer viewer= getViewer();
							if (viewer instanceof ITextViewerExtension5) {
								((ITextViewerExtension5) viewer).exposeModelRange(toReveal);
							}
							getViewer().revealRange(toReveal.getOffset(), toReveal.getLength());
						}
						final TextRegion toHighlight= getRangeToHighlight(modelInfo, sourceElement);
						if (toHighlight != null) {
							setHighlightRange(toHighlight.getStartOffset(), toHighlight.getLength(), true);
						}
					}
				}
				if (region == null && first instanceof TextRegion) {
					region= (TextRegion) first;
				}
				else if (region == null && first instanceof IRegion) {
					region= JFaceTextRegion.toTextRegion((IRegion) first);
				}
				
				if (region != null) {
					selectAndReveal(region.getStartOffset(), region.getLength());
					return;
				}
			}
		}
		super.doSetSelection(selection);
	}
	
	
	@Override
	public void dispose() {
		if (this.modelProvider != null) {
			this.modelProvider.setInput(null);
			this.modelProvider.dispose();
		}
		
		PreferencesUtil.getSettingsChangeNotifier().removeChangeListener(this);
		if (this.modelPostSelection != null) {
			this.modelPostSelection.dispose();
		}
		if (this.foldingEnablement != null) {
			PreferenceUtils.getInstancePrefs().removePreferenceNodeListener(
					this.foldingEnablement.getQualifier(), this);
			uninstallFoldingProvider();
		}
		if (this.markOccurrencesEnablement != null) {
			PreferenceUtils.getInstancePrefs().removePreferenceNodeListener(
					this.markOccurrencesEnablement.getQualifier(), this);
			uninstallMarkOccurrencesProvider();
		}
		
		super.dispose();
		
		if (this.imageDescriptor != null) {
			JFaceResources.getResources().destroyImage(this.imageDescriptor);
			this.imageDescriptor= null;
		}
		
		this.sourceUnit= null;
		this.modelProvider= null;
		this.modelPostSelection= null;
	}
	
	@Override
	public ShowInContext getShowInContext() {
		final Point selectionPoint= this.currentSelection;
		final ISourceViewer sourceViewer= getSourceViewer();
		final ISourceUnit unit= getSourceUnit();
		ISelection selection= null;
		if (selectionPoint != null && unit != null && sourceViewer != null) {
			selection= new LTKInputData(unit, getSelectionProvider());
		}
		return new ShowInContext(getEditorInput(), selection);
	}
	
	@Override
	public String[] getShowInTargetIds() {
		return new String[] { IPageLayout.ID_PROJECT_EXPLORER };
	}
	
}
