/*******************************************************************************
 * Copyright (c) 2002, 2013 GEBIT Gesellschaft fuer EDV-Beratung
 * und Informatik-Technologien mbH,
 * Berlin, Duesseldorf, Frankfurt (Germany) and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
 * 	   IBM Corporation - bug fixes
 *     John-Mason P. Shackelford - bug 40255
 *     Rob Dingwell - bug 68886
 *******************************************************************************/

package org.eclipse.ant.internal.ui.editor;

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

import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.ui.AntSourceViewerConfiguration;
import org.eclipse.ant.internal.ui.editor.formatter.XmlDocumentFormattingStrategy;
import org.eclipse.ant.internal.ui.editor.formatter.XmlElementFormattingStrategy;
import org.eclipse.ant.internal.ui.editor.text.AntDocumentSetupParticipant;
import org.eclipse.ant.internal.ui.editor.text.AntEditorPartitionScanner;
import org.eclipse.ant.internal.ui.editor.text.AntInformationProvider;
import org.eclipse.ant.internal.ui.editor.text.NotifyingReconciler;
import org.eclipse.ant.internal.ui.editor.text.XMLAnnotationHover;
import org.eclipse.ant.internal.ui.editor.text.XMLReconcilingStrategy;
import org.eclipse.ant.internal.ui.editor.text.XMLTextHover;
import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.preference.JFacePreferences;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.formatter.IContentFormatter;
import org.eclipse.jface.text.formatter.MultiPassContentFormatter;
import org.eclipse.jface.text.information.IInformationPresenter;
import org.eclipse.jface.text.information.IInformationProvider;
import org.eclipse.jface.text.information.InformationPresenter;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.graphics.Color;

/**
 * The source viewer configuration for the Ant Editor.
 */
public class AntEditorSourceViewerConfiguration extends AntSourceViewerConfiguration {

	private AntEditor fEditor;

	private XMLTextHover fTextHover;

	private ContentAssistant fContentAssistant;

	private AntAutoEditStrategy[] fAutoEditorStategies;

	/**
	 * Creates an instance with the specified color manager.
	 */
	public AntEditorSourceViewerConfiguration(AntEditor editor) {
		super();
		fEditor = editor;
	}

	@Override
	public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
		fContentAssistant = new ContentAssistant();
		AntEditorCompletionProcessor processor = new AntEditorCompletionProcessor(fEditor.getAntModel());
		fContentAssistant.setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
		fContentAssistant.setContentAssistProcessor(processor, AntEditorPartitionScanner.XML_TAG);
		fContentAssistant.setDocumentPartitioning(AntDocumentSetupParticipant.ANT_PARTITIONING);

		String triggers = fPreferenceStore.getString(AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS);
		if (triggers != null) {
			processor.setCompletionProposalAutoActivationCharacters(triggers.toCharArray());
		}

