package org.eclipse.jface.text.reconciler;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */


import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.swt.widgets.Listener;

import org.eclipse.core.runtime.IProgressMonitor;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TypedRegion;
import org.eclipse.jface.util.Assert;



/**
 * Abstract implementation of <code>IReconciler</code>. The reconciler
 * listens to input document changes as well as changes of
 * the input document of the text viewer it is installed on. Depending on 
 * its configuration it manages the received change notifications in a 
 * queue folding neighboring or overlapping changes together. After the
 * configured period of time, it processes one dirty region after the other.
 * A reconciler is started using its <code>install</code> method. It is the
 * clients responsibility to stop a reconciler using its <code>uninstall</code>
 * method. Unstopped reconcilers do not free their resources.<p>
 * It is subclass responsibility to specify how dirty regions are processed.
 *
 * @see IReconciler
 * @see IDocumentListener
 * @see ITextInputListener
 * @see DirtyRegion
 */
abstract public class AbstractReconciler implements IReconciler {

	
	/**
	 * Background thread for the periodic reconciling activity.
	 */
	class BackgroundThread extends Thread {
		
		/** Has the reconciler been canceled */
		private boolean fCanceled= false;
		/** Has the reconciler been reset */
		private boolean fReset= false;
		/** Has a change been applied */
		private boolean fIsDirty= false;
		/** Is a reconciling strategy active */
		private boolean fIsActive= false;
		
		/**
		 * Creates a new background thread. The thread 
		 * runs with minimal priority.
		 *
		 * @param name the thread's name
		 */
		public BackgroundThread(String name) {
			super(name);
			setPriority(Thread.MIN_PRIORITY);
			setDaemon(true);
		}
		
		/**
		 * Returns whether a reconciling strategy is active right now.
		 *
		 * @return <code>true</code> if a activity is active
		 */
		public boolean isActive() {
			return fIsActive;
		}
		
		/**
		 * Cancels the background thread.
		 */
		public void cancel() {
			fCanceled= true;
			synchronized (fDirtyRegionQueue) {
				fDirtyRegionQueue.notifyAll();
			}
		}
		
		/**
		 * Reset the background thread as the text viewer has been changed,
		 */
		public void reset() {
			
			if (fDelay > 0) {
				
				synchronized (this) {
					fIsDirty= true;
					fReset= true;
				}
				
			} else {
				
				synchronized(this) {
					fIsDirty= true;
				}
				
				synchronized (fDirtyRegionQueue) {
					fDirtyRegionQueue.notifyAll();
				}
			}
		}
		
		/**
		 * The periodic activity. Wait until there is something in the
		 * queue managing the changes applied to the text viewer. Remove the
		 * first change from the queue and process it.
		 */
		public void run() {
			
			synchronized (fDirtyRegionQueue) {
				try {
					fDirtyRegionQueue.wait(fDelay);
				} catch (InterruptedException x) {
				}
			}
			
			initialProcess();
			
			while (!fCanceled) {
				
				synchronized (fDirtyRegionQueue) {
					try {
						fDirtyRegionQueue.wait(fDelay);
					} catch (InterruptedException x) {
					}
				}
					
				if (fCanceled)
					break;
					
				if (!fIsDirty)
					continue;
					
				if (fReset) {
					synchronized (this) {
						fReset= false;
					}
					continue;
				}
				
				DirtyRegion r= null;
				synchronized (fDirtyRegionQueue) {
					r= fDirtyRegionQueue.removeNextDirtyRegion();
				}
					
				fIsActive= true;
				
				if (fProgressMonitor != null)
					fProgressMonitor.setCanceled(false);
					
				process(r);
				
				synchronized (this) {
					fIsDirty= false;
				}
				
				fIsActive= false;
			}
		}
	};
	
	/**
	 * Internal document listener and text input listener.
	 */
	class Listener implements IDocumentListener, ITextInputListener {
		
		/*
		 * @see IDocumentListener#documentAboutToBeChanged
		 */
		public void documentAboutToBeChanged(DocumentEvent e) {
		}
		
		/*
		 * @see IDocumentListener#documentChanged
		 */
		public void documentChanged(DocumentEvent e) {
			
			if (fProgressMonitor != null && fThread.isActive())
				fProgressMonitor.setCanceled(true);
				
			if (fIsIncrementalReconciler)
				createDirtyRegion(e);
				
			fThread.reset();
		}
		
		/*
		 * @see ITextInputListener#inputDocumentAboutToBeChanged
		 */
		public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
			
			if (oldInput == fDocument) {
				
				if (fDocument != null)
					fDocument.removeDocumentListener(this);
					
				if (fIsIncrementalReconciler) {
					fDirtyRegionQueue.purgeQueue();
					if (fDocument != null && fDocument.getLength() > 0) {
						DocumentEvent e= new DocumentEvent(fDocument, 0, fDocument.getLength(), null);
						createDirtyRegion(e);
					}
				}
				
				fDocument= null;
			}
		}
		
		/*
		 * @see ITextInputListener#inputDocumentChanged
		 */
		public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
			
			if (newInput == null)
				return;
				
			fDocument= newInput;
			reconcilerDocumentChanged(fDocument);
				
			fDocument.addDocumentListener(this);
				
			if (fIsIncrementalReconciler) {
				DocumentEvent e= new DocumentEvent(fDocument, 0, 0, fDocument.get());
				createDirtyRegion(e);
			}
			
