/*******************************************************************************
 * 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.HashMap;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.reconciler.DirtyRegion;
import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.wst.sse.core.internal.model.ModelLifecycleEvent;
import org.eclipse.wst.sse.core.internal.provisional.IModelLifecycleListener;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.events.IStructuredDocumentListener;
import org.eclipse.wst.sse.core.internal.provisional.events.NewDocumentEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionChangedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentRegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegionList;
import org.eclipse.wst.sse.ui.internal.IReleasable;
import org.eclipse.wst.sse.ui.internal.reconcile.validator.ValidatorBuilder;
import org.eclipse.wst.sse.ui.internal.reconcile.validator.ValidatorMetaData;
import org.eclipse.wst.sse.ui.internal.reconcile.validator.ValidatorStrategy;

/**
 * Adds StructuredDocument and StructuredModel listeners. Adds Text viewer
 * (dispose, input changed) listeners.
 * 
 * Implements a smarter "contains" method.
 * 
 * Adds default and validator strategies. Adds DirtyRegion processing logic.
 */
public class StructuredRegionProcessor extends DirtyRegionProcessor implements IStructuredDocumentListener, IModelLifecycleListener {

	/**
	 * Reconclies the entire document when the document in the viewer is
	 * changed. This happens when the document is initially opened, as well as
	 * after a save-as.
	 * 
	 * Also see processPostModelEvent(...) for similar behavior when document
	 * for the model is changed.
	 */
	private class SourceTextInputListener implements ITextInputListener {

		public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
			// do nothing
		}

