/*******************************************************************************
 * Copyright (c) 2009 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.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IPositionUpdater;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ISynchronizable;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextPresentationListener;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.internal.StructuredTextViewer;
import org.eclipse.wst.sse.ui.internal.preferences.EditorPreferenceNames;
import org.eclipse.wst.sse.ui.internal.provisional.style.StructuredPresentationReconciler;
import org.eclipse.wst.sse.ui.internal.style.SemanticHighlightingManager.HighlightedPosition;
import org.eclipse.wst.sse.ui.internal.style.SemanticHighlightingManager.HighlightingStyle;
import org.eclipse.wst.sse.ui.internal.util.EditorUtility;

/**
 * Semantic highlighting presenter - UI thread implementation.  Based on 
 * org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightingPresenter
 *
 * @since 3.1
 */
public class SemanticHighlightingPresenter implements ITextPresentationListener, ITextInputListener, IDocumentListener {

	/**
	 * Semantic highlighting position updater.
	 */
	private class HighlightingPositionUpdater implements IPositionUpdater {

		/** The position category. */
		private final String fCategory;

		/**
		 * Creates a new updater for the given <code>category</code>.
		 *
		 * @param category the new category.
		 */
		public HighlightingPositionUpdater(String category) {
			fCategory= category;
		}

		/*
		 * @see org.eclipse.jface.text.IPositionUpdater#update(org.eclipse.jface.text.DocumentEvent)
		 */
		public void update(DocumentEvent event) {

			int eventOffset= event.getOffset();
			int eventOldLength= event.getLength();
			int eventEnd= eventOffset + eventOldLength;

			try {
				Position[] positions= event.getDocument().getPositions(fCategory);

				for (int i= 0; i != positions.length; i++) {

					HighlightedPosition position= (HighlightedPosition) positions[i];

					// Also update deleted positions because they get deleted by the background thread and removed/invalidated only in the UI runnable
//					if (position.isDeleted())
//						continue;

					int offset= position.getOffset();
					int length= position.getLength();
					int end= offset + length;

					if (offset > eventEnd)
						updateWithPrecedingEvent(position, event);
					else if (end < eventOffset) {
						// do nothing
						// updateWithSucceedingEvent(position, event);
					}
					else if (offset <= eventOffset && end >= eventEnd)
						updateWithIncludedEvent(position, event);
					else if (offset <= eventOffset)
						updateWithOverEndEvent(position, event);
					else if (end >= eventEnd)
						updateWithOverStartEvent(position, event);
					else
						updateWithIncludingEvent(position, event);
				}
			} catch (BadPositionCategoryException e) {
				// ignore and return
			}
		}

		/**
		 * Update the given position with the given event. The event precedes the position.
		 *
		 * @param position The position
		 * @param event The event
		 */
		private void updateWithPrecedingEvent(HighlightedPosition position, DocumentEvent event) {
			String newText= event.getText();
			int eventNewLength= newText != null ? newText.length() : 0;
			int deltaLength= eventNewLength - event.getLength();

			position.setOffset(position.getOffset() + deltaLength);
		}

		/**
		 * Update the given position with the given event. The event succeeds the position.
		 *
		 * @param position The position
		 * @param event The event
		 */
//		private void updateWithSucceedingEvent(HighlightedPosition position, DocumentEvent event) {
//		}

		/**
		 * Update the given position with the given event. The event is included by the position.
		 *
		 * @param position The position
		 * @param event The event
		 */
		private void updateWithIncludedEvent(HighlightedPosition position, DocumentEvent event) {
			int eventOffset= event.getOffset();
			String newText= event.getText();
			if (newText == null)
				newText= ""; //$NON-NLS-1$
			int eventNewLength= newText.length();

			int deltaLength= eventNewLength - event.getLength();

			int offset= position.getOffset();
			int length= position.getLength();
			int end= offset + length;

			int includedLength= 0;
			while (includedLength < eventNewLength && !Character.isWhitespace(newText.charAt(includedLength)))
				includedLength++;
			if (includedLength == eventNewLength)
				position.setLength(length + deltaLength);
			else {
				int newLeftLength= eventOffset - offset + includedLength;

				int excludedLength= eventNewLength;
				while (excludedLength > 0 && !Character.isWhitespace(newText.charAt(excludedLength - 1)))
					excludedLength--;
				int newRightOffset= eventOffset + excludedLength;
				int newRightLength= end + deltaLength - newRightOffset;

				if (newRightLength == 0) {
					position.setLength(newLeftLength);
				} else {
					if (newLeftLength == 0) {
						position.update(newRightOffset, newRightLength);
					} else {
						position.setLength(newLeftLength);
						addPositionFromUI(position);
					}
				}
			}
		}

