/*******************************************************************************
 * Copyright (c) 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui.internal.spelling;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.reconciler.DirtyRegion;
import org.eclipse.jface.text.reconciler.IReconcileResult;
import org.eclipse.jface.text.reconciler.IReconcileStep;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IAnnotationModelExtension;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
import org.eclipse.ui.texteditor.spelling.ISpellingProblemCollector;
import org.eclipse.ui.texteditor.spelling.SpellingContext;
import org.eclipse.ui.texteditor.spelling.SpellingEngineDescriptor;
import org.eclipse.ui.texteditor.spelling.SpellingProblem;
import org.eclipse.ui.texteditor.spelling.SpellingService;
import org.eclipse.wst.sse.core.utils.StringUtils;
import org.eclipse.wst.sse.ui.internal.ExtendedConfigurationBuilder;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.internal.reconcile.DocumentAdapter;
import org.eclipse.wst.sse.ui.internal.reconcile.ReconcileAnnotationKey;
import org.eclipse.wst.sse.ui.internal.reconcile.StructuredReconcileStep;
import org.eclipse.wst.sse.ui.internal.reconcile.StructuredTextReconcilingStrategy;
import org.eclipse.wst.sse.ui.internal.reconcile.TemporaryAnnotation;

/**
 * A reconciling strategy that queries the SpellingService using its default
 * engine. Results are show as temporary annotations.
 * 
 * @since 1.5
 */
public class SpellcheckStrategy extends StructuredTextReconcilingStrategy {
	private class SpellingProblemCollector implements ISpellingProblemCollector {
		List annotations = new ArrayList();

		public void accept(SpellingProblem problem) {
			TemporaryAnnotation annotation = new TemporaryAnnotation(new Position(problem.getOffset(), problem.getLength()), TemporaryAnnotation.ANNOT_WARNING, problem.getMessage(), fReconcileAnnotationKey);
			/*
			 * TODO: create and use an IQuickFixProcessor that uses
			 * problem.getProposals() for fixes [note, the default engine
			 * doesn't propose fixes, at least without a dictionary].
			 */
			annotation.setAdditionalFixInfo(problem);
			annotations.add(annotation);
			if (_DEBUG_SPELLING) {
				Logger.log(Logger.INFO_DEBUG, problem.getMessage());
			}
		}

		public void beginCollecting() {
		}

		void clear() {
			annotations.clear();
		}

		public void endCollecting() {
		}

		IReconcileResult[] getResults() {
			return (IReconcileResult[]) annotations.toArray(new IReconcileResult[annotations.size()]);
		}
	}

	private class SpellingStep extends StructuredReconcileStep {
		protected IReconcileResult[] reconcileModel(final DirtyRegion dirtyRegion, IRegion subRegion) {
			SpellingService service = getSpellingService(fContentTypeId + "." + SpellingService.PREFERENCE_SPELLING_ENGINE);
			if (_DEBUG_SPELLING) {
				Logger.log(Logger.INFO_DEBUG, "Spell checking [" + subRegion.getOffset() + "-" + (subRegion.getOffset() + subRegion.getLength()) + "]"); //$NON-NLS-1$
			}
			service.check(getDocument(), new IRegion[]{subRegion}, fSpellingContext, fProblemCollector, getProgressMonitor());
			IReconcileResult[] results = fProblemCollector.getResults();
			fProblemCollector.clear();
			return results;
		}
	}

	static final boolean _DEBUG_SPELLING = Boolean.valueOf(Platform.getDebugOption("org.eclipse.wst.sse.ui/debug/reconcilerSpelling")).booleanValue(); //$NON-NLS-1$

	static final String ANNOTATION_TYPE = "org.eclipse.wst.sse.ui.temp.spelling"; //$NON-NLS-1$

	private static final String EXTENDED_BUILDER_TYPE = "spellingsupport"; //$NON-NLS-1$

	static final String KEY_CONTENT_TYPE = "org.eclipse.wst.sse.ui.temp.spelling"; //$NON-NLS-1$
	private String fContentTypeId = null;

	private String fDocumentPartitioning;

	private SpellingProblemCollector fProblemCollector = new SpellingProblemCollector();

	/*
	 * Keying our Temporary Annotations based on the partition doesn't help
	 * this strategy to only remove its own TemporaryAnnotations since it's
	 * possibly run on all partitions. Instead, set the key to use an
	 * arbitrary partition type that we can check for using our own
	 * implementation of getAnnotationsToRemove(DirtyRegion).
	 * 
	 * Value initialized through
	 * 
	 * super(ISourceViewer)->super.init()->createReconcileSteps()
	 */
	ReconcileAnnotationKey fReconcileAnnotationKey;

	SpellingContext fSpellingContext;
	/*
	 * Value initialized through
	 * 
	 * super(ISourceViewer)->super.init()->createReconcileSteps()
	 */
	IReconcileStep fSpellingStep;

	String[] fSupportedPartitionTypes;

	public SpellcheckStrategy(ISourceViewer viewer, String contentTypeId) {
		super(viewer);
		fContentTypeId = contentTypeId;

		fSpellingContext = new SpellingContext();
		fSpellingContext.setContentType(Platform.getContentTypeManager().getContentType(fContentTypeId));
		fReconcileAnnotationKey = new ReconcileAnnotationKey(fSpellingStep, KEY_CONTENT_TYPE, ReconcileAnnotationKey.PARTIAL);

		String[] definitions = ExtendedConfigurationBuilder.getInstance().getDefinitions(EXTENDED_BUILDER_TYPE, fContentTypeId);
		List defs = new ArrayList();
		for (int i = 0; i < definitions.length; i++) {
			defs.addAll(Arrays.asList(StringUtils.unpack(definitions[i])));
		}
		fSupportedPartitionTypes = (String[]) defs.toArray(new String[defs.size()]);
	}