		public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
			handleInputDocumentChanged(oldInput, newInput);
		}
	}

	/** for initital reconcile when document is opened */
	private SourceTextInputListener fTextInputListener = null;


	/** strategy called for unmapped partitions */
	private IReconcilingStrategy fDefaultStrategy;

	/**
	 * The strategy that runs validators contributed via
	 * <code>org.eclipse.wst.sse.ui.extensions.sourcevalidation</code>
	 * extension point
	 */
	private ValidatorStrategy fValidatorStrategy;
	
	private final String SSE_EDITOR_ID = "org.eclipse.wst.sse.ui"; //$NON-NLS-1$

	/**
	 * @return Returns the fDefaultStrategy.
	 */
	public IReconcilingStrategy getDefaultStrategy() {
		return fDefaultStrategy;
	}

	/**
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor#getAppropriateStrategy(org.eclipse.jface.text.reconciler.DirtyRegion)
	 */
	protected IReconcilingStrategy getStrategy(DirtyRegion dirtyRegion) {
		IReconcilingStrategy strategy = super.getStrategy(dirtyRegion);
		if (strategy == null)
			strategy = getDefaultStrategy();
		return strategy;
	}

	/**
	 * @return Returns the fValidatorStrategy.
	 */
	public ValidatorStrategy getValidatorStrategy() {
		if (fValidatorStrategy == null) {
			ValidatorStrategy validatorStrategy = null;
			
			if (getTextViewer() instanceof ISourceViewer) {
				ISourceViewer viewer = (ISourceViewer)getTextViewer();
				String contentTypeId = null;
				
				IDocument doc = viewer.getDocument();
				IStructuredModel sModel = null;
				try {
					sModel = StructuredModelManager.getModelManager().getExistingModelForRead(doc);
					if (sModel != null) {
						contentTypeId = sModel.getContentTypeIdentifier();
					}
				} finally {
					if (sModel != null)
						sModel.releaseFromRead();
				}
				
				if (contentTypeId != null) {
					validatorStrategy = new ValidatorStrategy(viewer, contentTypeId);
				
					ValidatorBuilder vBuilder = new ValidatorBuilder();
					ValidatorMetaData[] vmds = vBuilder.getValidatorMetaData(SSE_EDITOR_ID);
					for (int i = 0; i < vmds.length; i++) {
						if (vmds[i].canHandleContentType(contentTypeId))
							validatorStrategy.addValidatorMetaData(vmds[i]);
					}
				}
			}
			fValidatorStrategy = validatorStrategy;
		}
		return fValidatorStrategy;
	}

	/**
	 * @param dirtyRegion
	 */
	protected void process(DirtyRegion dirtyRegion) {
		if (!isInstalled())
			return;

		ITypedRegion[] unfiltered = computePartitioning(dirtyRegion);

		// remove duplicate typed regions
		// that are handled by the same "total scope" strategy
		ITypedRegion[] filtered = filterTotalScopeRegions(unfiltered);

		IReconcilingStrategy s;
		DirtyRegion dirty = null;
		for (int i = 0; i < filtered.length; i++) {

			dirty = createDirtyRegion(filtered[i], DirtyRegion.INSERT);
			s = getReconcilingStrategy(filtered[i].getType());
			if (s != null && dirty != null) {
				s.reconcile(dirty, dirty);
			}

			// validator for this partition
			if (fValidatorStrategy != null)
				fValidatorStrategy.reconcile(filtered[i], dirty);
		}
	}

	/**
	 * Removes multiple "total-scope" regions (and leaves one) for a each
	 * partitionType. This improves performance by preventing unnecessary full
	 * document validations.
	 * 
	 * @param unfiltered
	 * @return
	 */
	private ITypedRegion[] filterTotalScopeRegions(ITypedRegion[] unfiltered) {
		IReconcilingStrategy s = null;
		// ensure there is only one typed region in the list
		// for regions handled by "total scope" strategies
		HashMap totalScopeRegions = new HashMap();
		HashMap partialScopeRegions = new HashMap();
		List allRegions = new ArrayList();
		for (int i = 0; i < unfiltered.length; i++) {

			String partitionType = unfiltered[i].getType();

			// short circuit loop
			if (totalScopeRegions.containsKey(partitionType) || partialScopeRegions.containsKey(partitionType))
				continue;

			s = getReconcilingStrategy(partitionType);

			// might be the validator strategy
			if (s == null) {
				ValidatorStrategy validatorStrategy = getValidatorStrategy();
				if (validatorStrategy != null) {
					if (validatorStrategy.canValidatePartition(partitionType))
						s = validatorStrategy;
				}
			}

			if (s instanceof AbstractStructuredTextReconcilingStrategy) {
				// only allow one dirty region for a strategy
				// that has "total scope"
				if (((AbstractStructuredTextReconcilingStrategy) s).isTotalScope())
					totalScopeRegions.put(partitionType, unfiltered[i]);
				else
					partialScopeRegions.put(partitionType, unfiltered[i]);
			}
			else
				partialScopeRegions.put(partitionType, unfiltered[i]);
		}
		allRegions.addAll(totalScopeRegions.values());
		allRegions.addAll(partialScopeRegions.values());
		ITypedRegion[] filtered = (ITypedRegion[]) allRegions.toArray(new ITypedRegion[allRegions.size()]);

		if (DEBUG)
			System.out.println("filtered out this many 'total-scope' regions: " + (unfiltered.length - filtered.length)); //$NON-NLS-1$

		return filtered;
	}

	/**
	 * @param defaultStrategy
	 *            The fDefaultStrategy to set.
	 */
	public void setDefaultStrategy(IReconcilingStrategy defaultStrategy) {
		fDefaultStrategy = defaultStrategy;
		if (fDefaultStrategy != null) {
			fDefaultStrategy.setDocument(getDocument());
			if (fDefaultStrategy instanceof IReconcilingStrategyExtension)
				((IReconcilingStrategyExtension) fDefaultStrategy).setProgressMonitor(getLocalProgressMonitor());
		}
	}

	/**
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor#setDocumentOnAllStrategies(org.eclipse.jface.text.IDocument)
	 */
	protected void setDocumentOnAllStrategies(IDocument document) {

		super.setDocumentOnAllStrategies(document);

		IReconcilingStrategy defaultStrategy = getDefaultStrategy();
		IReconcilingStrategy validatorStrategy = getValidatorStrategy();

		// default strategies
		if (defaultStrategy != null)
			defaultStrategy.setDocument(document);

		// external validator strategy
		if (validatorStrategy != null)
			validatorStrategy.setDocument(document);
	}

	/**
	 * @param validatorStrategy
	 *            The fValidatorStrategy to set.
	 */
	public void setValidatorStrategy(ValidatorStrategy validatorStrategy) {
		fValidatorStrategy = validatorStrategy;
		if (fValidatorStrategy != null) {
			fValidatorStrategy.setDocument(getDocument());
			fValidatorStrategy.setProgressMonitor(getLocalProgressMonitor());
		}
	}

	/**
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor#contains(org.eclipse.jface.text.reconciler.DirtyRegion,
	 *      org.eclipse.jface.text.reconciler.DirtyRegion)
	 */
	protected boolean contains(DirtyRegion root, DirtyRegion possible) {

		// this method is a performance hit
		// look for alternatives

		boolean contains = false;
		IStructuredModel sModel = getStructuredModelForRead(getDocument());
		try {
			IndexedRegion rootRegion = sModel.getIndexedRegion(root.getOffset());
			IndexedRegion possRegion = sModel.getIndexedRegion(possible.getOffset());
			if (rootRegion != null && possRegion != null) {
				int rootStart = rootRegion.getStartOffset();
				int rootEnd = rootRegion.getEndOffset();
				int possStart = possRegion.getStartOffset();
				int possEnd = possRegion.getEndOffset();

				if (rootStart <= possStart && rootEnd >= possEnd)
					contains = true;

				if (DEBUG)
					System.out.println("checking if [" + rootStart + ":" + rootEnd + "] contains [" + possStart + ":" + possEnd + "] ... " + contains); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
			}
		}
		finally {
			if (sModel != null)
				sModel.releaseFromRead();
		}
		return contains;
	}

	/**
	 * Remember to release model after use!!
	 * 
	 * @return
	 */
	public IStructuredModel getStructuredModelForRead(IDocument doc) {

		IStructuredModel sModel = null;
		if (doc != null)
			sModel = StructuredModelManager.getModelManager().getExistingModelForRead(doc);
		return sModel;
	}

	/**
	 * 
	 * @param oldInput
	 * @param newInput
	 */
	public void handleInputDocumentChanged(IDocument oldInput, IDocument newInput) {
		// don't bother if reconciler not installed
		if (isInstalled()) {

			reconcilerDocumentChanged(newInput);

			setDocument(newInput);
			setDocumentOnAllStrategies(newInput);
			setEntireDocumentDirty(newInput);
		}
	}

	/**
	 * @param document
	 */
	private void hookUpModelLifecycleListener(IDocument document) {
		IStructuredModel sModel = getStructuredModelForRead(document);
		try {
			if (sModel != null) {
				sModel.addModelLifecycleListener(this);
			}
		}
		finally {
			if (sModel != null)
				sModel.releaseFromRead();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor#install(org.eclipse.jface.text.ITextViewer)
	 */
	public void install(ITextViewer textViewer) {

		super.install(textViewer);
		fTextInputListener = new SourceTextInputListener();
		textViewer.addTextInputListener(fTextInputListener);
	}

	public void newModel(NewDocumentEvent structuredDocumentEvent) {
		// happens on a revert
		reconcilerDocumentChanged(structuredDocumentEvent.getDocument());
	}

	public void noChange(NoChangeEvent structuredDocumentEvent) {
		// do nothing
	}

	public void nodesReplaced(StructuredDocumentRegionsReplacedEvent structuredDocumentEvent) {
		if (DEBUG)
			System.out.println("[trace reconciler] >StructuredRegionProcessor: *NODES REPLACED"); //$NON-NLS-1$

		DirtyRegion dr = partitionChanged(structuredDocumentEvent) ? createDirtyRegion(0, getDocument().getLength(), DirtyRegion.INSERT) : createDirtyRegion(structuredDocumentEvent.getOffset(), structuredDocumentEvent.getLength(), DirtyRegion.INSERT);
		processDirtyRegion(dr);
	}

	/**
	 * Checks if the StructuredDocumentEvent involved a partition change. If
	 * there's a partition change, we know we should run all strategies just
	 * to be sure we cover the new regions and remove obsolete annotations.
	 * 
	 * A primitive check for now.
	 * 
	 * @param structuredDocumentEvent
	 * @return
	 */
	private boolean partitionChanged(StructuredDocumentRegionsReplacedEvent structuredDocumentEvent) {
		boolean changed = false;

		IStructuredDocumentRegionList oldNodes = structuredDocumentEvent.getOldStructuredDocumentRegions();
		IStructuredDocumentRegionList newNodes = structuredDocumentEvent.getNewStructuredDocumentRegions();

		IStructuredDocumentRegion oldNode = (oldNodes.getLength() > 0) ? oldNode = oldNodes.item(0) : null;
		IStructuredDocumentRegion newNode = (newNodes.getLength() > 0) ? newNodes.item(0) : null;

		if (oldNode != null && newNode != null) {
			try {
				Object oldType = TextUtilities.getContentType(structuredDocumentEvent.getDocument(), getDocumentPartitioning(), oldNode.getStartOffset(), false);
				Object newType = TextUtilities.getContentType(structuredDocumentEvent.getDocument(), getDocumentPartitioning(), newNode.getStartOffset(), false);
				changed = !oldType.equals(newType);
			}
			catch (BadLocationException e) {
				changed = true;
			}
		}
		return changed;
	}

	/**
	 * @see org.eclipse.wst.sse.core.internal.provisional.IModelLifecycleListener#processPostModelEvent(org.eclipse.wst.sse.core.internal.model.ModelLifecycleEvent)
	 */
	public void processPostModelEvent(ModelLifecycleEvent event) {

		// if underlying StructuredDocument changed, need to reconnect it
		// here...
		// ex. file is modified outside the workbench
		if (event.getType() == ModelLifecycleEvent.MODEL_DOCUMENT_CHANGED) {

			// check that it's this model that changed
			IStructuredModel thisModel = getStructuredModelForRead(getDocument());
			try {
				if (thisModel != null && event.getModel().equals(thisModel)) {

					IStructuredDocument sDoc = event.getModel().getStructuredDocument();

					if (DEBUG) {
						System.out.println("======================================================"); //$NON-NLS-1$
						System.out.println("StructuredRegionProcessor: DOCUMENT MODEL CHANGED TO: "); //$NON-NLS-1$
						System.out.println(sDoc.get());
						System.out.println("======================================================"); //$NON-NLS-1$
					}
					setDocument(sDoc);
					// propagate document change
					setDocumentOnAllStrategies(sDoc);
					// ensure that the document is re-reconciled
					setEntireDocumentDirty(sDoc);
				}
			}
			finally {
				if (thisModel != null)
					thisModel.releaseFromRead();
			}
		}
	}

	/**
	 * @see org.eclipse.wst.sse.core.internal.provisional.IModelLifecycleListener#processPreModelEvent(org.eclipse.wst.sse.core.internal.model.ModelLifecycleEvent)
	 */
	public void processPreModelEvent(ModelLifecycleEvent event) {

		if (event.getType() == ModelLifecycleEvent.MODEL_DOCUMENT_CHANGED) {

			getDirtyRegionQueue().clear();
			// note: old annotations are removed via the strategies on
			// AbstractStructuredTextReconcilingStrategy#setDocument(...)
		}
	}

	/**
	 * Reinitializes listeners and sets new document onall strategies.
	 * 
	 * @see org.eclipse.jface.text.reconciler.AbstractReconciler#reconcilerDocumentChanged(IDocument)
	 */
	protected void reconcilerDocumentChanged(IDocument newDocument) {

		IDocument currentDoc = getDocument();

		// unhook old lifecycle listner
		unhookModelLifecycleListener(currentDoc);
		// add new lifecycle listener
		if (newDocument != null)
			hookUpModelLifecycleListener(newDocument);

		// unhook old document listener
		if (currentDoc != null && currentDoc instanceof IStructuredDocument)
			((IStructuredDocument) currentDoc).removeDocumentChangedListener(this);
		// hook up new document listener
		if (newDocument != null && newDocument instanceof IStructuredDocument)
			((IStructuredDocument) newDocument).addDocumentChangedListener(this);

		// sets document on all strategies
		super.reconcilerDocumentChanged(newDocument);
	}

	public void regionChanged(RegionChangedEvent structuredDocumentEvent) {
		if (DEBUG)
			System.out.println("[trace reconciler] >StructuredRegionProcessor: *REGION CHANGED: \r\n\r\n created dirty region from flat model event >> :" + structuredDocumentEvent.getOffset() + ":" + structuredDocumentEvent.getLength() + "\r\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		String dirtyRegionType = structuredDocumentEvent.getDeletedText().equals("") ? DirtyRegion.INSERT : DirtyRegion.REMOVE; //$NON-NLS-1$
		DirtyRegion dr = createDirtyRegion(structuredDocumentEvent.getOffset(), structuredDocumentEvent.getLength(), dirtyRegionType);
		processDirtyRegion(dr);
	}

	public void regionsReplaced(RegionsReplacedEvent structuredDocumentEvent) {
		if (DEBUG)
			System.out.println("[trace reconciler] >StructuredRegionProcessor: *REGIONS REPLACED: \r\n\r\n created dirty region from flat model event >> :" + structuredDocumentEvent.getOffset() + ":" + structuredDocumentEvent.getLength() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		DirtyRegion dr = createDirtyRegion(structuredDocumentEvent.getOffset(), structuredDocumentEvent.getLength(), DirtyRegion.INSERT);
		processDirtyRegion(dr);
	}

	protected void setEntireDocumentDirty(IDocument document) {

		// make the entire document dirty
		// this also happens on a "save as"
		if (document != null && isInstalled()) {

			// since we're marking the entire doc dirty
			getDirtyRegionQueue().clear();
			DirtyRegion entireDocument = createDirtyRegion(0, document.getLength(), DirtyRegion.INSERT);
			processDirtyRegion(entireDocument);
		}
	}

	/**
	 * @param document
	 */
	private void unhookModelLifecycleListener(IDocument document) {
		IStructuredModel sModel = getStructuredModelForRead(document);
		try {
			if (sModel != null)
				sModel.removeModelLifecycleListener(this);

		}
		finally {
			if (sModel != null)
				sModel.releaseFromRead();
		}
	}

	/**
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor#uninstall()
	 */
	public void uninstall() {
		if (isInstalled()) {

			getLocalProgressMonitor().setCanceled(true);
			cancel();

			// removes model listeners
			unhookModelLifecycleListener(getDocument());

			// removes document listeners
			reconcilerDocumentChanged(null);

			// removes widget listener
			getTextViewer().removeTextInputListener(fTextInputListener);
			// getTextViewer().getTextWidget().removeDisposeListener(fDisposeListener);

			// release all strategies
			List strategyTypes = getStrategyTypes();
			if (!strategyTypes.isEmpty()) {
				Iterator it = strategyTypes.iterator();
				IReconcilingStrategy strategy = null;
				while (it.hasNext()) {
					strategy = getReconcilingStrategy((String) it.next());
					if (strategy instanceof IReleasable) {
						((IReleasable) strategy).release();
						strategy = null;
					}
				}
			}
		}
		super.uninstall();
	}
}
