/*=============================================================================#
 # 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.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.internal.text.html.BrowserInformationControl;
import org.eclipse.jface.internal.text.html.HTMLTextPresenter;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.AbstractInformationControlManager;
import org.eclipse.jface.text.AbstractReusableInformationControlCreator;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultInformationControl;
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.ITextHover;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.information.IInformationPresenter;
import org.eclipse.jface.text.information.IInformationProvider;
import org.eclipse.jface.text.information.IInformationProviderExtension2;
import org.eclipse.jface.text.information.InformationPresenter;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.quickassist.IQuickAssistAssistant;
import org.eclipse.jface.text.quickassist.IQuickAssistProcessor;
import org.eclipse.jface.text.quickassist.QuickAssistAssistant;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.ITokenScanner;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.jface.text.templates.TemplateVariableResolver;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;

import org.eclipse.statet.ecommons.templates.TemplateVariableProcessor;
import org.eclipse.statet.ecommons.templates.WordFinder;
import org.eclipse.statet.ecommons.text.ICharPairMatcher;
import org.eclipse.statet.ecommons.text.IIndentSettings;
import org.eclipse.statet.ecommons.text.IndentUtil;
import org.eclipse.statet.ecommons.text.core.sections.DocContentSections;
import org.eclipse.statet.ecommons.text.ui.DefaultBrowserInformationInput;
import org.eclipse.statet.ecommons.text.ui.presentation.ITextPresentationConstants;
import org.eclipse.statet.ecommons.text.ui.settings.DecorationPreferences;
import org.eclipse.statet.ecommons.text.ui.settings.TextStyleManager;
import org.eclipse.statet.ecommons.ui.ISettingsChangedHandler;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.util.InformationDispatchHandler;

import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin;
import org.eclipse.statet.ltk.ui.LTKUIPreferences;
import org.eclipse.statet.ltk.ui.sourceediting.assist.AssistPreferences;
import org.eclipse.statet.ltk.ui.sourceediting.assist.ContentAssist;
import org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHoverDescriptor;
import org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHoverRegistry;
import org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHoverRegistry.EffectiveHovers;


/**
 * Abstract configuration for {@link ISourceEditor}s.
 */
