/*******************************************************************************
 * Copyright (c) 2006, 2016 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.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.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
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.resource.JFaceResources;

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<>();

		/**
		 * 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();

			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 adaptColor(Revision revision, boolean focus) {
			RGB rgb;
			float scale;
			if (fRenderingMode == IRevisionRulerColumnExtension.AGE) {
				int index= computeAgeIndex(revision);
				if (index == -1 || fRevisions.size() == 0) {
					rgb= getBackground().getRGB();
				} else {
					// gradient from intense red for most recent to faint yellow for oldest
					RGB[] gradient= Colors.palette(BY_DATE_START_COLOR, BY_DATE_END_COLOR, 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).indexOf("<html>") != -1) //$NON-NLS-1$
	        				// there is already a header
	        				return html;

	        			StringBuffer info= new StringBuffer(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: #0000FF }\n" + //$NON-NLS-1$
		"a:hover	     { color: #000080 }\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 zoom level for the current painting operation. Workaround for bug 516293.
	 * @since 3.12
	 */
	private int fZoom= 100;

	/**
	 * 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;
	}

	/**
	 * Sets the zoom level for the current painting operation. Workaround for bug 516293.
	 * 
	 * @param zoom the zoom to set
	 * @since 3.12
	 */
	public void setZoom(int zoom) {
		fZoom= zoom;
	}

	private int autoScaleUp(int value) {
		return value * fZoom / 100;
	}

	/**
	 * 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(new DisposeListener() {
			@Override
			public void widgetDisposed(DisposeEvent 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, autoScaleUp(y1), autoScaleUp(getWidth()), autoScaleUp(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(new Runnable() {
					@Override
					public void run() {
						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);
		}
	}
}