/*******************************************************************************
 * Copyright (c) 2001, 2004 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui.internal.reconcile;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
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.reconciler.IReconcilingStrategy;
import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.wst.sse.core.IModelManagerPlugin;
import org.eclipse.wst.sse.core.IStructuredModel;
import org.eclipse.wst.sse.core.IndexedRegion;
import org.eclipse.wst.sse.core.text.IStructuredDocument;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.util.Assert;
import org.eclipse.wst.sse.ui.IReleasable;
import org.eclipse.wst.sse.ui.ITemporaryAnnotation;
import org.eclipse.wst.sse.ui.Logger;
import org.eclipse.wst.sse.ui.StructuredTextReconciler;


/**
 * A base ReconcilingStrategy. Subclasses must implement
 * createReconcileSteps().
 * 
 * @author pavery
 */
public abstract class AbstractStructuredTextReconcilingStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension, IReleasable, IStructuredReconcilingStrategy {

	protected boolean fAlreadyRemovedAllThisRun = false;
	protected IDocument fDocument = null;

	protected IReconcileStep fFirstStep = null;
	protected IProgressMonitor fProgressMonitor = null;
	protected ITextEditor fTextEditor = null;

	/**
	 * Creates a new strategy. The editor parameter is for access to the
	 * annotation model.
	 * 
	 * @param editor
	 */
	public AbstractStructuredTextReconcilingStrategy(ITextEditor editor) {
		fTextEditor = editor;
		init();
	}

	/**
	 * This is where we add results to the annotationModel, doing any special
	 * "extra" processing.
	 */
	protected void addResultToAnnotationModel(IReconcileResult result) {
		if (!(result instanceof TemporaryAnnotation))
			return;
		// can be null when closing the editor
		if (getAnnotationModel() != null) {
			TemporaryAnnotation tempAnnotation = (TemporaryAnnotation) result;
			getAnnotationModel().addAnnotation(tempAnnotation, tempAnnotation.getPosition());
		}
	}

	/**
	 * @param object
	 * @return if this strategy is responisble for adding this type of key
	 */
	protected boolean canHandlePartition(String partition) {
		String[] haystack = getPartitionTypes();
		for (int i = 0; i < haystack.length; i++) {
			if (haystack[i].equals(partition))
				return true;
		}
		return false;
	}

	/**
	 * @param step
	 * @return
	 */
	protected boolean containsStep(IReconcileStep step) {
		if (fFirstStep instanceof IStructuredReconcileStep)
			return ((IStructuredReconcileStep) fFirstStep).isSiblingStep(step);
		return false;
	}

	/**
	 * This is where you should create the steps for this strategy
	 */
	abstract public void createReconcileSteps();

	/**
	 * Remove ALL temporary annotations that this strategy can handle.
	 */
	protected TemporaryAnnotation[] getAllAnnotationsToRemove() {
		List removals = new ArrayList();
		IAnnotationModel annotationModel = getAnnotationModel();
		if (annotationModel != null) {
			Iterator i = annotationModel.getAnnotationIterator();
			while (i.hasNext()) {
				Object obj = i.next();
				if (!(obj instanceof ITemporaryAnnotation))
					continue;

				ITemporaryAnnotation annotation = (ITemporaryAnnotation) obj;
				IReconcileAnnotationKey key = (IReconcileAnnotationKey) annotation.getKey();
				// then if this strategy knows how to add/remove this
				// partition type
				if (canHandlePartition(key.getPartitionType()) && containsStep(key.getStep()))
					removals.add(annotation);
			}
		}
		return (TemporaryAnnotation[]) removals.toArray(new TemporaryAnnotation[removals.size()]);
	}

	protected IAnnotationModel getAnnotationModel() {
		IAnnotationModel model = null;
		if (fTextEditor != null && fTextEditor.getEditorInput() != null) {
			model = fTextEditor.getDocumentProvider().getAnnotationModel(fTextEditor.getEditorInput());
		}
		return model;
	}

