/*******************************************************************************
 * Copyright (c) 2006, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jface.internal.text.revisions;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Platform;

import org.eclipse.jface.internal.text.html.BrowserInformationControl;
import org.eclipse.jface.internal.text.html.HTMLPrinter;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.JFacePreferences;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;

import org.eclipse.jface.text.AbstractReusableInformationControlCreator;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.JFaceTextUtil;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.information.IInformationProviderExtension2;
import org.eclipse.jface.text.revisions.IRevisionListener;
import org.eclipse.jface.text.revisions.IRevisionRulerColumnExtension;
import org.eclipse.jface.text.revisions.IRevisionRulerColumnExtension.RenderingMode;
import org.eclipse.jface.text.revisions.Revision;
import org.eclipse.jface.text.revisions.RevisionEvent;
import org.eclipse.jface.text.revisions.RevisionInformation;
import org.eclipse.jface.text.revisions.RevisionRange;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.CompositeRuler;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.IAnnotationHoverExtension;
import org.eclipse.jface.text.source.IAnnotationHoverExtension2;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IAnnotationModelExtension;
import org.eclipse.jface.text.source.IAnnotationModelListener;
import org.eclipse.jface.text.source.IChangeRulerColumn;
import org.eclipse.jface.text.source.ILineDiffer;
import org.eclipse.jface.text.source.ILineRange;
import org.eclipse.jface.text.source.ISharedTextColors;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRulerColumn;
import org.eclipse.jface.text.source.LineRange;


/**
 * A strategy for painting the live annotate colors onto the vertical ruler column. It also manages
 * the revision hover.
 *
 * @since 3.2
 */
public final class RevisionPainter {
	/** Tells whether this class is in debug mode. */
	private static boolean DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jface.text.source/debug/RevisionRulerColumn")); //$NON-NLS-1$//$NON-NLS-2$

	// RGBs provided by UI Designer
	private static final RGB BY_DATE_START_COLOR= new RGB(199, 134, 57);
	private static final RGB BY_DATE_END_COLOR= new RGB(241, 225, 206);


	/**
	 * The annotations created to show a revision in the overview ruler.
	 */
	private static final class RevisionAnnotation extends Annotation {
		public RevisionAnnotation(String text) {
			super("org.eclipse.ui.workbench.texteditor.revisionAnnotation", false, text); //$NON-NLS-1$
		}
	}

	/**
	 * The color tool manages revision colors and computes shaded colors based on the relative age
	 * and author of a revision.
	 */
	private final class ColorTool {
		/**
		 * The average perceived intensity of a base color. 0 means black, 1 means white. A base
		 * revision color perceived as light such as yellow will be darkened, while colors perceived
		 * as dark such as blue will be lightened up.
		 */
		private static final float AVERAGE_INTENSITY= 0.5f;
		/**
		 * The maximum shading in [0, 1] - this is the shade that the most recent revision will
		 * receive.
		 */
		private static final float MAX_SHADING= 0.7f;
		/**
		 * The minimum shading in [0, 1] - this is the shade that the oldest revision will receive.
		 */
		private static final float MIN_SHADING= 0.2f;
		/**
		 * The shade for the focus boxes.
		 */
		private static final float FOCUS_COLOR_SHADING= 1f;


		/**
		 * A list of {@link Long}, storing the age of each revision in a sorted list.
		 */
		private List<Long> fRevisions;
		/**
		 * The stored shaded colors.
		 */
		private final Map<Revision, RGB> fColors= new HashMap<>();
		/**
		 * The stored focus colors.
		 */
		private final Map<Revision, RGB> fFocusColors= new HashMap<>();

		/** Cached gradient start and stop values. */
		private RGB fGradientStart;

		private RGB fGradientStop;

		/**
		 * Sets the revision information, which is needed to compute the relative age of a revision.
		 *
		 * @param info the new revision info, <code>null</code> for none.
		 */
		public void setInfo(RevisionInformation info) {
			fRevisions= null;
			fColors.clear();
			fFocusColors.clear();
			fGradientStart= null;
			fGradientStop= null;
			if (info == null)
				return;
			List<Long> revisions= new ArrayList<>();
			for (Revision revision : info.getRevisions()) {
				revisions.add(Long.valueOf(computeAge(revision)));
			}
			Collections.sort(revisions);
			fRevisions= revisions;
		}

		private RGB getRGB(String key, RGB defaultValue) {
			RGB rgb= JFaceResources.getColorRegistry().getRGB(key);
			return rgb != null ? rgb : defaultValue;
		}

		private RGB adaptColor(Revision revision, boolean focus) {
			RGB rgb;
			float scale;
			if (fRenderingMode == IRevisionRulerColumnExtension.AGE) {
				int index= computeAgeIndex(revision);
				if (index == -1 || fRevisions.isEmpty()) {
					rgb= getBackground().getRGB();
				} else {
					if (fGradientStart == null) {
						fGradientStart= getRGB(JFacePreferences.REVISION_NEWEST_COLOR, BY_DATE_START_COLOR);
					}
					if (fGradientStop == null) {
						fGradientStop= getRGB(JFacePreferences.REVISION_OLDEST_COLOR, BY_DATE_END_COLOR);
					}
					// gradient from most recent to oldest
					RGB[] gradient= Colors.palette(fGradientStart, fGradientStop, fRevisions.size());
					rgb= gradient[gradient.length - index - 1];
				}
				scale= 0.99f;
			} else if (fRenderingMode == IRevisionRulerColumnExtension.AUTHOR) {
				rgb= revision.getColor();
				rgb= Colors.adjustBrightness(rgb, AVERAGE_INTENSITY);
				scale= 0.6f;
			} else if (fRenderingMode == IRevisionRulerColumnExtension.AUTHOR_SHADED_BY_AGE) {
				rgb= revision.getColor();
				rgb= Colors.adjustBrightness(rgb, AVERAGE_INTENSITY);
				int index= computeAgeIndex(revision);
				int size= fRevisions.size();
				// relative age: newest is 0, oldest is 1
				// if there is only one revision, use an intermediate value to avoid extreme coloring
				if (index == -1 || size < 2)
					scale= 0.5f;
				else
					scale= (float) index / (size - 1);
			} else {
				Assert.isTrue(false);
				return null; // dummy
			}
			rgb= getShadedColor(rgb, scale, focus);
			return rgb;
		}