		/**
		 * Update the given position with the given event. The event overlaps with the end of the position.
		 *
		 * @param position The position
		 * @param event The event
		 */
		private void updateWithOverEndEvent(HighlightedPosition position, DocumentEvent event) {
			String newText= event.getText();
			if (newText == null)
				newText= ""; //$NON-NLS-1$
			int eventNewLength= newText.length();

			int includedLength= 0;
			while (includedLength < eventNewLength && !Character.isWhitespace(newText.charAt(includedLength)))
				includedLength++;
			position.setLength(event.getOffset() - position.getOffset() + includedLength);
		}

		/**
		 * Update the given position with the given event. The event overlaps with the start of the position.
		 *
		 * @param position The position
		 * @param event The event
		 */
		private void updateWithOverStartEvent(HighlightedPosition position, DocumentEvent event) {
			int eventOffset= event.getOffset();
			int eventEnd= eventOffset + event.getLength();

			String newText= event.getText();
			if (newText == null)
				newText= ""; //$NON-NLS-1$
			int eventNewLength= newText.length();

			int excludedLength= eventNewLength;
			while (excludedLength > 0 && !Character.isWhitespace(newText.charAt(excludedLength - 1)))
				excludedLength--;
			int deleted= eventEnd - position.getOffset();
			int inserted= eventNewLength - excludedLength;
			position.update(eventOffset + excludedLength, position.getLength() - deleted + inserted);
		}

		/**
		 * Update the given position with the given event. The event includes the position.
		 *
		 * @param position The position
		 * @param event The event
		 */
		private void updateWithIncludingEvent(HighlightedPosition position, DocumentEvent event) {
			position.delete();
			position.update(event.getOffset(), 0);
		}
	}

	/** Position updater */
	private IPositionUpdater fPositionUpdater= new HighlightingPositionUpdater(getPositionCategory());

	/** The source viewer this semantic highlighting reconciler is installed on */
	private StructuredTextViewer fSourceViewer;
	/** The background presentation reconciler */
	private StructuredPresentationReconciler fPresentationReconciler;

	/** UI's current highlighted positions - can contain <code>null</code> elements */
	private List fPositions= new ArrayList();
	/** UI position lock */
	private Object fPositionLock= new Object();

	/** <code>true</code> iff the current reconcile is canceled. */
	private boolean fIsCanceled= false;

	/** Read-only color support */
	private YUV_RGBConverter rgbConverter;
	private Map readOnlyColorTable;
	double readOnlyForegroundScaleFactor = 30;
	
	public SemanticHighlightingPresenter() {
		// no listener for now since there's no UI to change the value
		IPreferenceStore editorStore = SSEUIPlugin.getDefault().getPreferenceStore();
		readOnlyForegroundScaleFactor = editorStore.getInt(EditorPreferenceNames.READ_ONLY_FOREGROUND_SCALE);
	}

	/**
	 * Creates and returns a new highlighted position with the given offset, length and highlighting.
	 * <p>
	 * NOTE: Also called from background thread.
	 * </p>
	 *
	 * @param offset The offset
	 * @param length The length
	 * @param highlighting The highlighting
	 * @return The new highlighted position
	 */
	public HighlightedPosition createHighlightedPosition(int offset, int length, HighlightingStyle highlighting) {
		// TODO: reuse deleted positions
		return new HighlightedPosition(offset, length, highlighting, fPositionUpdater);
	}
	
	/**
	 * Creates and returns a new highlighted position from the given position and highlighting.
	 * <p>
	 * NOTE: Also called from background thread.
	 * </p>
	 *
	 * @param position The position
	 * @param highlighting The highlighting
	 * @return The new highlighted position
	 */
	public HighlightedPosition createHighlightedPosition(Position position, HighlightingStyle highlighting) {
		// TODO: reuse deleted positions
		return new HighlightedPosition(position, highlighting, fPositionUpdater);
	}