public abstract class SourceEditorViewerConfiguration extends TextSourceViewerConfiguration
		implements ISettingsChangedHandler {
	
	
	static final boolean DEBUG= true;
	
	
	/**
	 * Flag to enable configuration for editing / showing templates.
	 * 
	 * Overwrite: {@link #getTemplateVariableProcessor()} */
	public static final int TEMPLATE_MODE=                  1 << 3;
	
	/**
	 * Flag to enable configuration for comparing sources.
	 */
	public static final int COMPARE_MODE=                   1 << 4;
	
	
	private static class AssistInformationControlCreator extends AbstractReusableInformationControlCreator {
		
		@Override
		protected IInformationControl doCreateInformationControl(final Shell parent) {
			if (BrowserInformationControl.isAvailable(parent)) {
				return new BrowserInformationControl(parent, JFaceResources.DIALOG_FONT, false) {
					
					@Override
					public void setInformation(String content) {
						if (content.startsWith("...<br")) { // spell correction change proposal //$NON-NLS-1$
							content= content.replace("\\t", "    "); //$NON-NLS-1$ //$NON-NLS-2$
							final StringBuffer s= new StringBuffer(content.length()+1000);
							s.append("<pre>"); //$NON-NLS-1$
							s.append(content);
							s.append("</pre>"); //$NON-NLS-1$
							setInput(new DefaultBrowserInformationInput(null, "", s.toString(),  //$NON-NLS-1$
									DefaultBrowserInformationInput.FORMAT_HTMLBODY_INPUT));
						}
						else {
							setInput(new DefaultBrowserInformationInput(null, "", content, //$NON-NLS-1$
									DefaultBrowserInformationInput.FORMAT_TEXT_INPUT));
						}
					}
				};
			}
			else {
				return new DefaultInformationControl(parent, new HTMLTextPresenter(false));
			}
		}
		
	}
	
	
	private static IInformationControlCreator assistTemplateInformationControlCreator;
	
	private static IInformationControlCreator assistDefaultInformationControlCreator;
	
	private static final IInformationControlCreator DEFAULT_INFORMATION_CONTROL_CREATOR=
			new IInformationControlCreator() {
				
				@Override
				public IInformationControl createInformationControl(final Shell parent) {
					return new DefaultInformationControl(parent, true);
				}
				
			};
	
	private static final ITextHover NO_HOVER= new ITextHover() {
		@Override
		public IRegion getHoverRegion(final ITextViewer textViewer, final int offset) {
			return null;
		}
		@Override
		public String getHoverInfo(final ITextViewer textViewer, final IRegion hoverRegion) {
			return null;
		}
	};
	
	
	private final DocContentSections documentContentInfo;
	
	private final int flags;
	
	private final ISourceEditor editor;
	
	private TextStyleManager textStyles;
	private final CopyOnWriteIdentityListSet<ISettingsChangedHandler> settingsHandler= new CopyOnWriteIdentityListSet<>();
	
	private Map<String, ITokenScanner> scanners;
	
	private IPresentationReconciler presentationReconciler;
	private ICharPairMatcher pairMatcher;
	private ContentAssist contentAssistant;
	private IQuickAssistAssistant quickAssistant;
	
	private DecorationPreferences decorationPreferences;
	private AssistPreferences assistPreferences;
	
	private EffectiveHovers infoHovers;
	private Map<Integer, ITextHover> infoHoverCache;
	
	
	public SourceEditorViewerConfiguration(final DocContentSections documentContentInfo, final int flags,
			final ISourceEditor sourceEditor) {
		if (documentContentInfo == null) {
			throw new NullPointerException("documentContentInfo"); //$NON-NLS-1$
		}
		this.documentContentInfo= documentContentInfo;
		this.flags= flags;
		this.editor= sourceEditor;
	}
	
	
	protected void setup(final IPreferenceStore preferenceStore,
			final DecorationPreferences decoPrefs, final AssistPreferences assistPrefs) {
		assert (preferenceStore != null);
		this.fPreferenceStore= preferenceStore;
		this.decorationPreferences= decoPrefs;
		this.assistPreferences= assistPrefs;
	}
	
	
	public int getFlags() {
		return this.flags;
	}
	
	
	protected void initTextStyles() {
	}
	
	protected void setTextStyles(final TextStyleManager textStyles) {
		this.textStyles= textStyles;
	}
	
	protected TextStyleManager getTextStyles() {
		if (this.textStyles == null) {
			initTextStyles();
		}
		return this.textStyles;
	}
	
	
	protected void initScanners() {
	}
	
	protected void addScanner(final String contentType, final ITokenScanner scanner) {
		this.scanners.put(contentType, scanner);
		
		if (scanner instanceof ISettingsChangedHandler) {
			this.settingsHandler.add((ISettingsChangedHandler) scanner);
		}
	}
	
	protected ITokenScanner getScanner(final String contentType) {
		if (this.scanners == null) {
			this.scanners= new HashMap<>();
			initScanners();
		}
		final ITokenScanner scanner= this.scanners.get(contentType);
		if (DEBUG && scanner == null) {
			StatusManager.getManager().handle(new Status(IStatus.WARNING, LTKUIPlugin.BUNDLE_ID,
					"No scanner for contentType= " + contentType + "." ));
		}
		return scanner;
	}
	
	
	protected ISourceEditor getSourceEditor() {
		return this.editor;
	}
	
	public final DocContentSections getDocumentContentInfo() {
		return this.documentContentInfo;
	}
	
	@Override
	public final String getConfiguredDocumentPartitioning(final ISourceViewer sourceViewer) {
		return this.documentContentInfo.getPartitioning();
	}
	
	public IPreferenceStore getPreferences() {
		return this.fPreferenceStore;
	}
	
	
	public DecorationPreferences getDecorationPreferences() {
		return this.decorationPreferences;
	}
	
	public AssistPreferences getAssistPreferences() {
		return this.assistPreferences;
	}
	
	
	@Override
	public void handleSettingsChanged(final Set<String> groupIds, final Map<String, Object> options) {
		if (this.assistPreferences != null
				&& (groupIds.contains(LTKUIPreferences.ASSIST_GROUP_ID) || groupIds.contains(this.assistPreferences.getGroupId())) ) {
			if (this.contentAssistant != null) {
				this.assistPreferences.configure(this.contentAssistant);
			}
			if (this.quickAssistant != null) {
				this.assistPreferences.configure(this.quickAssistant);
			}
		}
		if (this.textStyles != null && this.textStyles.affectsTextPresentation(groupIds)) {
			options.put(ITextPresentationConstants.SETTINGSCHANGE_AFFECTSPRESENTATION_KEY, Boolean.TRUE);
		}
		for (final ISettingsChangedHandler handler : this.settingsHandler.toList()) {
			handler.handleSettingsChanged(groupIds, options);
		}
	}
	
	@Override
	public IPresentationReconciler getPresentationReconciler(final ISourceViewer sourceViewer) {
		if (this.presentationReconciler == null) {
			this.presentationReconciler= createPresentationReconciler();
		}
		return this.presentationReconciler;
	}
	
	protected IPresentationReconciler createPresentationReconciler() {
		final PresentationReconciler reconciler= new PresentationReconciler();
		reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(null));
		
		initPresentationReconciler(reconciler);
		
		return reconciler;
	}
	
	PresentationReconciler getPresentationReconciler() {
		return (PresentationReconciler) this.presentationReconciler;
	}
	
	protected void initPresentationReconciler(final PresentationReconciler reconciler) {
		final String[] contentTypes= getConfiguredContentTypes(null);
		for (final String contentType : contentTypes) {
			final ITokenScanner scanner= getScanner(contentType);
			if (scanner != null) {
				final DefaultDamagerRepairer dr= new DefaultDamagerRepairer(scanner);
				reconciler.setDamager(dr, contentType);
				reconciler.setRepairer(dr, contentType);
			}
		}
	}
	
	
	public List<ISourceEditorAddon> getAddOns() {
		return new ArrayList<>();
	}
	
	
	public ICharPairMatcher getPairMatcher() {
		if (this.pairMatcher == null) {
			this.pairMatcher= createPairMatcher();
		}
		return this.pairMatcher;
	}
	
	protected ICharPairMatcher createPairMatcher() {
		return null;
	}
	
	
	protected IIndentSettings getIndentSettings() {
		return null;
	}
	
	@Override
	public int getTabWidth(final ISourceViewer sourceViewer) {
		final IIndentSettings settings= getIndentSettings();
		if (settings != null) {
			return settings.getTabSize();
		}
		return super.getTabWidth(sourceViewer);
	}
	
	@Override
	public String[] getIndentPrefixes(final ISourceViewer sourceViewer, final String contentType) {
		final IIndentSettings settings= getIndentSettings();
		if (settings != null) {
			final String[] prefixes= getIndentPrefixesForTab(getTabWidth(sourceViewer));
			if (settings.getIndentDefaultType() == IIndentSettings.IndentationType.SPACES) {
				for (int i= prefixes.length-2; i > 0; i--) {
					prefixes[i]= prefixes[i-1];
				}
				prefixes[0]= new String(IndentUtil.repeat(' ', settings.getIndentSpacesCount()));
			}
			return prefixes;
		}
		else {
			return super.getIndentPrefixes(sourceViewer, contentType);
		}
	}
	
	
	public boolean isSmartInsertSupported() {
		return false;
	}
	
	public boolean isSmartInsertByDefault() {
		return true;
	}
	
	
	@Override
	public IContentAssistant getContentAssistant(final ISourceViewer sourceViewer) {
		if (this.contentAssistant == null) {
			this.contentAssistant= ((getFlags() & TEMPLATE_MODE) != 0) ?
					createTemplateVariableContentAssistant(sourceViewer) :
					createContentAssistant(sourceViewer);
			if (this.contentAssistant != null) {
				if (this.assistPreferences != null) {
					this.assistPreferences.configure(this.contentAssistant);
				}
				this.contentAssistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
				this.contentAssistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
				this.contentAssistant.setInformationControlCreator(
						getAssistInformationControlCreator(sourceViewer) );
			}
		}
		return this.contentAssistant;
	}
	
	public ContentAssist getContentAssist() {
		return this.contentAssistant;
	}
	
	protected ContentAssist createContentAssistant(final ISourceViewer sourceViewer) {
		if (getSourceEditor() != null) {
			final ContentAssist assistant= new ContentAssist();
			assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(null));
			assistant.setRestoreCompletionProposalSize(DialogUtils.getDialogSettings(LTKUIPlugin.getInstance(), "ContentAssist.Proposal.size")); //$NON-NLS-1$
			
			initContentAssist(assistant);
			return assistant;
		}
		return null;
	}
	
	protected void initContentAssist(final ContentAssist assistant) {
	}
	
	
	@Override
	public IQuickAssistAssistant getQuickAssistAssistant(final ISourceViewer sourceViewer) {
		if (this.quickAssistant == null) {
			this.quickAssistant= createQuickAssistant(sourceViewer);
			if (this.quickAssistant != null) {
				if (this.assistPreferences != null) {
					this.assistPreferences.configure(this.quickAssistant);
				}
				this.quickAssistant.setInformationControlCreator(getAssistInformationControlCreator(sourceViewer));
			}
		}
		return this.quickAssistant;
	}
	
	protected IQuickAssistAssistant createQuickAssistant(final ISourceViewer sourceViewer) {
		final IQuickAssistProcessor processor= createQuickAssistProcessor();
		if (processor != null) {
			final QuickAssistAssistant assistent= new QuickAssistAssistant();
			assistent.setQuickAssistProcessor(processor);
			assistent.enableColoredLabels(true);
			return assistent;
		}
		return super.getQuickAssistAssistant(sourceViewer);
	}
	
	protected IQuickAssistProcessor createQuickAssistProcessor() {
		return null;
	}
	
	protected IInformationControlCreator getAssistInformationControlCreator(final ISourceViewer sourceViewer) {
		if ((getFlags() & TEMPLATE_MODE) != 0) {
			if (assistTemplateInformationControlCreator == null) {
				assistTemplateInformationControlCreator= new IInformationControlCreator() {
					@Override
					public IInformationControl createInformationControl(final Shell parent) {
						return new DefaultInformationControl(parent,
								InformationDispatchHandler.getAdditionalInfoAffordanceString() );
					}
				};
			}
			return assistTemplateInformationControlCreator;
		}
		if (assistDefaultInformationControlCreator == null) {
			assistDefaultInformationControlCreator= new AssistInformationControlCreator();
		}
		return assistDefaultInformationControlCreator;
	}
	
	@Override
	public int[] getConfiguredTextHoverStateMasks(final ISourceViewer sourceViewer, final String contentType) {
		if ((getFlags() & TEMPLATE_MODE) != 0) {
			return new int[] { ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK };
		}
		if (getSourceEditor() != null) {
			return getInfoHoverStateMasks(contentType);
		}
		return super.getConfiguredTextHoverStateMasks(sourceViewer, contentType);
	}
	
	@Override
	public ITextHover getTextHover(final ISourceViewer sourceViewer, final String contentType) {
		return getTextHover(sourceViewer, contentType, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
	}
	
	@Override
	public ITextHover getTextHover(final ISourceViewer sourceViewer, final String contentType, final int stateMask) {
		if ((getFlags() & TEMPLATE_MODE) != 0) {
			return getTemplateVariableTextHover(sourceViewer);
		}
		return getInfoHover(sourceViewer, contentType, stateMask);
	}
	
	
	protected int[] getInfoHoverStateMasks(final String contentType) {
		final String[] contentTypes= getConfiguredContentTypes(null);
		if (contentTypes != null && contentTypes.length > 0 && contentTypes[0].equals(contentType)) {
			initInfoHovers();
		}
		if (this.infoHovers != null && isInfoHoverDefaultContentType(contentType)) {
			return this.infoHovers.getStateMasks();
		}
		return new int[] { ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK };
	}
	
	protected void initInfoHovers() {
		final InfoHoverRegistry registry= getInfoHoverRegistry();
		this.infoHovers= (registry != null) ? registry.getEffectiveHoverDescriptors() : null;
		if (this.infoHoverCache == null) {
			this.infoHoverCache= new HashMap<>();
		}
		else {
			this.infoHoverCache.clear();
		}
	}
	
	public EffectiveHovers getConfiguredInfoHovers() {
		return this.infoHovers;
	}
	
	protected ITextHover getInfoHover(final ISourceViewer sourceViewer, final String contentType, final int stateMask) {
		if (this.infoHovers != null && isInfoHoverDefaultContentType(contentType)) {
			final Integer key= Integer.valueOf(stateMask);
			ITextHover hover= this.infoHoverCache.get(key);
			if (hover == null) {
				final InfoHoverDescriptor descriptor= this.infoHovers.getDescriptor(stateMask);
				if (descriptor != null) {
					hover= createInfoHover(descriptor);
					if (hover == null) {
						hover= NO_HOVER;
					}
					this.infoHoverCache.put(key, hover);
				}
			}
			return (hover != NO_HOVER) ? hover : null;
		}
		return null;
	}
	
	protected boolean isInfoHoverDefaultContentType(final String contentType) {
		final String[] partitioning= getConfiguredContentTypes(null);
		return (partitioning != null && partitioning.length > 0 && partitioning[0].equals(contentType));
	}
	
	protected InfoHoverRegistry getInfoHoverRegistry() {
		return null;
	}
	
	protected ITextHover createInfoHover(final InfoHoverDescriptor descriptor) {
		return null;
	}
	
	
	@Override
	public IInformationPresenter getInformationPresenter(final ISourceViewer sourceViewer) {
		final InformationPresenter presenter= new InformationPresenter(
				DEFAULT_INFORMATION_CONTROL_CREATOR);
		presenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(null));
		
		// Register information provider
		final IInformationProvider provider= getInformationProvider();
		final String[] contentTypes= getConfiguredContentTypes(null);
		for (int i= 0; i < contentTypes.length; i++) {
			presenter.setInformationProvider(provider, contentTypes[i]);
		}
		// sizes: see org.eclipse.jface.text.TextViewer.TEXT_HOVER_*_CHARS
		presenter.setSizeConstraints(100, 12, true, true);
		return presenter;
	}
	
	protected IInformationProvider getInformationProvider() {
		return null;
	}
	
	
	@Override
	protected Map getHyperlinkDetectorTargets(final ISourceViewer sourceViewer) {
		final Map<String, IAdaptable> targets= super.getHyperlinkDetectorTargets(sourceViewer);
		collectHyperlinkDetectorTargets(targets, sourceViewer);
		return targets;
	}
	
	protected void collectHyperlinkDetectorTargets(final Map<String, IAdaptable> targets, final ISourceViewer sourceViewer) {
	}
	
	public IInformationPresenter getQuickPresenter(final ISourceViewer sourceViewer,
			final int operation) {
		final IInformationProvider provider= getQuickInformationProvider(sourceViewer, operation);
		if (provider == null) {
			return null;
		}
		final InformationPresenter presenter= new InformationPresenter(((IInformationProviderExtension2) provider).getInformationPresenterControlCreator());
		presenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(null));
		presenter.setAnchor(AbstractInformationControlManager.ANCHOR_GLOBAL);
		presenter.setSizeConstraints(50, 20, true, false);
		
		final String[] contentTypes= getConfiguredContentTypes(null);
		for (int i= 0; i < contentTypes.length; i++) {
			presenter.setInformationProvider(provider, contentTypes[i]);
		}
		
		return presenter;
	}
	
	protected IInformationProvider getQuickInformationProvider(final ISourceViewer sourceViewer,
			final int operation) {
		return null;
	}
	

	
