/*******************************************************************************
 * 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.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.IStructuredModel;
import org.eclipse.wst.sse.core.IndexedRegion;
import org.eclipse.wst.sse.core.StructuredModelManager;
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.StructuredTextReconciler;
import org.eclipse.wst.sse.ui.internal.Logger;


/**
 * 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 = StructuredModelManager.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);
	}
}