	/**
	 * Creates and returns a new highlighted position from the given position and highlighting.
	 * <p>
	 * NOTE: Also called from background thread.
	 * </p>
	 *
	 * @param position The position
	 * @param highlighting The highlighting
	 * @param isReadOnly Is this a read-only position
	 * @return The new highlighted position
	 */
	public HighlightedPosition createHighlightedPosition(Position position, HighlightingStyle highlighting, boolean isReadOnly) {
		// TODO: reuse deleted positions
		return new HighlightedPosition(position, highlighting, fPositionUpdater, isReadOnly);
	}

	/**
	 * Adds all current positions to the given list.
	 * <p>
	 * NOTE: Called from background thread.
	 * </p>
	 *
	 * @param list The list
	 */
	public void addAllPositions(List list) {
		synchronized (fPositionLock) {
			list.addAll(fPositions);
		}
	}

	/**
	 * Create a text presentation in the background.
	 * <p>
	 * NOTE: Called from background thread.
	 * </p>
	 *
	 * @param addedPositions the added positions
	 * @param removedPositions the removed positions
	 * @return the text presentation or <code>null</code>, if reconciliation should be canceled
	 */
	public TextPresentation createPresentation(List addedPositions, List removedPositions) {
		ISourceViewer sourceViewer= fSourceViewer;
		StructuredPresentationReconciler presentationReconciler= fPresentationReconciler;
		if (sourceViewer == null || presentationReconciler == null)
			return null;

		if (isCanceled())
			return null;

		IDocument document= sourceViewer.getDocument();
		if (document == null)
			return null;

		int minStart= Integer.MAX_VALUE;
		int maxEnd= Integer.MIN_VALUE;
		for (int i= 0, n= removedPositions.size(); i < n; i++) {
			Position position= (Position) removedPositions.get(i);
			int offset= position.getOffset();
			minStart= Math.min(minStart, offset);
			maxEnd= Math.max(maxEnd, offset + position.getLength());
		}
		for (int i= 0, n= addedPositions.size(); i < n; i++) {
			Position position= (Position) addedPositions.get(i);
			int offset= position.getOffset();
			minStart= Math.min(minStart, offset);
			maxEnd= Math.max(maxEnd, offset + position.getLength());
		}

		if (minStart < maxEnd)
			try {
				return presentationReconciler.createRepairDescription(new Region(minStart, maxEnd - minStart), document);
			} catch (RuntimeException e) {
				// Assume concurrent modification from UI thread
			}

		return null;
	}

	/**
	 * Create a runnable for updating the presentation.
	 * <p>
	 * NOTE: Called from background thread.
	 * </p>
	 * @param textPresentation the text presentation
	 * @param addedPositions the added positions
	 * @param removedPositions the removed positions
	 * @return the runnable or <code>null</code>, if reconciliation should be canceled
	 */
	public Runnable createUpdateRunnable(final TextPresentation textPresentation, List addedPositions, List removedPositions) {
		if (fSourceViewer == null || textPresentation == null)
			return null;

		// TODO: do clustering of positions and post multiple fast runnables
		final HighlightedPosition[] added= new SemanticHighlightingManager.HighlightedPosition[addedPositions.size()];
		addedPositions.toArray(added);
		final SemanticHighlightingManager.HighlightedPosition[] removed= new SemanticHighlightingManager.HighlightedPosition[removedPositions.size()];
		removedPositions.toArray(removed);

		if (isCanceled())
			return null;

		Runnable runnable= new Runnable() {
			public void run() {
				updatePresentation(textPresentation, added, removed);
			}
		};
		return runnable;
	}