		private int computeAgeIndex(Revision revision) {
			long age= computeAge(revision);
			int index= fRevisions.indexOf(Long.valueOf(age));
			return index;
		}

		private RGB getShadedColor(RGB color, float scale, boolean focus) {
			Assert.isLegal(scale >= 0.0);
			Assert.isLegal(scale <= 1.0);
			RGB background= getBackground().getRGB();

			// normalize to lie within [MIN_SHADING, MAX_SHADING]
			// use more intense colors if the ruler is narrow (i.e. not showing line numbers)
			boolean makeIntense= getWidth() <= 15;
			float intensityShift= makeIntense ? 0.3f : 0f;
			float max= MAX_SHADING + intensityShift;
			float min= MIN_SHADING + intensityShift;
			scale= (max - min) * scale + min;

			// focus coloring
			if (focus) {
				scale += FOCUS_COLOR_SHADING;
				if (scale > 1) {
					background= new RGB(255 - background.red, 255 - background.green, 255 - background.blue);
					scale= 2 - scale;
				}
			}

			return Colors.blend(background, color, scale);
		}

		private long computeAge(Revision revision) {
			return revision.getDate().getTime();
		}

		/**
		 * Returns the color for a revision based on relative age and author.
		 *
		 * @param revision the revision
		 * @param focus <code>true</code> to return the focus color
		 * @return the color for a revision
		 */
		public RGB getColor(Revision revision, boolean focus) {
			Map<Revision, RGB> map= focus ? fFocusColors : fColors;
			RGB color= map.get(revision);
			if (color != null)
				return color;

			color= adaptColor(revision, focus);
			map.put(revision, color);
			return color;
		}
	}

	/**
	 * Handles all the mouse interaction in this line number ruler column.
	 */
	private class MouseHandler implements MouseMoveListener, MouseTrackListener, Listener {

		private RevisionRange fMouseDownRegion;

		private void handleMouseUp(Event e) {
			if (e.button == 1) {
				RevisionRange upRegion= fFocusRange;
				RevisionRange downRegion= fMouseDownRegion;
				fMouseDownRegion= null;

				if (upRegion == downRegion) {
					Revision revision= upRegion == null ? null : upRegion.getRevision();
					if (revision == fSelectedRevision)
						revision= null; // deselect already selected revision
					handleRevisionSelected(revision);
				}
			}
		}

		private void handleMouseDown(Event e) {
			if (e.button == 3)
				updateFocusRevision(null); // kill any focus as the ctx menu is going to show
			if (e.button == 1) {
				fMouseDownRegion= fFocusRange;
				postRedraw();
			}
		}

		@Override
		public void handleEvent(Event event) {
			switch (event.type) {
				case SWT.MouseVerticalWheel:
					handleMouseWheel(event);
					break;
				case SWT.MouseDown:
					handleMouseDown(event);
					break;
				case SWT.MouseUp:
					handleMouseUp(event);
					break;
				default:
					Assert.isLegal(false);
			}
		}

		@Override
		public void mouseEnter(MouseEvent e) {
			updateFocusLine(toDocumentLineNumber(e.y));
		}

		@Override
		public void mouseExit(MouseEvent e) {
			updateFocusLine(-1);
		}

		@Override
		public void mouseHover(MouseEvent e) {
		}

		@Override
		public void mouseMove(MouseEvent e) {
			updateFocusLine(toDocumentLineNumber(e.y));
		}
	}

	/**
	 * Internal listener class that will update the ruler when the underlying model changes.
	 */
	private class AnnotationListener implements IAnnotationModelListener {
		@Override
		public void modelChanged(IAnnotationModel model) {
			clearRangeCache();
			postRedraw();
		}

	}

	/**
	 * The information control creator.
	 */
	private static final class HoverInformationControlCreator extends AbstractReusableInformationControlCreator {
		private boolean fIsFocusable;

		public HoverInformationControlCreator(boolean isFocusable) {
			fIsFocusable= isFocusable;
		}

		@Override
		protected IInformationControl doCreateInformationControl(Shell parent) {
			if (BrowserInformationControl.isAvailable(parent)) {
				return new BrowserInformationControl(parent, JFaceResources.DIALOG_FONT, fIsFocusable) {
					/**
					 * {@inheritDoc}
					 *
					 * @deprecated use {@link #setInput(Object)}
					 */
					@Deprecated
					@Override
					public void setInformation(String content) {
						content= addCSSToHTMLFragment(content);
						super.setInformation(content);
					}

					/**
					 * Adds a HTML header and CSS info if <code>html</code> is only an HTML fragment (has no
					 * &lt;html&gt; section).
					 *
					 * @param html the html / text produced by a revision
					 * @return modified html
					 */
					private String addCSSToHTMLFragment(String html) {
						int max= Math.min(100, html.length());
						if (html.substring(0, max).contains("<html>")) //$NON-NLS-1$
							// there is already a header
							return html;

						StringBuilder info= new StringBuilder(512 + html.length());
						HTMLPrinter.insertPageProlog(info, 0, fgStyleSheet);
						info.append(html);
						HTMLPrinter.addPageEpilog(info);
						return info.toString();
					}

				};
			}
			return new DefaultInformationControl(parent, fIsFocusable);
		}

		@Override
		public boolean canReplace(IInformationControlCreator creator) {
			return creator.getClass() == getClass()
					&& ((HoverInformationControlCreator) creator).fIsFocusable == fIsFocusable;
		}
	}