			if (oldInput == null && !fThread.isAlive())
				fThread.start();
			else
				fThread.reset();
		}
	};
	
	/** Queue to manage the changes applied to the text viewer */
	private DirtyRegionQueue fDirtyRegionQueue;
	/** The background thread */
	private BackgroundThread fThread;
	/** Internal document and text input listener */
	private Listener fListener;
	/** The background thread delay */
	private int fDelay= 500;
	/** Are there incremental reconciling strategies? */
	private boolean fIsIncrementalReconciler= true;
	/** The progress monitor used by this reconciler */
	private IProgressMonitor fProgressMonitor;

	/** The text viewer's document */
	private IDocument fDocument;
	/** The text viewer */
	private ITextViewer fViewer;
	
	
	/**
	 * Processes a dirty region. If the dirty region is <code>null</code> the whole
	 * document is consider being dirty. The dirty region is partitioned by the
	 * document and each partition is handed over to a reconciling strategy registered
	 * for the partition's content type.
	 *
	 * @param dirtyRegion the dirty region to be processed
	 */
	abstract protected void process(DirtyRegion dirtyRegion);
	
	/**
	 * Hook called when the document whose contents should be reconciled
	 * has been changed, i.e., the input document of the text viewer this
	 * reconciler is installed on. Usually, subclasses use this hook to 
	 * inform all their reconciling strategies about the change.
	 * 
	 * @param newDocument the new reconciler document
	 */
	abstract protected void reconcilerDocumentChanged(IDocument newDocument);
	
	
	/**
	 * Creates a new reconciler with the following configuration: it is
	 * an incremental reconciler which kicks in every 500 ms. There are no
	 * predefined reconciling strategies.
	 */ 
	protected AbstractReconciler() {
		super();
	}
		
	/**
	 * Tells the reconciler how long it should collect text changes before
	 * it activates the appropriate reconciling strategies.
	 *
	 * @param delay the duration in milli seconds of a change collection period.
	 */
	public void setDelay(int delay) {
		fDelay= delay;
	}
	
	/**
	 * Tells the reconciler whether any of the available reconciling strategies
	 * is interested in getting detailed dirty region information or just in the
	 * fact the the document has been changed. In the second case, the reconciling 
	 * can not incrementally be pursued.
	 *
	 * @param isIncremental indicates whether this reconciler will be configured with
	 *		incremental reconciling strategies
	 *
	 * @see DirtyRegion
	 * @see IReconcilingStrategy
	 */
	public void setIsIncrementalReconciler(boolean isIncremental) {
		fIsIncrementalReconciler= isIncremental;
	}
	
	/**
	 * Sets the progress monitor of this reconciler.
	 * 
	 * @param monitor the monitor to be used
	 */
	public void setProgressMonitor(IProgressMonitor monitor) {
		fProgressMonitor= monitor;
	}
	
	/**
	 * Returns whether any of the reconciling strategies is interested in
	 * detailed dirty region information.
	 * 
	 * @return whether this reconciler is incremental
	 * 
	 * @see IReconcilingStrategy 
	 */
	protected boolean isIncrementalReconciler() {
		return fIsIncrementalReconciler;
	}
	
	/**
	 * Returns the input document of the text viewer this reconciler is installed on.
	 * 
	 * @return the reconciler document
	 */
	protected IDocument getDocument() {
		return fDocument;
	}
	
	/**
	 * Returns the text viewer this reconciler is installed on.
	 * 
	 * @return the text viewer this reconciler is installed on
	 */
	protected ITextViewer getTextViewer() {
		return fViewer;
	}
	
	/**
	 * Returns the progress monitor of this reconciler.
	 * 
	 * @return the progress monitor of this reconciler
	 */
	protected IProgressMonitor getProgressMonitor() {
		return fProgressMonitor;
	}
	
	/*
	 * @see IReconciler#install
	 */
	public void install(ITextViewer textViewer) {
		
		Assert.isNotNull(textViewer);
		
		fViewer= textViewer;
		
		fListener= new Listener();
		fViewer.addTextInputListener(fListener);
		
		fDirtyRegionQueue= new DirtyRegionQueue();
		fThread= new BackgroundThread(getClass().getName());
	}
	
	/*
	 * @see IReconciler#uninstall
	 */
	public void uninstall() {
		if (fListener != null) {
			
			fViewer.removeTextInputListener(fListener);
			if (fDocument != null) fDocument.removeDocumentListener(fListener);
			fListener= null;
			
			fThread.cancel();
			fThread= null;
		}
	}
		
	/**
	 * Creates a dirty region for a document event and adds it to the queue.
	 *
	 * @param e the document event for which to create a dirty region
	 */
	private void createDirtyRegion(DocumentEvent e) {
		
		if (e.getLength() == 0 && e.getText() != null) {
			// Insert
			fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getText().length(), DirtyRegion.INSERT, e.getText()));
				
		} else if (e.getText() == null || e.getText().length() == 0) {
			// Remove
			fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getLength(), DirtyRegion.REMOVE, null));
				
		} else {
			// Replace (Remove + Insert)
			fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getLength(), DirtyRegion.REMOVE, null));
			fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getText().length(), DirtyRegion.INSERT, e.getText()));
		}
	}
	
	/**
	 * This method is called on startup of the background activity. It is called only
	 * once during the life time of the reconciler. Clients may reimplement this method.
	 */
	protected void initialProcess() {
	}
}