	/**
	 * Invalidate the presentation of the positions based on the given added positions and the existing deleted positions.
	 * Also unregisters the deleted positions from the document and patches the positions of this presenter.
	 * <p>
	 * NOTE: Indirectly called from background thread by UI runnable.
	 * </p>
	 * @param textPresentation the text presentation or <code>null</code>, if the presentation should computed in the UI thread
	 * @param addedPositions the added positions
	 * @param removedPositions the removed positions
	 */
	public void updatePresentation(TextPresentation textPresentation, HighlightedPosition[] addedPositions, HighlightedPosition[] removedPositions) {
		if (fSourceViewer == null)
			return;

//		checkOrdering("added positions: ", Arrays.asList(addedPositions)); //$NON-NLS-1$
//		checkOrdering("removed positions: ", Arrays.asList(removedPositions)); //$NON-NLS-1$
//		checkOrdering("old positions: ", fPositions); //$NON-NLS-1$

		// TODO: double-check consistency with document.getPositions(...)
		// TODO: reuse removed positions
		if (isCanceled())
			return;

		IDocument document= fSourceViewer.getDocument();
		if (document == null)
			return;

		String positionCategory= getPositionCategory();

		List removedPositionsList= Arrays.asList(removedPositions);

		try {
			synchronized (fPositionLock) {
				List oldPositions= fPositions;
				int newSize= Math.max(fPositions.size() + addedPositions.length - removedPositions.length, 10);

				/*
				 * The following loop is a kind of merge sort: it merges two List<Position>, each
				 * sorted by position.offset, into one new list. The first of the two is the
				 * previous list of positions (oldPositions), from which any deleted positions get
				 * removed on the fly. The second of two is the list of added positions. The result
				 * is stored in newPositions.
				 */
				List newPositions= new ArrayList(newSize);
				Position position= null;
				Position addedPosition= null;
				for (int i= 0, j= 0, n= oldPositions.size(), m= addedPositions.length; i < n || position != null || j < m || addedPosition != null;) {
					// loop variant: i + j < old(i + j)

					// a) find the next non-deleted Position from the old list
					while (position == null && i < n) {
						position= (Position) oldPositions.get(i++);
						if (position.isDeleted() || contain(removedPositionsList, position)) {
							document.removePosition(positionCategory, position);
							position= null;
						}
					}

					// b) find the next Position from the added list
					if (addedPosition == null && j < m) {
						addedPosition= addedPositions[j++];
						document.addPosition(positionCategory, addedPosition);
					}

					// c) merge: add the next of position/addedPosition with the lower offset
					if (position != null) {
						if (addedPosition != null)
							if (position.getOffset() <= addedPosition.getOffset()) {
								newPositions.add(position);
								position= null;
							} else {
								newPositions.add(addedPosition);
								addedPosition= null;
							}
						else {
							newPositions.add(position);
							position= null;
						}
					} else if (addedPosition != null) {
						newPositions.add(addedPosition);
						addedPosition= null;
					}
				}
				fPositions= newPositions;
			}
		} catch (BadPositionCategoryException e) {
			// Should not happen
			Logger.logException(e);
		} catch (BadLocationException e) {
			// Should not happen
			Logger.logException(e);
		}
//		checkOrdering("new positions: ", fPositions); //$NON-NLS-1$

		if (textPresentation != null)
			fSourceViewer.changeTextPresentation(textPresentation, false);
		else
			fSourceViewer.invalidateTextPresentation();
	}

//	private void checkOrdering(String s, List positions) {
//		Position previous= null;
//		for (int i= 0, n= positions.size(); i < n; i++) {
//			Position current= (Position) positions.get(i);
//			if (previous != null && previous.getOffset() + previous.getLength() > current.getOffset())
//				return;
//		}
//	}

	/**
	 * Returns <code>true</code> iff the positions contain the position.
	 * @param positions the positions, must be ordered by offset but may overlap
	 * @param position the position
	 * @return <code>true</code> iff the positions contain the position
	 */
	private boolean contain(List positions, Position position) {
		return indexOf(positions, position) != -1;
	}

	/**
	 * Returns index of the position in the positions, <code>-1</code> if not found.
	 * @param positions the positions, must be ordered by offset but may overlap
	 * @param position the position
	 * @return the index
	 */
	private int indexOf(List positions, Position position) {
		int index= computeIndexAtOffset(positions, position.getOffset());
		int size= positions.size();
		while (index < size) {
			if (positions.get(index) == position)
				return index;
			index++;
		}
		return -1;
	}

	/**
	 * Insert the given position in <code>fPositions</code>, s.t. the offsets remain in linear order.
	 *
	 * @param position The position for insertion
	 */
	private void insertPosition(Position position) {
		int i= computeIndexAfterOffset(fPositions, position.getOffset());
		fPositions.add(i, position);
	}

	/**
	 * Returns the index of the first position with an offset greater than the given offset.
	 *
	 * @param positions the positions, must be ordered by offset and must not overlap
	 * @param offset the offset
	 * @return the index of the last position with an offset greater than the given offset
	 */
	private int computeIndexAfterOffset(List positions, int offset) {
		int i= -1;
		int j= positions.size();
		while (j - i > 1) {
			int k= (i + j) >> 1;
			Position position= (Position) positions.get(k);
			if (position.getOffset() > offset)
				j= k;
			else
				i= k;
		}
		return j;
	}