	private static final String fgStyleSheet= "/* Font definitions */\n" + //$NON-NLS-1$
		"body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt {font-family: sans-serif; font-size: 9pt }\n" + //$NON-NLS-1$
		"pre				{ font-family: monospace; font-size: 9pt }\n" + //$NON-NLS-1$
		"\n" + //$NON-NLS-1$
		"/* Margins */\n" + //$NON-NLS-1$
		"body	     { overflow: auto; margin-top: 0; margin-bottom: 4; margin-left: 3; margin-right: 0 }\n" + //$NON-NLS-1$
		"h1           { margin-top: 5; margin-bottom: 1 }	\n" + //$NON-NLS-1$
		"h2           { margin-top: 25; margin-bottom: 3 }\n" + //$NON-NLS-1$
		"h3           { margin-top: 20; margin-bottom: 3 }\n" + //$NON-NLS-1$
		"h4           { margin-top: 20; margin-bottom: 3 }\n" + //$NON-NLS-1$
		"h5           { margin-top: 0; margin-bottom: 0 }\n" + //$NON-NLS-1$
		"p            { margin-top: 10px; margin-bottom: 10px }\n" + //$NON-NLS-1$
		"pre	         { margin-left: 6 }\n" + //$NON-NLS-1$
		"ul	         { margin-top: 0; margin-bottom: 10 }\n" + //$NON-NLS-1$
		"li	         { margin-top: 0; margin-bottom: 0 } \n" + //$NON-NLS-1$
		"li p	     { margin-top: 0; margin-bottom: 0 } \n" + //$NON-NLS-1$
		"ol	         { margin-top: 0; margin-bottom: 10 }\n" + //$NON-NLS-1$
		"dl	         { margin-top: 0; margin-bottom: 10 }\n" + //$NON-NLS-1$
		"dt	         { margin-top: 0; margin-bottom: 0; font-weight: bold }\n" + //$NON-NLS-1$
		"dd	         { margin-top: 0; margin-bottom: 0 }\n" + //$NON-NLS-1$
		"\n" + //$NON-NLS-1$
		"/* Styles and colors */\n" + //$NON-NLS-1$
		"a:link	     { color: hyperlinkColor }\n" + //$NON-NLS-1$
		"a:hover	     { color: activeHyperlinkColor; }\n" + //$NON-NLS-1$
		"a:visited    { text-decoration: underline }\n" + //$NON-NLS-1$
		"h4           { font-style: italic }\n" + //$NON-NLS-1$
		"strong	     { font-weight: bold }\n" + //$NON-NLS-1$
		"em	         { font-style: italic }\n" + //$NON-NLS-1$
		"var	         { font-style: italic }\n" + //$NON-NLS-1$
		"th	         { font-weight: bold }\n" + //$NON-NLS-1$
		""; //$NON-NLS-1$

	/**
	 * The revision hover displays information about the currently selected revision.
	 */
	private final class RevisionHover implements IAnnotationHover, IAnnotationHoverExtension, IAnnotationHoverExtension2, IInformationProviderExtension2 {

		@Override
		public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
			Object info= getHoverInfo(sourceViewer, getHoverLineRange(sourceViewer, lineNumber), 0);
			return info == null ? null : info.toString();
		}

		@Override
		public IInformationControlCreator getHoverControlCreator() {
			RevisionInformation revisionInfo= fRevisionInfo;
			if (revisionInfo != null) {
				IInformationControlCreator creator= revisionInfo.getHoverControlCreator();
				if (creator != null)
					return creator;
			}
			return new HoverInformationControlCreator(false);
		}

		@Override
		public boolean canHandleMouseCursor() {
			return false;
		}

		@Override
		public boolean canHandleMouseWheel() {
			return true;
		}