/* For TemplateEditors ********************************************************/
	
	protected TemplateVariableProcessor getTemplateVariableProcessor() {
		throw new UnsupportedOperationException();
	}
	
	protected ContentAssist createTemplateVariableContentAssistant(final ISourceViewer sourceViewer) {
		final ContentAssist assistant= new ContentAssist();
		assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(null));
		
		for (final String contentType : getConfiguredContentTypes(null)) {
			assistant.setContentAssistProcessor(getTemplateVariableProcessor(), contentType);
		}
		
		return assistant;
	}
	
	protected static class TemplateVariableTextHover implements ITextHover {
		
		private final TemplateVariableProcessor processor;
		
		/**
		 * @param processor the template variable processor
		 */
		public TemplateVariableTextHover(final TemplateVariableProcessor processor) {
			this.processor= processor;
		}
		
		@Override
		public String getHoverInfo(final ITextViewer textViewer, final IRegion subject) {
			try {
				final IDocument doc= textViewer.getDocument();
				final int offset= subject.getOffset();
				if (offset >= 2 && "${".equals(doc.get(offset-2, 2))) { //$NON-NLS-1$
					final String varName= doc.get(offset, subject.getLength());
					final TemplateContextType contextType= this.processor.getContextType();
					if (contextType != null) {
						final Iterator iter= contextType.resolvers();
						while (iter.hasNext()) {
							final TemplateVariableResolver var= (TemplateVariableResolver) iter.next();
							if (varName.equals(var.getType())) {
								return var.getDescription();
							}
						}
					}
				}
			} catch (final BadLocationException e) {
			}
			return null;
		}
		
		@Override
		public IRegion getHoverRegion(final ITextViewer textViewer, final int offset) {
			if (textViewer != null) {
				return WordFinder.findWord(textViewer.getDocument(), offset);
			}
			return null;
		}
		
	}
	
	public ITextHover getTemplateVariableTextHover(final ISourceViewer sourceViewer) {
		final Integer key= Integer.valueOf(0);
		ITextHover hover;
		if (this.infoHoverCache != null) {
			hover= this.infoHoverCache.get(key);
		}
		else {
			hover= new TemplateVariableTextHover(getTemplateVariableProcessor());
			this.infoHoverCache= Collections.singletonMap(key, hover);
		}
		return hover;
	}
	
}