		fContentAssistant.enableAutoInsert(fPreferenceStore.getBoolean(AntEditorPreferenceConstants.CODEASSIST_AUTOINSERT));
		fContentAssistant.enableAutoActivation(fPreferenceStore.getBoolean(AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION));
		fContentAssistant.setAutoActivationDelay(fPreferenceStore.getInt(AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY));
		fContentAssistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
		fContentAssistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
		fContentAssistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));

		Color background = JFaceResources.getColorRegistry().get(JFacePreferences.CONTENT_ASSIST_BACKGROUND_COLOR);
		fContentAssistant.setContextInformationPopupBackground(background);
		fContentAssistant.setContextSelectorBackground(background);

		Color foreground = JFaceResources.getColorRegistry().get(JFacePreferences.CONTENT_ASSIST_FOREGROUND_COLOR);
		fContentAssistant.setContextInformationPopupForeground(foreground);
		fContentAssistant.setContextSelectorForeground(foreground);

		IInformationControlCreator creator = getInformationControlCreator(sourceViewer);
		fContentAssistant.setInformationControlCreator(creator);

		fContentAssistant.setRepeatedInvocationMode(true);
		fContentAssistant.setStatusLineVisible(true);
		fContentAssistant.setShowEmptyList(true);
		fContentAssistant.addCompletionListener(processor);
		return fContentAssistant;
	}

	@Override
	public IReconciler getReconciler(ISourceViewer sourceViewer) {
		NotifyingReconciler reconciler = new NotifyingReconciler(new XMLReconcilingStrategy(fEditor));
		reconciler.setDelay(XMLReconcilingStrategy.DELAY);
		reconciler.addReconcilingParticipant(fEditor);
		return reconciler;
	}

	@Override
	public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
		return new XMLAnnotationHover();
	}

	@Override
	public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) {
		return parent -> new DefaultInformationControl(parent, false);
	}

	@Override
	public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
		if (fTextHover == null) {
			fTextHover = new XMLTextHover(fEditor);
		}
		return fTextHover;
	}

	protected void changeConfiguration(PropertyChangeEvent event) {
		String p = event.getProperty();

		if (AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION.equals(p)) {
			boolean enabled = fPreferenceStore.getBoolean(AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION);
			fContentAssistant.enableAutoActivation(enabled);
		} else if (AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY.equals(p) && fContentAssistant != null) {
			int delay = fPreferenceStore.getInt(AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY);
			fContentAssistant.setAutoActivationDelay(delay);
		} else if (AntEditorPreferenceConstants.CODEASSIST_AUTOINSERT.equals(p) && fContentAssistant != null) {
			boolean enabled = fPreferenceStore.getBoolean(AntEditorPreferenceConstants.CODEASSIST_AUTOINSERT);
			fContentAssistant.enableAutoInsert(enabled);
		} else if (AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS.equals(p)) {
			changeContentAssistProcessor();
		}
	}

	private void changeContentAssistProcessor() {
		String triggers = fPreferenceStore.getString(AntEditorPreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS);
		if (triggers != null) {
			AntEditorCompletionProcessor cp = (AntEditorCompletionProcessor) fContentAssistant.getContentAssistProcessor(IDocument.DEFAULT_CONTENT_TYPE);
			if (cp != null) {
				cp.setCompletionProposalAutoActivationCharacters(triggers.toCharArray());
			}
		}
	}

	@Override
	public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {

		MultiPassContentFormatter formatter = new MultiPassContentFormatter(getConfiguredDocumentPartitioning(sourceViewer), IDocument.DEFAULT_CONTENT_TYPE);

		formatter.setMasterStrategy(new XmlDocumentFormattingStrategy());

		formatter.setSlaveStrategy(new XmlElementFormattingStrategy(), AntEditorPartitionScanner.XML_TAG);

		// formatter.setSlaveStrategy(new XmlCommentFormattingStrategy(), AntEditorPartitionScanner.XML_COMMENT);

		return formatter;
	}

	@Override
	public IInformationPresenter getInformationPresenter(ISourceViewer sourceViewer) {
		InformationPresenter presenter = new InformationPresenter(getInformationPresenterControlCreator());
		presenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
		IInformationProvider provider = new AntInformationProvider(new XMLTextHover(fEditor));
		presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE);
		presenter.setInformationProvider(provider, AntEditorPartitionScanner.XML_CDATA);
		presenter.setInformationProvider(provider, AntEditorPartitionScanner.XML_COMMENT);
		presenter.setInformationProvider(provider, AntEditorPartitionScanner.XML_DTD);
		presenter.setInformationProvider(provider, AntEditorPartitionScanner.XML_TAG);
		presenter.setSizeConstraints(60, 10, true, true);
		return presenter;
	}

	/**
	 * Returns the information presenter control creator. The creator is a factory creating the presenter controls for the given source viewer. This
	 * implementation always returns a creator for <code>DefaultInformationControl</code> instances.
	 * 
	 * @return an information control creator
	 * @since 3.1
	 */
	public static IInformationControlCreator getInformationPresenterControlCreator() {
		return parent -> new DefaultInformationControl(parent, true);
	}

	@Override
	public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) {
		List<String> list = new ArrayList<>();

		// prefix[0] is either '\t' or ' ' x tabWidth, depending on useSpaces

		int tabWidth = getTabWidth(sourceViewer);
		boolean useSpaces = fEditor.isTabsToSpacesConversionEnabled();

		for (int i = 0; i <= tabWidth; i++) {
			StringBuilder prefix = new StringBuilder();
			if (useSpaces) {
				for (int j = 0; j + i < tabWidth; j++) {
					prefix.append(' ');
				}

				if (i != 0) {
					prefix.append('\t');
				}
			} else {
				for (int j = 0; j < i; j++) {
					prefix.append(' ');
				}
				if (i != tabWidth) {
					prefix.append('\t');
				}
			}

			list.add(prefix.toString());
		}

		list.add(IAntCoreConstants.EMPTY_STRING);

		return list.toArray(new String[list.size()]);
	}

	@Override
	public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
		if (AntEditorPartitionScanner.XML_COMMENT.equals(contentType)) {
			return super.getAutoEditStrategies(sourceViewer, contentType);
		}
		if (fAutoEditorStategies == null) {
			fAutoEditorStategies = new AntAutoEditStrategy[] { new AntAutoEditStrategy(fEditor.getAntModel()) };
		}
		return fAutoEditorStategies;
	}

	@Override
	protected Map<String, IAdaptable> getHyperlinkDetectorTargets(ISourceViewer sourceViewer) {
		Map<String, IAdaptable> targets = super.getHyperlinkDetectorTargets(sourceViewer);
		targets.put("org.eclipse.ant.ui.buildFiles", fEditor); //$NON-NLS-1$
		return targets;
	}
}