		@Override
		public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleNumberOfLines) {
			RevisionRange range= getRange(lineRange.getStartLine());
			Object info= range == null ? null : range.getRevision().getHoverInfo();
			return info;
		}

		@Override
		public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) {
			RevisionRange range= getRange(lineNumber);
			return range == null ? null : new LineRange(lineNumber, 1);
		}

		@Override
		public IInformationControlCreator getInformationPresenterControlCreator() {
			RevisionInformation revisionInfo= fRevisionInfo;
			if (revisionInfo != null) {
				IInformationControlCreator creator= revisionInfo.getInformationPresenterControlCreator();
				if (creator != null)
					return creator;
			}
			return new HoverInformationControlCreator(true);
		}
	}

	/* Listeners and helpers. */

	/** The shared color provider. */
	private final ISharedTextColors fSharedColors;
	/** The color tool. */
	private final ColorTool fColorTool= new ColorTool();
	/** The mouse handler. */
	private final MouseHandler fMouseHandler= new MouseHandler();
	/** The hover. */
	private final RevisionHover fHover= new RevisionHover();
	/** The annotation listener. */
	private final AnnotationListener fAnnotationListener= new AnnotationListener();
	/** The selection provider. */
	private final RevisionSelectionProvider fRevisionSelectionProvider= new RevisionSelectionProvider(this);
	/**
	 * The list of revision listeners.
	 * @since 3.3.
	 */
	private final ListenerList<IRevisionListener> fRevisionListeners= new ListenerList<>(ListenerList.IDENTITY);

	/* The context - column and viewer we are connected to. */

	/** The vertical ruler column that delegates painting to this painter. */
	private final IVerticalRulerColumn fColumn;
	/** The parent ruler. */
	private CompositeRuler fParentRuler;
	/** The column's control, typically a {@link Canvas}, possibly <code>null</code>. */
	private Control fControl;
	/** The text viewer that the column is attached to. */
	private ITextViewer fViewer;
	/** The viewer's text widget. */
	private StyledText fWidget;

	/* The models we operate on. */

	/** The revision model object. */
	private RevisionInformation fRevisionInfo;
	/** The line differ. */
	private ILineDiffer fLineDiffer= null;
	/** The annotation model. */
	private IAnnotationModel fAnnotationModel= null;
	/** The background color, possibly <code>null</code>. */
	private Color fBackground;

	/* Cache. */

	/** The cached list of ranges adapted to quick diff. */
	private List<RevisionRange> fRevisionRanges= null;
	/** The annotations created for the overview ruler temporary display. */
	private List<Annotation> fAnnotations= new ArrayList<>();

	/* State */

	/** The current focus line, -1 for none. */
	private int fFocusLine= -1;
	/** The current focus region, <code>null</code> if none. */
	private RevisionRange fFocusRange= null;
	/** The current focus revision, <code>null</code> if none. */
	private Revision fFocusRevision= null;
	/**
	 * The currently selected revision, <code>null</code> if none. The difference between
	 * {@link #fFocusRevision} and {@link #fSelectedRevision} may not be obvious: the focus revision
	 * is the one focused by the mouse (by hovering over a block of the revision), while the
	 * selected revision is sticky, i.e. is not removed when the mouse leaves the ruler.
	 *
	 * @since 3.3
	 */
	private Revision fSelectedRevision= null;
	/** <code>true</code> if the mouse wheel handler is installed, <code>false</code> otherwise. */
	private boolean fWheelHandlerInstalled= false;
	/**
	 * The revision rendering mode.
	 */
	private RenderingMode fRenderingMode= IRevisionRulerColumnExtension.AUTHOR_SHADED_BY_AGE;
	/**
	 * The required with in characters.
	 * @since 3.3
	 */
	private int fRequiredWidth= -1;
	/**
	 * The width of the revision field in chars to compute {@link #fAuthorInset} from.
	 * @since 3.3
	 */
	private int fRevisionIdChars= 0;
	/**
	 * <code>true</code> to show revision ids, <code>false</code> otherwise.
	 * @since 3.3
	 */
	private boolean fShowRevision= false;
	/**
	 * <code>true</code> to show the author, <code>false</code> otherwise.
	 * @since 3.3
	 */
	private boolean fShowAuthor= false;
	/**
	 * The author inset in pixels for when author *and* revision id are shown.
	 * @since 3.3
	 */
	private int fAuthorInset;
	/**
	 * The remembered ruler width (as changing the ruler width triggers recomputation of the colors.
	 * @since 3.3
	 */
	private int fLastWidth= -1;

	/** The JFace preference store, or {@code null} if there is none. */
	private IPreferenceStore fPreferences;

	/** Listens on {@link #fPreferences} to update the ruler when colors change. */
	private final IPropertyChangeListener fColorListener= event -> {
		String property= event.getProperty();
		if (property == null) {
			return;
		}
		switch (property) {
			case JFacePreferences.REVISION_NEWEST_COLOR:
			case JFacePreferences.REVISION_OLDEST_COLOR:
				fLastWidth= -1; // Recalculate colors
				postRedraw();
				break;
			default:
				break;
		}
	};

	/**
	 * Creates a new revision painter for a vertical ruler column.
	 *
	 * @param column the column that will delegate{@link #paint(GC, ILineRange) painting} to the
	 *        newly created painter.
	 * @param sharedColors a shared colors object to store shaded colors in
	 */
	public RevisionPainter(IVerticalRulerColumn column, ISharedTextColors sharedColors) {
		Assert.isLegal(column != null);
		Assert.isLegal(sharedColors != null);
		fColumn= column;
		fSharedColors= sharedColors;
	}

	/**
	 * Sets the revision information to be drawn and triggers a redraw.
	 *
	 * @param info the revision information to show, <code>null</code> to draw none
	 */
	public void setRevisionInformation(RevisionInformation info) {
		if (fRevisionInfo != info) {
			fRequiredWidth= -1;
			fRevisionIdChars= 0;
			fRevisionInfo= info;
			clearRangeCache();
			updateFocusRange(null);
			handleRevisionSelected((Revision) null);
			fColorTool.setInfo(info);
			postRedraw();
			informListeners();
		}
	}

	/**
	 * Changes the rendering mode and triggers redrawing if needed.
	 *
	 * @param renderingMode the rendering mode
	 * @since 3.3
	 */
	public void setRenderingMode(RenderingMode renderingMode) {
		Assert.isLegal(renderingMode != null);
		if (fRenderingMode != renderingMode) {
			fRenderingMode= renderingMode;
			fColorTool.setInfo(fRevisionInfo);
			postRedraw();
		}
	}

	/**
	 * Sets the background color.
	 *
	 * @param background the background color, <code>null</code> for the platform's list
	 *        background
	 */
	public void setBackground(Color background) {
		fBackground= background;
	}

	/**
	 * Sets the parent ruler - the delegating column must call this method as soon as it creates its
	 * control.
	 *
	 * @param parentRuler the parent ruler
	 */
	public void setParentRuler(CompositeRuler parentRuler) {
		fParentRuler= parentRuler;
		if (parentRuler != null) {
			fPreferences= JFacePreferences.getPreferenceStore();
			if (fPreferences != null) {
				fPreferences.addPropertyChangeListener(fColorListener);
			}
		} else if (fPreferences != null) {
			fPreferences.removePropertyChangeListener(fColorListener);
			fPreferences= null;
		}
	}

	/**
	 * Delegates the painting of the quick diff colors to this painter. The painter will draw the
	 * color boxes onto the passed {@link GC} for all model (document) lines in
	 * <code>visibleModelLines</code>.
	 *
	 * @param gc the {@link GC} to draw onto
	 * @param visibleLines the lines (in document offsets) that are currently (perhaps only
	 *        partially) visible
	 */
	public void paint(GC gc, ILineRange visibleLines) {
		connectIfNeeded();
		if (!isConnected())
			return;

		// compute the horizontal indent of the author for the case that we show revision
		// and author
		if (fShowAuthor && fShowRevision) {
			char[] string= new char[fRevisionIdChars + 1];
			Arrays.fill(string, '9');
			if (string.length > 1) {
				string[0]= '.';
				string[1]= ' ';
			}
			fAuthorInset= gc.stringExtent(new String(string)).x;
		}

		// recompute colors (show intense colors if ruler is narrow)
		int width= getWidth();
		if (width != fLastWidth) {
			fColorTool.setInfo(fRevisionInfo);
			fLastWidth= width;
		}

		// draw change regions
		List<RevisionRange> ranges= getRanges(visibleLines);
		for (RevisionRange region : ranges) {
			paintRange(region, gc);
		}
	}

	/**
	 * Ensures that the column is fully instantiated, i.e. has a control, and that the viewer is
	 * visible.
	 */
	private void connectIfNeeded() {
		if (isConnected() || fParentRuler == null)
			return;

		fViewer= fParentRuler.getTextViewer();
		if (fViewer == null)
			return;

		fWidget= fViewer.getTextWidget();
		if (fWidget == null)
			return;

		fControl= fColumn.getControl();
		if (fControl == null)
			return;

		fControl.addMouseTrackListener(fMouseHandler);
		fControl.addMouseMoveListener(fMouseHandler);
		fControl.addListener(SWT.MouseUp, fMouseHandler);
		fControl.addListener(SWT.MouseDown, fMouseHandler);
		fControl.addDisposeListener(e -> handleDispose());

		fRevisionSelectionProvider.install(fViewer);
	}

	/**
	 * Returns <code>true</code> if the column is fully connected.
	 *
	 * @return <code>true</code> if the column is fully connected, false otherwise
	 */
	private boolean isConnected() {
		return fControl != null;
	}

	/**
	 * Sets the annotation model.
	 *
	 * @param model the annotation model, possibly <code>null</code>
	 * @see IVerticalRulerColumn#setModel(IAnnotationModel)
	 */
	public void setModel(IAnnotationModel model) {
		IAnnotationModel diffModel;
		if (model instanceof IAnnotationModelExtension)
			diffModel= ((IAnnotationModelExtension) model).getAnnotationModel(IChangeRulerColumn.QUICK_DIFF_MODEL_ID);
		else
			diffModel= model;

		setDiffer(diffModel);
		setAnnotationModel(model);
	}

	/**
	 * Sets the annotation model.
	 *
	 * @param model the annotation model.
	 */
	private void setAnnotationModel(IAnnotationModel model) {
		if (fAnnotationModel != model)
			fAnnotationModel= model;
	}

	/**
	 * Sets the line differ.
	 *
	 * @param differ the line differ or <code>null</code> if none
	 */
	private void setDiffer(IAnnotationModel differ) {
		if (differ instanceof ILineDiffer || differ == null) {
			if (fLineDiffer != differ) {
				if (fLineDiffer != null)
					((IAnnotationModel) fLineDiffer).removeAnnotationModelListener(fAnnotationListener);
				fLineDiffer= (ILineDiffer) differ;
				if (fLineDiffer != null)
					((IAnnotationModel) fLineDiffer).addAnnotationModelListener(fAnnotationListener);
			}
		}
	}

	/**
	 * Disposes of the painter's resources.
	 */
	private void handleDispose() {
		updateFocusLine(-1);

		if (fLineDiffer != null) {
			((IAnnotationModel) fLineDiffer).removeAnnotationModelListener(fAnnotationListener);
			fLineDiffer= null;
		}

		fRevisionSelectionProvider.uninstall();
	}

	/**
	 * Paints a single change region onto <code>gc</code>.
	 *
	 * @param range the range to paint
	 * @param gc the {@link GC} to paint on
	 */
	private void paintRange(RevisionRange range, GC gc) {
		ILineRange widgetRange= modelLinesToWidgetLines(range);
		if (widgetRange == null)
			return;

		Revision revision= range.getRevision();
		boolean drawArmedFocus= range == fMouseHandler.fMouseDownRegion;
		boolean drawSelection= !drawArmedFocus && revision == fSelectedRevision;
		boolean drawFocus= !drawSelection && !drawArmedFocus && revision == fFocusRevision;
		Rectangle box= computeBoxBounds(widgetRange);

		gc.setBackground(lookupColor(revision, false));
		if (drawArmedFocus) {
			Color foreground= gc.getForeground();
			Color focusColor= lookupColor(revision, true);
			gc.setForeground(focusColor);
			gc.fillRectangle(box);
			gc.drawRectangle(box.x, box.y, box.width - 1, box.height - 1); // highlight box
			gc.drawRectangle(box.x + 1, box.y + 1, box.width - 3, box.height - 3); // inner highlight box
			gc.setForeground(foreground);
		} else if (drawFocus || drawSelection) {
			Color foreground= gc.getForeground();
			Color focusColor= lookupColor(revision, true);
			gc.setForeground(focusColor);
			gc.fillRectangle(box);
			gc.drawRectangle(box.x, box.y, box.width - 1, box.height - 1); // highlight box
			gc.setForeground(foreground);
		} else {
			gc.fillRectangle(box);
		}

		if ((fShowAuthor || fShowRevision)) {
			int indentation= 1;
			int baselineBias= getBaselineBias(gc, widgetRange.getStartLine());
			if (fShowAuthor && fShowRevision) {
				gc.drawString(revision.getId(), indentation, box.y + baselineBias, true);
				gc.drawString(revision.getAuthor(), fAuthorInset, box.y + baselineBias, true);
			} else if (fShowAuthor) {
				gc.drawString(revision.getAuthor(), indentation, box.y + baselineBias, true);
			} else if (fShowRevision) {
				gc.drawString(revision.getId(), indentation, box.y + baselineBias, true);
			}
		}
	}

	/**
	 * Returns the difference between the baseline of the widget and the
	 * baseline as specified by the font for <code>gc</code>. When drawing
	 * line numbers, the returned bias should be added to obtain text lined up
	 * on the correct base line of the text widget.
	 *
	 * @param gc the <code>GC</code> to get the font metrics from
	 * @param widgetLine the widget line
	 * @return the baseline bias to use when drawing text that is lined up with
	 *         <code>fCachedTextWidget</code>
	 * @since 3.3
	 */
	private int getBaselineBias(GC gc, int widgetLine) {
		if (widgetLine == fWidget.getLineCount())
			widgetLine--;

		/*
		 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=62951
		 * widget line height may be more than the font height used for the
		 * line numbers, since font styles (bold, italics...) can have larger
		 * font metrics than the simple font used for the numbers.
		 */
		int offset= fWidget.getOffsetAtLine(widgetLine);
		int widgetBaseline= fWidget.getBaseline(offset);

		FontMetrics fm = gc.getFontMetrics();
		int fontBaseline = fm.getAscent() + fm.getLeading();
		int baselineBias= widgetBaseline - fontBaseline;
		return Math.max(0, baselineBias);
	}

	/**
	 * Looks up the color for a certain revision.
	 *
	 * @param revision the revision to get the color for
	 * @param focus <code>true</code> if it is the focus revision
	 * @return the color for the revision
	 */
	private Color lookupColor(Revision revision, boolean focus) {
		return fSharedColors.getColor(fColorTool.getColor(revision, focus));
	}

	/**
	 * Returns the revision range that contains the given line, or
	 * <code>null</code> if there is none.
	 *
	 * @param line the line of interest
	 * @return the corresponding <code>RevisionRange</code> or <code>null</code>
	 */
	private RevisionRange getRange(int line) {
		List<RevisionRange> ranges= getRangeCache();

		if (ranges.isEmpty() || line == -1)
			return null;

		for (RevisionRange range : ranges) {
			if (contains(range, line))
				return range;
		}

		// line may be right after the last region
		RevisionRange lastRegion= ranges.get(ranges.size() - 1);
		if (line == end(lastRegion))
			return lastRegion;
		return null;
	}

	/**
	 * Returns the sublist of all <code>RevisionRange</code>s that intersect with the given lines.
	 *
	 * @param lines the model based lines of interest
	 * @return elementType: RevisionRange
	 */
	private List<RevisionRange> getRanges(ILineRange lines) {
		List<RevisionRange> ranges= getRangeCache();

		// return the interesting subset
		int end= end(lines);
		int first= -1, last= -1;
		for (int i= 0; i < ranges.size(); i++) {
			RevisionRange range= ranges.get(i);
			int rangeEnd= end(range);
			if (first == -1 && rangeEnd > lines.getStartLine())
				first= i;
			if (first != -1 && rangeEnd > end) {
				last= i;
				break;
			}
		}
		if (first == -1)
			return Collections.emptyList();
		if (last == -1)
			last= ranges.size() - 1; // bottom index may be one too much

		return ranges.subList(first, last + 1);
	}

	/**
	 * Gets all change ranges of the revisions in the revision model and adapts them to the current
	 * quick diff information. The list is cached.
	 *
	 * @return the list of all change regions, with diff information applied
	 */
	private synchronized List<RevisionRange> getRangeCache() {
		if (fRevisionRanges == null) {
			if (fRevisionInfo == null) {
				fRevisionRanges= Collections.emptyList();
			} else {
				Hunk[] hunks= HunkComputer.computeHunks(fLineDiffer, fViewer.getDocument().getNumberOfLines());
				fRevisionInfo.applyDiff(hunks);
				fRevisionRanges= fRevisionInfo.getRanges();
				updateOverviewAnnotations();
				informListeners();
			}
		}

		return fRevisionRanges;
	}

	/**
	 * Clears the range cache.
	 *
	 * @since 3.3
	 */
	private synchronized void clearRangeCache() {
		fRevisionRanges= null;
	}

	/**
	 * Returns <code>true</code> if <code>range</code> contains <code>line</code>. A line is
	 * not contained in a range if it is the range's exclusive end line.
	 *
	 * @param range the range to check whether it contains <code>line</code>
	 * @param line the line the line
	 * @return <code>true</code> if <code>range</code> contains <code>line</code>,
	 *         <code>false</code> if not
	 */
	private static boolean contains(ILineRange range, int line) {
		return range.getStartLine() <= line && end(range) > line;
	}

	/**
	 * Computes the end index of a line range.
	 *
	 * @param range a line range
	 * @return the last line (exclusive) of <code>range</code>
	 */
	private static int end(ILineRange range) {
		return range.getStartLine() + range.getNumberOfLines();
	}

	/**
	 * Returns the visible extent of a document line range in widget lines.
	 *
	 * @param range the document line range
	 * @return the visible extent of <code>range</code> in widget lines
	 */
	private ILineRange modelLinesToWidgetLines(ILineRange range) {
		int widgetStartLine= -1;
		int widgetEndLine= -1;
		if (fViewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension= (ITextViewerExtension5) fViewer;
			int modelEndLine= end(range);
			for (int modelLine= range.getStartLine(); modelLine < modelEndLine; modelLine++) {
				int widgetLine= extension.modelLine2WidgetLine(modelLine);
				if (widgetLine != -1) {
					if (widgetStartLine == -1)
						widgetStartLine= widgetLine;
					widgetEndLine= widgetLine;
				}
			}
		} else {
			IRegion region= fViewer.getVisibleRegion();
			IDocument document= fViewer.getDocument();
			try {
				int visibleStartLine= document.getLineOfOffset(region.getOffset());
				int visibleEndLine= document.getLineOfOffset(region.getOffset() + region.getLength());
				widgetStartLine= Math.max(0, range.getStartLine() - visibleStartLine);
				widgetEndLine= Math.min(visibleEndLine, end(range) - 1);
			} catch (BadLocationException x) {
				// ignore and return null
			}
		}
		if (widgetStartLine == -1 || widgetEndLine == -1)
			return null;
		return new LineRange(widgetStartLine, widgetEndLine - widgetStartLine + 1);
	}

	/**
	 * Returns the revision hover.
	 *
	 * @return the revision hover
	 */
	public IAnnotationHover getHover() {
		return fHover;
	}

	/**
	 * Computes and returns the bounds of the rectangle corresponding to a widget line range. The
	 * rectangle is in pixel coordinates relative to the text widget's
	 * {@link StyledText#getClientArea() client area} and has the width of the ruler.
	 *
	 * @param range the widget line range
	 * @return the box bounds corresponding to <code>range</code>
	 */
	private Rectangle computeBoxBounds(ILineRange range) {
		int y1= fWidget.getLinePixel(range.getStartLine());
		int y2= fWidget.getLinePixel(range.getStartLine() + range.getNumberOfLines());

		return new Rectangle(0, y1, getWidth(), y2 - y1 - 1);
	}

	/**
	 * Shows (or hides) the overview annotations.
	 */
	private void updateOverviewAnnotations() {
		if (fAnnotationModel == null)
			return;

		Revision revision= fFocusRevision != null ? fFocusRevision : fSelectedRevision;

		Map<Annotation, Position> added= null;
		if (revision != null) {
			added= new HashMap<>();
			for (RevisionRange range : revision.getRegions()) {
				try {
					IRegion charRegion= toCharRegion(range);
					Position position= new Position(charRegion.getOffset(), charRegion.getLength());
					Annotation annotation= new RevisionAnnotation(revision.getId());
					added.put(annotation, position);
				} catch (BadLocationException x) {
					// ignore - document was changed, show no annotations
				}
			}
		}

		if (fAnnotationModel instanceof IAnnotationModelExtension) {
			IAnnotationModelExtension ext= (IAnnotationModelExtension) fAnnotationModel;
			ext.replaceAnnotations(fAnnotations.toArray(new Annotation[fAnnotations.size()]), added);
		} else {
			for (Annotation annotation : fAnnotations) {
				fAnnotationModel.removeAnnotation(annotation);
			}
			if (added != null) {
				for (Entry<Annotation, Position> entry : added.entrySet()) {
					fAnnotationModel.addAnnotation(entry.getKey(), entry.getValue());
				}
			}
		}
		fAnnotations.clear();
		if (added != null)
			fAnnotations.addAll(added.keySet());

	}

	/**
	 * Returns the character offset based region of a line range.
	 *
	 * @param lines the line range to convert
	 * @return the character offset range corresponding to <code>range</code>
	 * @throws BadLocationException if the line range is not within the document bounds
	 */
	private IRegion toCharRegion(ILineRange lines) throws BadLocationException {
		IDocument document= fViewer.getDocument();
		int offset= document.getLineOffset(lines.getStartLine());
		int nextLine= end(lines);
		int endOffset;
		if (nextLine >= document.getNumberOfLines())
			endOffset= document.getLength();
		else
			endOffset= document.getLineOffset(nextLine);
		return new Region(offset, endOffset - offset);
	}

	/**
	 * Handles the selection of a revision and informs listeners.
	 *
	 * @param revision the selected revision, <code>null</code> for none
	 */
	void handleRevisionSelected(Revision revision) {
		fSelectedRevision= revision;
		fRevisionSelectionProvider.revisionSelected(revision);

		if (isConnected())
			updateOverviewAnnotations();

		postRedraw();
	}

	/**
	 * Handles the selection of a revision id and informs listeners
	 *
	 * @param id the selected revision id
	 */
	void handleRevisionSelected(String id) {
		Assert.isLegal(id != null);
		if (fRevisionInfo == null)
			return;

		for (Revision revision : fRevisionInfo.getRevisions()) {
			if (id.equals(revision.getId())) {
				handleRevisionSelected(revision);
				return;
			}
		}

		// clear selection if it does not exist
		handleRevisionSelected((Revision) null);
	}

	/**
	 * Returns the selection provider.
	 *
	 * @return the selection provider
	 */
	public RevisionSelectionProvider getRevisionSelectionProvider() {
		return fRevisionSelectionProvider;
	}

	/**
	 * Updates the focus line with a new line.
	 *
	 * @param line the new focus line, -1 for no focus
	 */
	private void updateFocusLine(int line) {
		if (fFocusLine != line)
			onFocusLineChanged(fFocusLine, line);
	}

	/**
	 * Handles a changing focus line.
	 *
	 * @param previousLine the old focus line (-1 for no focus)
	 * @param nextLine the new focus line (-1 for no focus)
	 */
	private void onFocusLineChanged(int previousLine, int nextLine) {
		if (DEBUG)
			System.out.println("line: " + previousLine + " > " + nextLine); //$NON-NLS-1$ //$NON-NLS-2$
		fFocusLine= nextLine;
		RevisionRange region= getRange(nextLine);
		updateFocusRange(region);
	}

	/**
	 * Updates the focus range.
	 *
	 * @param range the new focus range, <code>null</code> for no focus
	 */
	private void updateFocusRange(RevisionRange range) {
		if (range != fFocusRange)
			onFocusRangeChanged(fFocusRange, range);
	}

	/**
	 * Handles a changing focus range.
	 *
	 * @param previousRange the old focus range (<code>null</code> for no focus)
	 * @param nextRange the new focus range (<code>null</code> for no focus)
	 */
	private void onFocusRangeChanged(RevisionRange previousRange, RevisionRange nextRange) {
		if (DEBUG)
			System.out.println("range: " + previousRange + " > " + nextRange); //$NON-NLS-1$ //$NON-NLS-2$
		fFocusRange= nextRange;
		Revision revision= nextRange == null ? null : nextRange.getRevision();
		updateFocusRevision(revision);
	}

	private void updateFocusRevision(Revision revision) {
		if (fFocusRevision != revision)
			onFocusRevisionChanged(fFocusRevision, revision);
	}

	/**
	 * Handles a changing focus revision.
	 *
	 * @param previousRevision the old focus revision (<code>null</code> for no focus)
	 * @param nextRevision the new focus revision (<code>null</code> for no focus)
	 */
	private void onFocusRevisionChanged(Revision previousRevision, Revision nextRevision) {
		if (DEBUG)
			System.out.println("revision: " + previousRevision + " > " + nextRevision); //$NON-NLS-1$ //$NON-NLS-2$
		fFocusRevision= nextRevision;
		uninstallWheelHandler();
		installWheelHandler();
		updateOverviewAnnotations();
		redraw(); // pick up new highlights
	}

	/**
	 * Uninstalls the mouse wheel handler.
	 */
	private void uninstallWheelHandler() {
		fControl.removeListener(SWT.MouseVerticalWheel, fMouseHandler);
		fWheelHandlerInstalled= false;
	}

	/**
	 * Installs the mouse wheel handler.
	 */
	private void installWheelHandler() {
		if (fFocusRevision != null && !fWheelHandlerInstalled) {
			//FIXME: does not work on Windows, because Canvas cannot get focus and therefore does not send out mouse wheel events:
			//https://bugs.eclipse.org/bugs/show_bug.cgi?id=81189
			//see also https://bugs.eclipse.org/bugs/show_bug.cgi?id=75766
			fControl.addListener(SWT.MouseVerticalWheel, fMouseHandler);
			fWheelHandlerInstalled= true;
		}
	}

	/**
	 * @return <code>true</code> iff the mouse wheel handler is installed and others should avoid
	 *         handling mouse wheel events
	 * @since 3.10
	 */
	public boolean isWheelHandlerInstalled() {
		return fWheelHandlerInstalled;
	}

	/**
	 * Handles a mouse wheel event.
	 *
	 * @param event the mouse wheel event
	 */
	private void handleMouseWheel(Event event) {
		boolean up= event.count > 0;
		int documentHoverLine= fFocusLine;

		ILineRange nextWidgetRange= null;
		ILineRange last= null;
		List<RevisionRange> ranges= fFocusRevision.getRegions();
		if (up) {
			for (RevisionRange range : ranges) {
				ILineRange widgetRange= modelLinesToWidgetLines(range);
				if (contains(range, documentHoverLine)) {
					nextWidgetRange= last;
					break;
				}
				if (widgetRange != null)
					last= widgetRange;
			}
		} else {
			for (ListIterator<RevisionRange> it= ranges.listIterator(ranges.size()); it.hasPrevious();) {
				RevisionRange range= it.previous();
				ILineRange widgetRange= modelLinesToWidgetLines(range);
				if (contains(range, documentHoverLine)) {
					nextWidgetRange= last;
					break;
				}
				if (widgetRange != null)
					last= widgetRange;
			}
		}

		if (nextWidgetRange == null)
			return;

		int widgetCurrentFocusLine= modelLinesToWidgetLines(new LineRange(documentHoverLine, 1)).getStartLine();
		int widgetNextFocusLine= nextWidgetRange.getStartLine();
		int newTopPixel= fWidget.getTopPixel() + JFaceTextUtil.computeLineHeight(fWidget, widgetCurrentFocusLine, widgetNextFocusLine, widgetNextFocusLine - widgetCurrentFocusLine);
		fWidget.setTopPixel(newTopPixel);
		if (newTopPixel < 0) {
			Point cursorLocation= fWidget.getDisplay().getCursorLocation();
			cursorLocation.y+= newTopPixel;
			fWidget.getDisplay().setCursorLocation(cursorLocation);
		} else {
			int topPixel= fWidget.getTopPixel();
			if (topPixel < newTopPixel) {
				Point cursorLocation= fWidget.getDisplay().getCursorLocation();
				cursorLocation.y+= newTopPixel - topPixel;
				fWidget.getDisplay().setCursorLocation(cursorLocation);
			}
		}
		updateFocusLine(toDocumentLineNumber(fWidget.toControl(fWidget.getDisplay().getCursorLocation()).y));
		immediateUpdate();
	}

	/**
	 * Triggers a redraw in the display thread.
	 */
	private final void postRedraw() {
		if (isConnected() && !fControl.isDisposed()) {
			Display d= fControl.getDisplay();
			if (d != null) {
				d.asyncExec(() -> redraw());
			}
		}
	}

	/**
	 * Translates a y coordinate in the pixel coordinates of the column's control to a document line
	 * number.
	 *
	 * @param y the y coordinate
	 * @return the corresponding document line, -1 for no line
	 * @see CompositeRuler#toDocumentLineNumber(int)
	 */
	private int toDocumentLineNumber(int y) {
		return fParentRuler.toDocumentLineNumber(y);
	}

	/**
	 * Triggers redrawing of the column.
	 */
	private void redraw() {
		fColumn.redraw();
	}

	/**
	 * Triggers immediate redrawing of the entire column - use with care.
	 */
	private void immediateUpdate() {
		fParentRuler.immediateUpdate();
	}

	/**
	 * Returns the width of the column.
	 *
	 * @return the width of the column
	 */
	private int getWidth() {
		return fColumn.getWidth();
	}

	/**
	 * Returns the System background color for list widgets.
	 *
	 * @return the System background color for list widgets
	 */
	private Color getBackground() {
		if (fBackground == null)
			return fWidget.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
		return fBackground;
	}

	/**
	 * Sets the hover later returned by {@link #getHover()}.
	 *
	 * @param hover the hover
	 */
	public void setHover(IAnnotationHover hover) {
		// TODO ignore for now - must make revision hover settable from outside
	}

	/**
	 * Returns <code>true</code> if the receiver can provide a hover for a certain document line.
	 *
	 * @param activeLine the document line of interest
	 * @return <code>true</code> if the receiver can provide a hover
	 */
	public boolean hasHover(int activeLine) {
		return fViewer instanceof ISourceViewer && fHover.getHoverLineRange((ISourceViewer) fViewer, activeLine) != null;
	}

	/**
	 * Returns the revision at a certain document offset, or <code>null</code> for none.
	 *
	 * @param offset the document offset
	 * @return the revision at offset, or <code>null</code> for none
	 */
	Revision getRevision(int offset) {
		IDocument document= fViewer.getDocument();
		int line;
		try {
			line= document.getLineOfOffset(offset);
		} catch (BadLocationException x) {
			return null;
		}
		if (line != -1) {
			RevisionRange range= getRange(line);
			if (range != null)
				return range.getRevision();
		}
		return null;
	}

	/**
	 * Returns <code>true</code> if a revision model has been set, <code>false</code> otherwise.
	 *
	 * @return <code>true</code> if a revision model has been set, <code>false</code> otherwise
	 */
	public boolean hasInformation() {
		return fRevisionInfo != null;
	}

	/**
	 * Returns the width in chars required to display information.
	 *
	 * @return the width in chars required to display information
	 * @since 3.3
	 */
	public int getRequiredWidth() {
		if (fRequiredWidth == -1) {
			if (hasInformation() && (fShowRevision || fShowAuthor)) {
				int revisionWidth= 0;
				int authorWidth= 0;
				for (Revision revision : fRevisionInfo.getRevisions()) {
					revisionWidth= Math.max(revisionWidth, revision.getId().length());
					authorWidth= Math.max(authorWidth, revision.getAuthor().length());
				}
				fRevisionIdChars= revisionWidth + 1;
				if (fShowAuthor && fShowRevision)
					fRequiredWidth= revisionWidth + authorWidth + 2;
				else if (fShowAuthor)
					fRequiredWidth= authorWidth + 1;
				else
					fRequiredWidth= revisionWidth + 1;
			} else {
				fRequiredWidth= 0;
			}
		}
		return fRequiredWidth;
	}

	/**
	 * Enables showing the revision id.
	 *
	 * @param show <code>true</code> to show the revision, <code>false</code> to hide it
	 */
	public void showRevisionId(boolean show) {
		if (fShowRevision != show) {
			fRequiredWidth= -1;
			fRevisionIdChars= 0;
			fShowRevision= show;
			postRedraw();
		}
	}

	/**
	 * Enables showing the revision author.
	 *
	 * @param show <code>true</code> to show the author, <code>false</code> to hide it
	 */
	public void showRevisionAuthor(boolean show) {
		if (fShowAuthor != show) {
			fRequiredWidth= -1;
			fRevisionIdChars= 0;
			fShowAuthor= show;
			postRedraw();
		}
	}

	/**
	 * Adds a revision listener.
	 *
	 * @param listener the listener
	 * @since 3.3
	 */
	public void addRevisionListener(IRevisionListener listener) {
		fRevisionListeners.add(listener);
	}

	/**
	 * Removes a revision listener.
	 *
	 * @param listener the listener
	 * @since 3.3
	 */
	public void removeRevisionListener(IRevisionListener listener) {
		fRevisionListeners.remove(listener);
	}

	/**
	 * Informs the revision listeners about a change.
	 *
	 * @since 3.3
	 */
	private void informListeners() {
		if (fRevisionInfo == null || fRevisionListeners.isEmpty())
			return;

		RevisionEvent event= new RevisionEvent(fRevisionInfo);
		for (IRevisionListener listener : fRevisionListeners) {
			listener.revisionInformationChanged(event);
		}
	}
}