	protected TemporaryAnnotation[] getAnnotationsToRemove(DirtyRegion dr) {
		IStructuredDocumentRegion[] sdRegions = getStructuredDocumentRegions(dr);
		List remove = 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;
				IReconcileAnnotationKey key = (IReconcileAnnotationKey) annotation.getKey();

				// first check if this annotation is still relevant for the
				// current partition
				if (sdRegions.length > 0) {
					if (!partitionsMatch(key, annotation.getPosition().offset, sdRegions[0])) {
						remove.add(annotation);
						continue;
					}
				}

				// then if this strategy knows how to add/remove this
				// partition type
				if (canHandlePartition(key.getPartitionType()) && containsStep(key.getStep())) {
					if (key.getScope() == IReconcileAnnotationKey.PARTIAL && overlaps(annotation.getPosition(), sdRegions)) {
						remove.add(annotation);
					} else if (key.getScope() == IReconcileAnnotationKey.TOTAL) {
						remove.add(annotation);
					}
				}
			}
		}
		return (TemporaryAnnotation[]) remove.toArray(new TemporaryAnnotation[remove.size()]);
	}

	/**
	 * Returns the corresponding node for the StructuredDocumentRegion.
	 * 
	 * @param sdRegion
	 * @return the corresponding node for sdRegion
	 */
	protected IndexedRegion getCorrespondingNode(IStructuredDocumentRegion sdRegion) {
		IStructuredModel sModel = ((IModelManagerPlugin) Platform.getPlugin(IModelManagerPlugin.ID)).getModelManager().getExistingModelForRead(fDocument);
		IndexedRegion xmlNode = sModel.getIndexedRegion(sdRegion.getStart());
		sModel.releaseFromRead();
		return xmlNode;
	}

	/**
	 * The IFile that this strategy is operating on (the file input for the
	 * TextEditor)
	 * 
	 * @return the IFile that this strategy is operating on
	 */
	protected IFile getFile() {
		if (fTextEditor == null)
			return null;
		IEditorInput input = fTextEditor.getEditorInput();
		if (!(input instanceof IFileEditorInput))
			return null;
		return ((IFileEditorInput) input).getFile();
	}

	/**
	 * pa_TODO - should be temporary until we figure out a way to send in
	 * partition with "reconcile()" call
	 * 
	 * @param sdRegion
	 */
	protected IDocumentPartitioner getPartitioner(IStructuredDocumentRegion sdRegion) {
		Assert.isNotNull(fDocument, "document was null when partitioning information was sought"); //$NON-NLS-1$
		IDocumentPartitioner partitioner = fDocument.getDocumentPartitioner();
		return partitioner;
	}

	/**
	 * Gets partition types from all steps in this strategy.
	 * 
	 * @return parition types from all steps
	 */
	public String[] getPartitionTypes() {
		if (fFirstStep instanceof IStructuredReconcileStep)
			return ((IStructuredReconcileStep) fFirstStep).getPartitionTypes();
		return new String[0];
	}

	/**
	 * Returns the appropriate (first) IStructuredDocumentRegion for the given
	 * dirtyRegion.
	 * 
	 * @param dirtyRegion
	 * @return the appropriate StructuredDocumentRegion for the given
	 *         dirtyRegion.
	 */
	private IStructuredDocumentRegion getStructuredDocumentRegion(int offset) {
		IStructuredDocumentRegion sdRegion = null;
		if (fDocument instanceof IStructuredDocument) {
			sdRegion = ((IStructuredDocument) fDocument).getRegionAtCharacterOffset(offset);
		}
		return sdRegion;
	}

	private IStructuredDocumentRegion[] getStructuredDocumentRegions(DirtyRegion dr) {
		int offset = dr.getOffset();
		int end = offset + dr.getLength();
		List regions = new ArrayList();
		IStructuredDocumentRegion r = getStructuredDocumentRegion(offset);
		while (r != null && r.getStartOffset() <= end) {
			if (!r.isDeleted())
				regions.add(r);
			r = r.getNext();
		}
		return (IStructuredDocumentRegion[]) regions.toArray(new IStructuredDocumentRegion[regions.size()]);
	}

	public void init() {
		createReconcileSteps();
	}

	/**
	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#initialReconcile()
	 */
	public void initialReconcile() {
		// do nothing
	}

	/**
	 * @return
	 */
	protected boolean isCanceled() {
		if (Logger.isTracing(StructuredTextReconciler.TRACE_FILTER) && (fProgressMonitor != null && fProgressMonitor.isCanceled()))
			Logger.trace(StructuredTextReconciler.TRACE_FILTER, "** STRATEGY CANCELED **:" + this.getClass().getName()); //$NON-NLS-1$
		return fProgressMonitor != null && fProgressMonitor.isCanceled();
	}

	/**
	 * Checks if this position overlaps any of the StructuredDocument regions'
	 * correstponding IndexedRegion.
	 * 
	 * @param pos
	 * @param sdRegions
	 * @return true if the position overlaps any of the regions, otherwise
	 *         false.
	 */
	protected boolean overlaps(Position pos, IStructuredDocumentRegion[] sdRegions) {
		int start = -1;
		int end = -1;
		for (int i = 0; i < sdRegions.length; i++) {
			IndexedRegion corresponding = getCorrespondingNode(sdRegions[i]);
			if (start == -1 || start > corresponding.getStartOffset())
				start = corresponding.getStartOffset();
			if (end == -1 || end < corresponding.getEndOffset())
				end = corresponding.getEndOffset();
		}
		//System.out.println("checking overlap: [node:" + start + ":" + end +
		// " pos:" + pos.getOffset() + ":" + pos.getLength() + "> " +
		// pos.overlapsWith(start, end - start));
		return pos.overlapsWith(start, end - start);
	}

	/**
	 * Checks to make sure that the annotation key (partition type for which
	 * it was originally added) matches the current document partition at that
	 * offset. This can occur when the character you just typed caused the
	 * previous (or subsequent) partition type to change.
	 * 
	 * @param key
	 * @param sdRegion
	 * @return the partition type for this annotation matches the current
	 *         document partition type
	 */
	private boolean partitionsMatch(IReconcileAnnotationKey key, int annotationPos, IStructuredDocumentRegion sdRegion) {
		String keyPartitionType = key.getPartitionType();
		IDocumentPartitioner p = getPartitioner(sdRegion);
		String partitionType = p.getPartition(annotationPos).getType();
		return keyPartitionType.equals(partitionType);
	}

	/**
	 * Process the results from the reconcile steps in this strategy.
	 * 
	 * @param results
	 */
	private void process(final IReconcileResult[] results) {
		if (Logger.isTracing(StructuredTextReconciler.TRACE_FILTER))
			Logger.trace(StructuredTextReconciler.TRACE_FILTER, "[trace reconciler] > STARTING PROCESS METHOD with (" + results.length + ") results"); //$NON-NLS-1$ //$NON-NLS-2$

		if (results == null)
			return;

		for (int i = 0; i < results.length; i++) {
			if (isCanceled()) {
				Logger.trace(StructuredTextReconciler.TRACE_FILTER, "[trace reconciler] >** PROCESS (adding) WAS CANCELLED **"); //$NON-NLS-1$
				return;
			}
			addResultToAnnotationModel(results[i]);
		}
		// tracing
		// --------------------------------------------------------------------
		if (Logger.isTracing(StructuredTextReconciler.TRACE_FILTER)) {
			StringBuffer traceString = new StringBuffer();
			for (int j = 0; j < results.length; j++)
				traceString.append("\n (+) :" + results[j] + ":\n"); //$NON-NLS-1$ //$NON-NLS-2$
			Logger.trace(StructuredTextReconciler.TRACE_FILTER, "[trace reconciler] > PROCESSING (" + results.length + ") results in AbstractStructuredTextReconcilingStrategy " + traceString); //$NON-NLS-1$ //$NON-NLS-2$
		}
		//------------------------------------------------------------------------------
	}

	/**
	 * @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) {

		// external files may be null
		if (isCanceled() || fFirstStep == null)
			return;

		reconcile(dirtyRegion, subRegion, false);
	}

	/**
	 * Like IReconcileStep.reconcile(DirtyRegion dirtyRegion, IRegion
	 * subRegion) but also aware of the fact that the reconciler is running a
	 * processAll() operation, and short circuits removal and reconcile calls
	 * accordingly.
	 * 
	 * @param dirtyRegion
	 * @param refreshAll
	 * @param subRegion
	 * @see IStructuredReconcilingStrategy#reconcile(DirtyRegion, IRegion,
	 *      boolean)
	 */
	public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion, boolean refreshAll) {

		// external files may be null
		if (isCanceled() || fFirstStep == null)
			return;

		IStructuredDocumentRegion sdRegion = getStructuredDocumentRegion(dirtyRegion.getOffset());
		if (sdRegion == null)
			return;

		TemporaryAnnotation[] annotationsToRemove = new TemporaryAnnotation[0];
		IReconcileResult[] annotationsToAdd = new IReconcileResult[0];
		IStructuredReconcileStep structuredStep = (IStructuredReconcileStep) fFirstStep;
		if (!refreshAll) {
			// regular reconcile
			annotationsToRemove = getAnnotationsToRemove(dirtyRegion);
			annotationsToAdd = structuredStep.reconcile(dirtyRegion, subRegion);
			fAlreadyRemovedAllThisRun = false;
		} else {
			// the entire document is being reconciled (strategies may be
			// called multiple times)
			if (!fAlreadyRemovedAllThisRun) {
				annotationsToRemove = getAllAnnotationsToRemove();
				fAlreadyRemovedAllThisRun = true;
			}
			annotationsToAdd = structuredStep.reconcile(dirtyRegion, subRegion, true);
		}
		smartProcess(annotationsToRemove, annotationsToAdd);
	}

	/**
	 * @param partition
	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
	 */
	public void reconcile(IRegion partition) {
		// not used, we use - reconcile(DirtyRegion dirtyRegion, IRegion
		// subRegion)
	}

	/**
	 * Calls release() on all the steps in this strategy. Currently done in
	 * StructuredTextReconciler.SourceWidgetDisposeListener#widgetDisposed(...)
	 */
	public void release() {
		// release steps (each step calls release on the next)
		if (fFirstStep != null && fFirstStep instanceof IReleasable)
			((IReleasable) fFirstStep).release();
		// we don't to null out the steps, in case
		// it's reconfigured later
		//fFirstStep = null;
	}

	private void removeAnnotations(TemporaryAnnotation[] annotationsToRemove) {
		IAnnotationModel annotationModel = getAnnotationModel();
		// can be null when closing the editor
		if (annotationModel != null) {
			for (int i = 0; i < annotationsToRemove.length; i++) {
				if (isCanceled()) {
					Logger.trace(StructuredTextReconciler.TRACE_FILTER, "[trace reconciler] >** REMOVAL WAS CANCELLED **"); //$NON-NLS-1$
					return;
				}
				annotationModel.removeAnnotation(annotationsToRemove[i]);
			}
		}
		// tracing
		// --------------------------------------------------------------------
		if (Logger.isTracing(StructuredTextReconciler.TRACE_FILTER)) {
			StringBuffer traceString = new StringBuffer();
			for (int i = 0; i < annotationsToRemove.length; i++)
				traceString.append("\n (-) :" + annotationsToRemove[i] + ":\n"); //$NON-NLS-1$ //$NON-NLS-2$
			Logger.trace(StructuredTextReconciler.TRACE_FILTER, "[trace reconciler] > REMOVED (" + annotationsToRemove.length + ") annotations in AbstractStructuredTextReconcilingStrategy :" + traceString); //$NON-NLS-1$ //$NON-NLS-2$
		}
		//------------------------------------------------------------------------------
	}

	/**
	 * Resets any specially set for an operation such as processAll() from the
	 * reconciler.
	 */
	public void reset() {
		fAlreadyRemovedAllThisRun = false;
		if (fFirstStep instanceof IStructuredReconcileStep)
			((IStructuredReconcileStep) fFirstStep).reset();
	}

	/**
	 * Set the document for this strategy.
	 * 
	 * @param document
	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#setDocument(org.eclipse.jface.text.IDocument)
	 */
	public void setDocument(IDocument document) {

		// remove all old annotations since it's a new document
		removeAnnotations(getAllAnnotationsToRemove());

		if (document == null)
			release();

		fDocument = document;
		if (fFirstStep != null)
			fFirstStep.setInputModel(new DocumentAdapter(document));
	}

	/**
	 * @param monitor
	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void setProgressMonitor(IProgressMonitor monitor) {
		fProgressMonitor = monitor;
		if (fFirstStep != null)
			fFirstStep.setProgressMonitor(fProgressMonitor);
	}

	/**
	 * pa_TODO make adding/removing smarter... Check if the annotation is
	 * already there, if it is, no need to remove or add again. this will
	 * avoid a lot of flickering behavior...
	 * 
	 * @param annotationsToRemove
	 * @param annotationsToAdd
	 */

	protected void smartProcess(TemporaryAnnotation[] annotationsToRemove, IReconcileResult[] annotationsToAdd) {
		removeAnnotations(annotationsToRemove);
		process(annotationsToAdd);
	}
}
