/*******************************************************************************
 * Copyright (c) 2009, 2010 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.style;

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

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.reconciler.DirtyRegion;
import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.wst.sse.core.internal.model.ModelManagerImpl;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
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.ui.ISemanticHighlighting;
import org.eclipse.wst.sse.ui.ISemanticHighlightingExtension;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.style.SemanticHighlightingManager.HighlightedPosition;
import org.eclipse.wst.sse.ui.internal.style.SemanticHighlightingManager.HighlightingStyle;

/**
 * Semantic highlighting reconciler for Structured Source Editors. Based on 
 * org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightingReconciler
 *
 * @since 3.1
 */
public class SemanticHighlightingReconciler implements IReconcilingStrategy, IReconcilingStrategyExtension {

	private IDocument fDocument;

	private ITextViewer fViewer;
	private SemanticHighlightingPresenter fPresenter;
	private ISemanticHighlighting[] fSemanticHighlightings;
	private HighlightingStyle[] fHighlightings;

	private List fAddedPositions = new ArrayList();
	private List fRemovedPositions = new ArrayList();
	/** Number of removed positions */
	private int fNOfRemovedPositions;
	
	/** Background job */
	private Job fJob;
	/** Background job lock */
	private final Object fJobLock = new Object();
	
	/** Reconcile operation lock. */
	private final Object fReconcileLock = new Object();
	private boolean fIsReconciling = false;
	/** The semantic highlighting presenter - cache for background thread, only valid during {@link #reconcile(IRegion)} */
	private SemanticHighlightingPresenter fJobPresenter;
	/** Semantic highlightings - cache for background thread, only valid during {@link #reconcile(IRegion)} */
	private ISemanticHighlighting[] fJobSemanticHighlightings;
	/** HighlightingStyle - cache for background thread, only valid during {@link #reconcile(IRegion)} */
	private HighlightingStyle[] fJobHighlightings;

	private boolean fIsInstalled;

	public void install(ITextViewer sourceViewer, SemanticHighlightingPresenter presenter, ISemanticHighlighting[] semanticHighlightings, HighlightingStyle[] highlightings) {
		fViewer = sourceViewer;
		fPresenter = presenter;
		fSemanticHighlightings = semanticHighlightings;
		fHighlightings = highlightings;
		fIsInstalled = true;
	}

	public void uninstall() {
		fIsInstalled = false;
		fViewer = null;
		fPresenter = null;
		fSemanticHighlightings = null;
		fHighlightings = null;
	}

	public void reconcile(IRegion partition) {
		// ensure at most one thread can be reconciling at any time
		synchronized (fReconcileLock) {
			if (fIsReconciling)
				return;
			else
				fIsReconciling= true;
		}
		fJobPresenter = fPresenter;
		fJobSemanticHighlightings = fSemanticHighlightings;
		fJobHighlightings = fHighlightings;
		IStructuredModel model = null;
		try {
			if (fJobPresenter == null || fJobSemanticHighlightings == null || fJobHighlightings == null)
				return;

			fJobPresenter.setCanceled(false);
		
			startReconcilingPositions();
			IStructuredDocument document = (IStructuredDocument) fDocument;
			model = ModelManagerImpl.getInstance().getModelForRead(document);
			IStructuredDocumentRegion[] regions = document.getStructuredDocumentRegions(partition.getOffset(), partition.getLength());
			for (int i = 0; i < regions.length && fIsInstalled; i++) {
				if (document.containsReadOnly(regions[i].getStartOffset(), regions[i].getLength()))
					addPosition(new Position(regions[i].getStartOffset(), regions[i].getLength()), null, true);
				else {
					for (int j = 0; j < fJobSemanticHighlightings.length && fIsInstalled; j++) {
						if (fJobHighlightings[j].isEnabled()) {
							Position[] consumes = null;
							if (fJobSemanticHighlightings[j] instanceof ISemanticHighlightingExtension && model != null) {
								consumes = ((ISemanticHighlightingExtension) fJobSemanticHighlightings[j]).consumes(regions[i], model.getIndexedRegion(regions[i].getStartOffset()));
							}
							else {
								consumes = fJobSemanticHighlightings[j].consumes(regions[i]);
							}
							if (consumes != null) {
								for (int k = 0; k < consumes.length; k++)
									addPosition(consumes[k], fJobHighlightings[j]);
							}
						}
					}
				}
			}

			if (fIsInstalled) {
				List oldPositions = fRemovedPositions;
				List newPositions = new ArrayList(fNOfRemovedPositions);
				for (int i = 0, n = oldPositions.size(); i < n && fIsInstalled; i++) {
					Object current = oldPositions.get(i);
					if (current != null)
						newPositions.add(current);
				}
				fRemovedPositions = newPositions;
				
				TextPresentation presentation = null;
				if (!fJobPresenter.isCanceled())
					presentation = fJobPresenter.createPresentation(fAddedPositions, fRemovedPositions);
				if (!fJobPresenter.isCanceled())
					updatePresentation(presentation, fAddedPositions, fRemovedPositions);
			}
			stopReconcilingPositions();
		}
		finally {
			fJobPresenter= null;
			fJobSemanticHighlightings= null;
			fJobHighlightings= null;
			if (model != null)
				model.releaseFromRead();
			synchronized (fReconcileLock) {
				fIsReconciling= false;
			}
		}
	}

