/*******************************************************************************
 * Copyright (c) 2005, 2007 IBM Corporation and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 
 *******************************************************************************/
package org.eclipse.dltk.javascript.internal.ui.text;

import java.util.Map;

import org.eclipse.dltk.javascript.internal.ui.text.completion.JavaScriptCompletionProcessor;
import org.eclipse.dltk.javascript.internal.ui.text.completion.JavaScriptContentAssistPreference;
import org.eclipse.dltk.javascript.ui.text.IJavaScriptPartitions;
import org.eclipse.dltk.ui.text.AbstractScriptScanner;
import org.eclipse.dltk.ui.text.IColorManager;
import org.eclipse.dltk.ui.text.ScriptPresentationReconciler;
import org.eclipse.dltk.ui.text.ScriptSourceViewerConfiguration;
import org.eclipse.dltk.ui.text.SingleTokenScriptScanner;
import org.eclipse.dltk.ui.text.TodoTaskPreferencesOnPreferenceStore;
import org.eclipse.dltk.ui.text.completion.ContentAssistPreference;
import org.eclipse.dltk.ui.text.completion.ContentAssistProcessor;
import org.eclipse.dltk.ui.text.spelling.SpellCheckDelegate;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPartitioningException;
import org.eclipse.jface.text.DefaultTextDoubleClickStrategy;
import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextDoubleClickStrategy;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.ui.texteditor.ITextEditor;