	/**
	 * Returns the index of the first position with an offset equal or greater than the given offset.
	 *
	 * @param positions the positions, must be ordered by offset and must not overlap
	 * @param offset the offset
	 * @return the index of the last position with an offset equal or greater than the given offset
	 */
	private int computeIndexAtOffset(List positions, int offset) {
		int i= -1;
		int j= positions.size();
		while (j - i > 1) {
			int k= (i + j) >> 1;
			Position position= (Position) positions.get(k);
			if (position.getOffset() >= offset)
				j= k;
			else
				i= k;
		}
		return j;
	}

	/*
	 * @see org.eclipse.jface.text.ITextPresentationListener#applyTextPresentation(org.eclipse.jface.text.TextPresentation)
	 */
	public void applyTextPresentation(TextPresentation textPresentation) {
		IRegion region= textPresentation.getExtent();
		int minStart= Integer.MAX_VALUE;
		int maxEnd= Integer.MIN_VALUE;
		int i= computeIndexAtOffset(fPositions, region.getOffset()), n= computeIndexAtOffset(fPositions, region.getOffset() + region.getLength());
		if (n - i > 2) {
			List ranges= new ArrayList(n - i);
			for (; i < n; i++) {
				HighlightedPosition position= (HighlightedPosition) fPositions.get(i);
				if (!position.isDeleted()) {
					if (!position.isReadOnly())
						ranges.add(position.createStyleRange());
					else {
						int offset= position.getOffset();
						minStart= Math.min(minStart, offset);
						maxEnd= Math.max(maxEnd, offset + position.getLength());
					}
						
				}
			}
			StyleRange[] array= new StyleRange[ranges.size()];
			array= (StyleRange[]) ranges.toArray(array);
			textPresentation.replaceStyleRanges(array);
		} else {
			for (; i < n; i++) {
				HighlightedPosition position= (HighlightedPosition) fPositions.get(i);
				if (!position.isDeleted()) {
					if (!position.isReadOnly())
						textPresentation.replaceStyleRange(position.createStyleRange());
					else {
						int offset= position.getOffset();
						minStart= Math.min(minStart, offset);
						maxEnd= Math.max(maxEnd, offset + position.getLength());
					}
				}
			}
		}
		if (minStart < maxEnd) {
			IStructuredDocument document = (IStructuredDocument) fSourceViewer.getDocument();
			if (document.containsReadOnly(minStart, maxEnd)) {
				Iterator nonDefaultStyleRangeIterator = textPresentation.getNonDefaultStyleRangeIterator();
				while (nonDefaultStyleRangeIterator.hasNext()) {
					StyleRange styleRange = (StyleRange) nonDefaultStyleRangeIterator.next();
					if (document.containsReadOnly(styleRange.start, styleRange.length)) {
						adjustForeground(styleRange);
					}
				}
			}
		}
	}