	private void addPosition(Position position, HighlightingStyle highlighting) {
		addPosition(position, highlighting, false);
	}

	private void addPosition(Position position, HighlightingStyle highlighting, boolean isReadOnly) {
		boolean isExisting = false;
		// TODO: use binary search
		for (int i = 0, n = fRemovedPositions.size(); i < n; i++) {
			HighlightedPosition highlightedPosition = (HighlightedPosition) fRemovedPositions.get(i);
			if (highlightedPosition == null)
				continue;
			if (highlightedPosition.isEqual(position, highlighting)) {
				isExisting = true;
				fRemovedPositions.set(i, null);
				fNOfRemovedPositions--;
				break;
			}
		}
		if (!isExisting) {
			fAddedPositions.add(fJobPresenter.createHighlightedPosition(position, highlighting, isReadOnly));
		}
	}

	/**
	 * Update the presentation.
	 * 
	 * @param textPresentation
	 *            the text presentation
	 * @param addedPositions
	 *            the added positions
	 * @param removedPositions
	 *            the removed positions
	 */
	private void updatePresentation(TextPresentation textPresentation, List addedPositions, List removedPositions) {
		Runnable runnable = fJobPresenter.createUpdateRunnable(textPresentation, addedPositions, removedPositions);
		if (runnable == null)
			return;

		if (fViewer == null)
			return;

		Control viewerControl = fViewer.getTextWidget();
		if (viewerControl == null)
			return;

		Display display = viewerControl.getDisplay();
		if (display == null || display.isDisposed())
			return;

		display.asyncExec(runnable);
	}

	/**
	 * Start reconciling positions.
	 */
	private void startReconcilingPositions() {
		fJobPresenter.addAllPositions(fRemovedPositions);
		fNOfRemovedPositions = fRemovedPositions.size();
	}

	/**
	 * Stop reconciling positions.
	 */
	private void stopReconcilingPositions() {
		fRemovedPositions.clear();
		fNOfRemovedPositions = 0;
		fAddedPositions.clear();
	}

	public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
		reconcile(dirtyRegion);
	}

	public void setDocument(IDocument document) {
		fDocument = document;
		refresh();
	}

	public void initialReconcile() {
		// Do nothing
	}

	public void setProgressMonitor(IProgressMonitor monitor) {
	}
	
	/**
	 * Schedule a background job for reconciling the Semantic Highlighting model.
	 */
	private void scheduleJob() {
		synchronized (fJobLock) {
			final Job oldJob= fJob;
			if (fJob != null) {
				fJob.cancel();
				fJob= null;
			}

			fJob= new Job("Semantic Highlighting Job") {
				protected IStatus run(IProgressMonitor monitor) {
					if (oldJob != null) {
						try {
							oldJob.join();
						} catch (InterruptedException e) {
							Logger.logException(e);
							return Status.CANCEL_STATUS;
						}
					}
					if (monitor.isCanceled())
						return Status.CANCEL_STATUS;

					reconcile(new Region(0, fDocument.getLength()));
					synchronized (fJobLock) {
						// allow the job to be gc'ed
						if (fJob == this)
							fJob= null;
					}
					return Status.OK_STATUS;
				}
			};
			fJob.setSystem(true);
			fJob.setPriority(Job.DECORATE);
			fJob.schedule();
		}
	}

	public void refresh() {
		if (fDocument != null)
			scheduleJob();
	}
}