public class JavascriptSourceViewerConfiguration extends
		ScriptSourceViewerConfiguration {

	private JavascriptCodeScanner fCodeScanner;

	private AbstractScriptScanner fStringScanner;

	private AbstractScriptScanner fCommentScanner;

	private JavascriptDocScanner fDocScanner;

	public JavascriptSourceViewerConfiguration(IColorManager colorManager,
			IPreferenceStore preferenceStore, ITextEditor editor,
			String partitioning) {
		super(colorManager, preferenceStore, editor, partitioning);
	}

	/**
	 * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getDoubleClickStrategy(org.eclipse.jface.text.source.ISourceViewer,
	 *      java.lang.String)
	 * @since 2.0
	 */
	@Override
	public ITextDoubleClickStrategy getDoubleClickStrategy(
			ISourceViewer sourceViewer, String contentType) {
		if (IJavaScriptPartitions.JS_DOC.equals(contentType)) {
			return new JSDocDoubleClickStrategy(
					getConfiguredDocumentPartitioning(sourceViewer));
		}
		return new DefaultTextDoubleClickStrategy() {
			/**
			 * @see org.eclipse.jface.text.DefaultTextDoubleClickStrategy#findExtendedDoubleClickSelection(org.eclipse.jface.text.IDocument,
			 *      int)
			 */
			@Override
			protected IRegion findExtendedDoubleClickSelection(
					IDocument document, int offset) {
				int start = -1;
				int end = -1;
				String text = document.get();

				if (document instanceof IDocumentExtension3) {
					try {
						String contentType = ((IDocumentExtension3) document)
								.getContentType(
										IJavaScriptPartitions.JS_PARTITIONING,
										offset, true);
						if (IJavaScriptPartitions.JS_STRING_SINGLE
								.equals(contentType)
								|| IJavaScriptPartitions.JS_STRING
										.equals(contentType)
						// || IJavaScriptPartitions.JS_REGEXP
						// .equals(contentType)
						) {
							ITypedRegion region = ((IDocumentExtension3) document)
									.getPartition(
											IJavaScriptPartitions.JS_PARTITIONING,
											offset, true);
							if (region != null && region.getLength() > 0) {
								// if reg exp return as is.
								// if (IJavaScriptPartitions.JS_REGEXP
								// .equals(contentType))
								// return region;
								// if it is a string, strip the quotes.
								return new Region(region.getOffset() + 1,
										region.getLength() - 2);
							}
						}
					} catch (BadLocationException ex) {
						ex.printStackTrace();
					} catch (BadPartitioningException ex) {
						ex.printStackTrace();
					}
				}

				// try to find if the text just before the offset is 1 of (,[ or
				// {
				if (offset > 0) {
					char ch = text.charAt(offset - 1);
					char closingChar = 0;

					if (ch == '(')
						closingChar = ')';
					else if (ch == '{')
						closingChar = '}';
					else if (ch == '[')
						closingChar = ']';

					if (closingChar != 0) {
						// it was one of the grouping chars, try to find the
						// closing.
						int closing = findClosing(text, offset, ch,
								closingChar, 1);
						if (closing != -1)
							return new Region(offset, closing - offset);
					}
				}

				// try to find if the text under the offset is 1 of ),] or }
				if (offset >= text.length()) {
					return null;
				}
				char ch = text.charAt(offset);
				char startChar = 0;

				if (ch == ')')
					startChar = '(';
				else if (ch == '}')
					startChar = '{';
				else if (ch == ']')
					startChar = '[';

				if (startChar != 0) {
					// it was one now try to find the start.
					int closing = findClosing(text, offset - 1, ch, startChar,
							-1);
					if (closing != -1)
						return new Region(closing + 1, offset - closing - 1);
				}

				// fall back on just words
				int i = offset;
				while (Character.isJavaIdentifierPart(text.charAt(i--))) {
					if (i == -1) {
						break;
					}
				}
				start = i + 2;

				i = offset;
				while (Character.isJavaIdentifierPart(text.charAt(i++))) {
					if (i == text.length()) {
						break;
					}
				}
				end = i - 1;

				return new Region(start, end - start);
			}

			// pretty simple find next { or }, doesnt skip over strings yet.
			private int findClosing(String text, int offset, char beginChar,
					char endChar, int next) {
				int skip = 0;
				int counter = offset;
				while (counter != -1 && counter < text.length()) {
					char ch = text.charAt(counter);

					if (ch == endChar) {
						if (skip == 0)
							return counter;
						skip--;
					}

					if (ch == beginChar)
						skip++;

					counter += next;
				}
				return -1;
			}
		};
	}

	@Override
	public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
		return IJavaScriptPartitions.JS_PARTITION_TYPES;
	}

	@Override
	public String getCommentPrefix() {
		return "//"; //$NON-NLS-1$
	}

	@Override
	protected void alterContentAssistant(ContentAssistant assistant) {
		IContentAssistProcessor scriptProcessor = new JavaScriptCompletionProcessor(
				getEditor(), assistant, IDocument.DEFAULT_CONTENT_TYPE);
		assistant.setContentAssistProcessor(scriptProcessor,
				IDocument.DEFAULT_CONTENT_TYPE);

		ContentAssistProcessor singleLineProcessor = new JavaScriptCompletionProcessor(
				getEditor(), assistant,
				IJavaScriptPartitions.JS_MULTI_LINE_COMMENT);
		assistant.setContentAssistProcessor(singleLineProcessor,
				IJavaScriptPartitions.JS_MULTI_LINE_COMMENT);

		ContentAssistProcessor stringProcessor = new JavaScriptCompletionProcessor(
				getEditor(), assistant, IJavaScriptPartitions.JS_STRING);
		assistant.setContentAssistProcessor(stringProcessor,
				IJavaScriptPartitions.JS_STRING);

		ContentAssistProcessor stringSingleProcessor = new JavaScriptCompletionProcessor(
				getEditor(), assistant, IJavaScriptPartitions.JS_STRING_SINGLE);
		assistant.setContentAssistProcessor(stringSingleProcessor,
				IJavaScriptPartitions.JS_STRING_SINGLE);

		// TODO JS DOC completion??
		ContentAssistProcessor jsProcessor = new JavaScriptCompletionProcessor(
				getEditor(), assistant, IJavaScriptPartitions.JS_DOC);
		assistant.setContentAssistProcessor(jsProcessor,
				IJavaScriptPartitions.JS_DOC);

	}

	@Override
	protected ContentAssistPreference getContentAssistPreference() {
		return JavaScriptContentAssistPreference.getDefault();
	}

	@Override
	protected void initializeScanners() {
		fCodeScanner = new JavascriptCodeScanner(getColorManager(),
				fPreferenceStore);
		fStringScanner = new SingleTokenScriptScanner(getColorManager(),
				fPreferenceStore, JavascriptColorConstants.JS_STRING);

		fCommentScanner = new JavaScriptScriptCommentScanner(getColorManager(),
				fPreferenceStore,
				JavascriptColorConstants.JS_SINGLE_LINE_COMMENT,
				JavascriptColorConstants.JS_TODO_TAG,
				new TodoTaskPreferencesOnPreferenceStore(fPreferenceStore));
		fDocScanner = new JavascriptDocScanner(this);

	}

	@Override
	public IPresentationReconciler getPresentationReconciler(
			ISourceViewer sourceViewer) {
		ScriptPresentationReconciler reconciler = new ScriptPresentationReconciler();
		reconciler
				.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));

		DefaultDamagerRepairer dr = new DefaultDamagerRepairer(
				this.fCodeScanner);
		reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
		reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);

		dr = new DefaultDamagerRepairer(fStringScanner);
		reconciler.setDamager(dr, IJavaScriptPartitions.JS_STRING);
		reconciler.setRepairer(dr, IJavaScriptPartitions.JS_STRING);

		dr = new DefaultDamagerRepairer(fStringScanner);
		reconciler.setDamager(dr, IJavaScriptPartitions.JS_STRING_SINGLE);
		reconciler.setRepairer(dr, IJavaScriptPartitions.JS_STRING_SINGLE);

		dr = new DefaultDamagerRepairer(fCommentScanner);
		reconciler.setDamager(dr, IJavaScriptPartitions.JS_MULTI_LINE_COMMENT);
		reconciler.setRepairer(dr, IJavaScriptPartitions.JS_MULTI_LINE_COMMENT);

		dr = new DefaultDamagerRepairer(fCommentScanner);
		reconciler.setDamager(dr, IJavaScriptPartitions.JS_SINGLE_LINE_COMMENT);
		reconciler
				.setRepairer(dr, IJavaScriptPartitions.JS_SINGLE_LINE_COMMENT);

		dr = new DefaultDamagerRepairer(fDocScanner);
		reconciler.setDamager(dr, IJavaScriptPartitions.JS_DOC);
		reconciler.setRepairer(dr, IJavaScriptPartitions.JS_DOC);

		return reconciler;
	}

	/**
	 * Adapts the behavior of the contained components to the change encoded in
	 * the given event.
	 * <p>
	 * Clients are not allowed to call this method if the old setup with text
	 * tools is in use.
	 * </p>
	 * 
	 * @param event
	 *            the event to which to adapt
	 * @see JavascriptSourceViewerConfiguration#ScriptSourceViewerConfiguration(IColorManager,
	 *      IPreferenceStore, ITextEditor, String)
	 */
	@Override
	public void handlePropertyChangeEvent(PropertyChangeEvent event) {
		if (fCodeScanner.affectsBehavior(event))
			fCodeScanner.adaptToPreferenceChange(event);
		if (fCommentScanner.affectsBehavior(event))
			fCommentScanner.adaptToPreferenceChange(event);
		if (fDocScanner.affectsBehavior(event))
			fDocScanner.adaptToPreferenceChange(event);
		if (fStringScanner.affectsBehavior(event))
			fStringScanner.adaptToPreferenceChange(event);
	}

	/**
	 * Determines whether the preference change encoded by the given event
	 * changes the behavior of one of its contained components.
	 * 
	 * @param event
	 *            the event to be investigated
	 * @return <code>true</code> if event causes a behavioral change
	 * 
	 */
	@Override
	public boolean affectsTextPresentation(PropertyChangeEvent event) {
		return fCodeScanner.affectsBehavior(event)
				|| fCommentScanner.affectsBehavior(event)
				|| fDocScanner.affectsBehavior(event)
				|| fStringScanner.affectsBehavior(event);
	}

	@Override
	public IAutoEditStrategy[] getAutoEditStrategies(
			ISourceViewer sourceViewer, String contentType) {
		if (IJavaScriptPartitions.JS_MULTI_LINE_COMMENT.equals(contentType)
				|| IJavaScriptPartitions.JS_DOC.equals(contentType)) {
			return new IAutoEditStrategy[] { new JSDocAutoIndentStrategy(
					fPreferenceStore) };
		} else if (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType)) {
			String partitioning = getConfiguredDocumentPartitioning(sourceViewer);
			return new IAutoEditStrategy[] { new JavascriptAutoEditStrategy(
					partitioning, null) };
		} else {
			return super.getAutoEditStrategies(sourceViewer, contentType);
		}
	}

	@Override
	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected Map getHyperlinkDetectorTargets(final ISourceViewer sourceViewer) {
		final Map targets = super.getHyperlinkDetectorTargets(sourceViewer);
		targets.put("org.eclipse.dltk.javascript.code", getEditor()); //$NON-NLS-1$
		return targets;
	}

	@Override
	protected SpellCheckDelegate createSpellCheckDelegate() {
		return new SpellCheckDelegate(IDocument.DEFAULT_CONTENT_TYPE,
				IJavaScriptPartitions.JS_STRING,
				IJavaScriptPartitions.JS_STRING_SINGLE);
	}
}