	protected boolean containsStep(IReconcileStep step) {
		return fSpellingStep.equals(step);
	}

	public void createReconcileSteps() {
		fSpellingStep = new SpellingStep();
	}

	String getDocumentPartitioning() {
		return fDocumentPartitioning == null ? IDocumentExtension3.DEFAULT_PARTITIONING : fDocumentPartitioning;
	}

	private TemporaryAnnotation[] getSpellingAnnotationsToRemove(IRegion region) {
		List toRemove = new ArrayList();
		IAnnotationModel annotationModel = getAnnotationModel();
		// can be null when closing the editor
		if (getAnnotationModel() != null) {
			Iterator i = annotationModel.getAnnotationIterator();
			while (i.hasNext()) {
				Object obj = i.next();
				if (!(obj instanceof TemporaryAnnotation))
					continue;

				TemporaryAnnotation annotation = (TemporaryAnnotation) obj;
				ReconcileAnnotationKey key = (ReconcileAnnotationKey) annotation.getKey();

				// then if this strategy knows how to add/remove this
				// partition type
				if (key != null && key.equals(fReconcileAnnotationKey)) {
					Position position = annotation.getPosition();
					if (key.getScope() == ReconcileAnnotationKey.PARTIAL && position.overlapsWith(region.getOffset(), region.getLength())) {
						toRemove.add(annotation);
					}
					else if (key.getScope() == ReconcileAnnotationKey.TOTAL) {
						toRemove.add(annotation);
					}
				}
			}
		}

		return (TemporaryAnnotation[]) toRemove.toArray(new TemporaryAnnotation[toRemove.size()]);
	}

	/**
	 * @param engineID
	 * @return the SpellingService with the preferred engine
	 */
	SpellingService getSpellingService(String engineID) {
		SpellingService defaultService = EditorsUI.getSpellingService();

		SpellingService preferredService = defaultService;

		if (engineID != null) {
			/*
			 * Set up a preference store indicating that the given engine
			 * should be used instead of the default preference store's
			 * default
			 */
			SpellingEngineDescriptor[] descriptors = defaultService.getSpellingEngineDescriptors();
			for (int i = 0; i < descriptors.length; i++) {
				if (engineID.equals(descriptors[i].getId())) {
					IPreferenceStore store = new ScopedPreferenceStore(new InstanceScope(), SSEUIPlugin.getDefault().getBundle().getSymbolicName());
					store.setValue(SpellingService.PREFERENCE_SPELLING_ENGINE, engineID);
					preferredService = new SpellingService(store);
					break;
				}
			}
		}
		return preferredService;
	}

	private boolean isSupportedPartitionType(String type) {
		boolean supported = false;
		if (fSupportedPartitionTypes == null || fSupportedPartitionTypes.length == 0) {
			supported = true;
		}
		else {
			for (int i = 0; i < fSupportedPartitionTypes.length; i++) {
				if (type.equals(fSupportedPartitionTypes[i])) {
					supported = true;
					break;
				}
			}
		}
		return supported;
	}

	/**
	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion,
	 *      org.eclipse.jface.text.IRegion)
	 */
	public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
		if (isCanceled())
			return;

		TemporaryAnnotation[] annotationsToRemove = null;
		IReconcileResult[] annotationsToAdd = null;
		StructuredReconcileStep structuredStep = (StructuredReconcileStep) fSpellingStep;
		IAnnotationModel annotationModel = getAnnotationModel();

		try {
			ITypedRegion[] partitions = TextUtilities.computePartitioning(getDocument(), getDocumentPartitioning(), dirtyRegion.getOffset(), dirtyRegion.getLength(), true);
			for (int i = 0; i < partitions.length; i++) {
				if (isSupportedPartitionType(partitions[i].getType())) {
					annotationsToRemove = getSpellingAnnotationsToRemove(partitions[i]);
					annotationsToAdd = structuredStep.reconcile(dirtyRegion, partitions[i]);

					if (annotationModel instanceof IAnnotationModelExtension) {
						IAnnotationModelExtension modelExtension = (IAnnotationModelExtension) annotationModel;
						Map annotationsToAddMap = new HashMap();
						for (int j = 0; j < annotationsToAdd.length; j++) {
							annotationsToAddMap.put(annotationsToAdd[j], ((TemporaryAnnotation) annotationsToAdd[j]).getPosition());
						}
						modelExtension.replaceAnnotations(annotationsToRemove, annotationsToAddMap);
					}

					else {
						for (int j = 0; j < annotationsToAdd.length; j++) {
							annotationModel.addAnnotation((TemporaryAnnotation) annotationsToAdd[j], ((TemporaryAnnotation) annotationsToAdd[j]).getPosition());
						}
						for (int j = 0; j < annotationsToRemove.length; j++) {
							annotationModel.removeAnnotation(annotationsToRemove[j]);
						}
					}
				}
			}
		}
		catch (BadLocationException e) {
		}

	}

	/**
	 * @param partition
	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
	 */

	public void reconcile(IRegion partition) {
		DirtyRegion region = null;
		try {
			region = new DirtyRegion(partition.getOffset(), partition.getLength(), DirtyRegion.INSERT, getDocument().get(partition.getOffset(), partition.getLength()));
			reconcile(region, region);
		}
		catch (BadLocationException e) {
			Logger.logException(e);
		}
	}

	public void setDocument(IDocument document) {
		super.setDocument(document);
		if (fSpellingStep == null) {
			createReconcileSteps();
		}
		fSpellingStep.setInputModel(new DocumentAdapter(document));
	}

	public void setDocumentPartitioning(String partitioning) {
		fDocumentPartitioning = partitioning;
	}
}