	/*
	 * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
	 */
	public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
		setCanceled(true);
		releaseDocument(oldInput);
		resetState();
	}

	/*
	 * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
	 */
	public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
		manageDocument(newInput);
	}

	/*
	 * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
	 */
	public void documentAboutToBeChanged(DocumentEvent event) {
		setCanceled(true);
	}

	/*
	 * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
	 */
	public void documentChanged(DocumentEvent event) {
	}

	/**
	 * @return Returns <code>true</code> iff the current reconcile is canceled.
	 * <p>
	 * NOTE: Also called from background thread.
	 * </p>
	 */
	public boolean isCanceled() {
		IDocument document= fSourceViewer != null ? fSourceViewer.getDocument() : null;
		if (document == null)
			return fIsCanceled;

		synchronized (getLockObject(document)) {
			return fIsCanceled;
		}
	}

	/**
	 * Set whether or not the current reconcile is canceled.
	 *
	 * @param isCanceled <code>true</code> iff the current reconcile is canceled
	 */
	public void setCanceled(boolean isCanceled) {
		IDocument document= fSourceViewer != null ? fSourceViewer.getDocument() : null;
		if (document == null) {
			fIsCanceled= isCanceled;
			return;
		}

		synchronized (getLockObject(document)) {
			fIsCanceled= isCanceled;
		}
	}

	/**
	 * @param document the document
	 * @return the document's lock object
	 */
	private Object getLockObject(IDocument document) {
		if (document instanceof ISynchronizable) {
			Object lock= ((ISynchronizable)document).getLockObject();
			if (lock != null)
				return lock;
		}
		return document;
	}

	/**
	 * Install this presenter on the given source viewer and background presentation
	 * reconciler.
	 *
	 * @param sourceViewer the source viewer
	 * @param backgroundPresentationReconciler the background presentation reconciler,
	 * 	can be <code>null</code>, in that case {@link SemanticHighlightingPresenter#createPresentation(List, List)}
	 * 	should not be called
	 */
	public void install(StructuredTextViewer sourceViewer, StructuredPresentationReconciler backgroundPresentationReconciler) {
		fSourceViewer= sourceViewer;
		fPresentationReconciler= backgroundPresentationReconciler;

		fSourceViewer.prependTextPresentationListener(this);
		fSourceViewer.addTextInputListener(this);
		manageDocument(fSourceViewer.getDocument());
	}

	/**
	 * Uninstall this presenter.
	 */
	public void uninstall() {
		setCanceled(true);

		if (fSourceViewer != null) {
			fSourceViewer.removeTextPresentationListener(this);
			releaseDocument(fSourceViewer.getDocument());
			invalidateTextPresentation();
			resetState();

			fSourceViewer.removeTextInputListener(this);
			fSourceViewer= null;
		}
	}

	/**
	 * Invalidate text presentation of positions with the given highlighting.
	 *
	 * @param highlighting The highlighting
	 */
	public void highlightingStyleChanged(HighlightingStyle highlighting) {
		for (int i= 0, n= fPositions.size(); i < n; i++) {
			HighlightedPosition position= (HighlightedPosition) fPositions.get(i);
			if (position.getHighlighting() == highlighting)
				fSourceViewer.invalidateTextPresentation(position.getOffset(), position.getLength());
		}
	}

	/**
	 * Invalidate text presentation of all positions.
	 */
	private void invalidateTextPresentation() {
		for (int i= 0, n= fPositions.size(); i < n; i++) {
			Position position= (Position) fPositions.get(i);
			fSourceViewer.invalidateTextPresentation(position.getOffset(), position.getLength());
		}
	}

	/**
	 * Add a position with the given range and highlighting unconditionally, only from UI thread.
	 * The position will also be registered on the document. The text presentation is not invalidated.
	 *
	 * @param uiPosition the highlighted position to add from the UI
	 */
	private void addPositionFromUI(HighlightedPosition uiPosition) {
		Position position= createHighlightedPosition(uiPosition, uiPosition.getHighlighting(), uiPosition.isReadOnly());
		synchronized (fPositionLock) {
			insertPosition(position);
		}

		IDocument document= fSourceViewer.getDocument();
		if (document == null)
			return;
		String positionCategory= getPositionCategory();
		try {
			document.addPosition(positionCategory, position);
		} catch (BadLocationException e) {
			// Should not happen
			Logger.logException(e);
		} catch (BadPositionCategoryException e) {
			// Should not happen
			Logger.logException(e);
		}
	}

	/**
	 * Reset to initial state.
	 */
	private void resetState() {
		synchronized (fPositionLock) {
			fPositions.clear();
		}
	}

	/**
	 * Start managing the given document.
	 *
	 * @param document The document
	 */
	private void manageDocument(IDocument document) {
		if (document != null) {
			document.addPositionCategory(getPositionCategory());
			document.addPositionUpdater(fPositionUpdater);
			document.addDocumentListener(this);
		}
	}

	/**
	 * Stop managing the given document.
	 *
	 * @param document The document
	 */
	private void releaseDocument(IDocument document) {
		if (document != null) {
			document.removeDocumentListener(this);
			document.removePositionUpdater(fPositionUpdater);
			try {
				document.removePositionCategory(getPositionCategory());
			} catch (BadPositionCategoryException e) {
				// Should not happen
				Logger.logException(e);
			}
		}
	}

	/**
	 * @return The semantic reconciler position's category.
	 */
	private String getPositionCategory() {
		return toString();
	}
	
	private void adjustForeground(StyleRange styleRange) {
		RGB oldRGB = null;
		// Color oldColor = styleRange.foreground;
		Color oldColor = styleRange.background;
		if (oldColor == null) {
			// oldRGB = getTextWidget().getForeground().getRGB();
			oldColor = fSourceViewer.getTextWidget().getBackground();
			oldRGB = oldColor.getRGB();
		}
		else {
			oldRGB = oldColor.getRGB();
		}
		Color newColor = getCachedColorFor(oldRGB);
		if (newColor == null) {
			// make text "closer to" background lumanence
			double target = getRGBConverter().calculateYComponent(oldColor);
			RGB newRGB = getRGBConverter().transformRGBToGrey(oldRGB, readOnlyForegroundScaleFactor / 100.0, target);

			// save conversion, so calculations only need to be done once
			cacheColor(oldRGB, newRGB);
			newColor = getCachedColorFor(oldRGB);
		}
		styleRange.foreground = newColor;
	}

	private YUV_RGBConverter getRGBConverter() {
		if (rgbConverter == null) {
			rgbConverter = new YUV_RGBConverter();
		}
		return rgbConverter;
	}

	/**
	 * Cache read-only color.
	 * 
	 * @param oldRGB
	 * @param newColor
	 */
	private void cacheColor(RGB oldRGB, RGB newColor) {
		if (readOnlyColorTable == null) {
			readOnlyColorTable = new HashMap();
		}
		readOnlyColorTable.put(oldRGB, newColor);
	}

	/**
	 * This method is just to get existing read-only colors.
	 */
	private Color getCachedColorFor(RGB oldRGB) {
		Color result = null;
	
		if (readOnlyColorTable != null) {
			RGB readOnlyRGB = (RGB) readOnlyColorTable.get(oldRGB);
			result = EditorUtility.getColor(readOnlyRGB);
		}
	
		return result;
	}
	
	/**
	 * A utility class to do various color manipulations
	 */
	private class YUV_RGBConverter {
		/**
		 * This class "holds" the YUV values corresponding to RGB color
		 */
		private class YUV {

			class NormalizedRGB {
				double blue;
				double green;
				private final double maxRGB = 256.0;
				double red;

				public NormalizedRGB(RGB rgb) {
					// first normalize to between 0 - 1
					red = rgb.red / maxRGB;
					green = rgb.green / maxRGB;
					blue = rgb.blue / maxRGB;

					red = gammaNormalized(red);
					green = gammaNormalized(green);
					blue = gammaNormalized(blue);

				}
			}

			private NormalizedRGB normalizedRGB;

			private double u = -1;
			private double v = -1;
			private double y = -1;

			private YUV() {
				super();
			}

			public YUV(RGB rgb) {
				this();
				normalizedRGB = new NormalizedRGB(rgb);
				// force calculations
				getY();
				getV();
				getU();
			}

			/**
			 * normalize to "average" gamma 2.2222 or 1/0.45
			 */
			double gammaNormalized(double colorComponent) {
				if (colorComponent < 0.018) {
					return colorComponent * 0.45;
				}
				else {
					return 1.099 * Math.pow(colorComponent, 0.45) - 0.099;
				}
			}

			/**
			 * @return RGB based on original RGB and current YUV values;
			 */

			public double getU() {
				if (u == -1) {
					u = 0.4949 * (normalizedRGB.blue - getY());
				}
				return u;

			}

			public double getV() {
				if (v == -1) {
					v = 0.877 * (normalizedRGB.red - getY());
				}
				return v;
			}

			public double getY() {
				if (y == -1) {
					y = 0.299 * normalizedRGB.red + 0.587 * normalizedRGB.green + 0.114 * normalizedRGB.blue;
				}
				return y;
			}

		}

		public YUV_RGBConverter() {
			super();
		}

		public double calculateYComponent(Color targetColor) {
			return new YUV(targetColor.getRGB()).getY();
		}

		public RGB transformRGBToGrey(RGB originalRGB, double scaleFactor, double target) {
			RGB transformedRGB = null;
			// we left the "full" API method signature, but this
			// version does not take into account originalRGB, though
			// it might someday.
			// for now, we'll simply make the new RGB grey, either a little
			// lighter, or a little darker than background.
			double y = 0;
			double mid = 0.5;
			// zero is black, one is white
			if (target < mid) {
				// is "dark" make lighter
				y = target + scaleFactor;
			}
			else {
				// is "light" make darker
				y = target - scaleFactor;
			}
			int c = (int) Math.round(y * 255);
			// just to gaurd against mis-use, or scale's values greater
			// than mid point (and possibly rounding error)
			if (c > 255)
				c = 255;
			if (c < 0)
				c = 0;
			transformedRGB = new RGB(c, c, c);
			return transformedRGB;
		}
	}
}
