package org.eclipse.wst.sse.ui.internal.hyperlink;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.text.Assert;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.text.hyperlink.IHyperlinkPresenter;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
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.Display;


/**
 * The is almost an exact copy of DefaultHyperlinkPresenter. However this
 * hyperlink presenter works with the StructuredTextEditor's Highlighter
 * instead of TextPresentation.
 * 
 * The main difference is <code>text.redrawRange(offset, length, true);</code>
 * is called instead of passing false for clearBackground. Also all mention of
 * TextPresentation was removed since it does not really apply.
 * 
 * @see org.eclipse.jface.text.hyperlink.DefaultHyperlinkPresenter
 */
public class HighlighterHyperlinkPresenter implements IHyperlinkPresenter, PaintListener, ITextInputListener, IDocumentListener, IPropertyChangeListener {

	/**
	 * A named preference that holds the color used for hyperlinks.
	 * <p>
	 * Value is of type <code>String</code>. A RGB color value encoded as a
	 * string using class <code>PreferenceConverter</code>
	 * </p>
	 * 
	 * @see org.eclipse.jface.resource.StringConverter
	 * @see org.eclipse.jface.preference.PreferenceConverter
	 */
	public final static String HYPERLINK_COLOR = "hyperlinkColor"; //$NON-NLS-1$


	/** The text viewer. */
	private ITextViewer fTextViewer;
	/** The hand cursor. */
	private Cursor fCursor;
	/** The link color. */
	private Color fColor;
	/** Tells whether to dispose the color on uninstall. */
	private boolean fDisposeColor;
	/** The currently active region. */
	private IRegion fActiveRegion;
	/** The currently active style range as position. */
	private Position fRememberedPosition;
	/** The optional preference store */
	private IPreferenceStore fPreferenceStore;


	/**
	 * Creates a new default hyperlink presenter which uses
	 * {@link #HYPERLINK_COLOR}to read the color from the given preference
	 * store.
	 * 
	 * @param store
	 *            the preference store
	 */
	public HighlighterHyperlinkPresenter(IPreferenceStore store) {
		fPreferenceStore = store;
		fDisposeColor = true;
	}

	/**
	 * Creates a new default hyperlink presenter.
	 * 
	 * @param color
	 *            the hyperlink color, to be disposed by the caller
	 */
	public HighlighterHyperlinkPresenter(Color color) {
		fDisposeColor = false;
		fColor = color;
	}

	public boolean canShowMultipleHyperlinks() {
		return false;
	}

	public void showHyperlinks(IHyperlink[] hyperlinks) {
		Assert.isLegal(hyperlinks != null && hyperlinks.length == 1);
		highlightRegion(hyperlinks[0].getHyperlinkRegion());
		activateCursor();
	}

	public void hideHyperlinks() {
		repairRepresentation();
		fRememberedPosition = null;
	}

	public void install(ITextViewer textViewer) {
		Assert.isNotNull(textViewer);
		fTextViewer = textViewer;
		fTextViewer.addTextInputListener(this);

		StyledText text = fTextViewer.getTextWidget();
		if (text != null && !text.isDisposed()) {
			text.addPaintListener(this);
			if (fPreferenceStore != null)
				fColor = createColor(fPreferenceStore, HYPERLINK_COLOR, text.getDisplay());
		}

		if (fPreferenceStore != null)
			fPreferenceStore.addPropertyChangeListener(this);
	}

	public void uninstall() {
		fTextViewer.removeTextInputListener(this);

		if (fColor != null) {
			if (fDisposeColor)
				fColor.dispose();
			fColor = null;
		}

		if (fCursor != null) {
			fCursor.dispose();
			fCursor = null;
		}

		StyledText text = fTextViewer.getTextWidget();
		if (text != null && !text.isDisposed())
			text.removePaintListener(this);

		fTextViewer = null;

		if (fPreferenceStore != null)
			fPreferenceStore.removePropertyChangeListener(this);
	}

	public void setColor(Color color) {
		Assert.isNotNull(fTextViewer);
		fColor = color;
	}

	private void highlightRegion(IRegion region) {

		if (region.equals(fActiveRegion))
			return;

		repairRepresentation();

		StyledText text = fTextViewer.getTextWidget();
		if (text == null || text.isDisposed())
			return;


		// Underline
		int offset = 0;
		int length = 0;
		if (fTextViewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension = (ITextViewerExtension5) fTextViewer;
			IRegion widgetRange = extension.modelRange2WidgetRange(region);
			if (widgetRange == null)
				return;

			offset = widgetRange.getOffset();
			length = widgetRange.getLength();

		}
		else {
			offset = region.getOffset() - fTextViewer.getVisibleRegion().getOffset();
			length = region.getLength();
		}

		// needs to clean background due to StructuredTextEditor's highlighter
		text.redrawRange(offset, length, true);

		// Invalidate region ==> apply text presentation
		fActiveRegion = region;

		if (fTextViewer instanceof ITextViewerExtension2)
			((ITextViewerExtension2) fTextViewer).invalidateTextPresentation(region.getOffset(), region.getLength());
		else
			fTextViewer.invalidateTextPresentation();
	}

	private void activateCursor() {
		StyledText text = fTextViewer.getTextWidget();
		if (text == null || text.isDisposed())
			return;
		Display display = text.getDisplay();
		if (fCursor == null)
			fCursor = new Cursor(display, SWT.CURSOR_HAND);
		text.setCursor(fCursor);
	}

	private void resetCursor() {
		StyledText text = fTextViewer.getTextWidget();
		if (text != null && !text.isDisposed())
			text.setCursor(null);

		if (fCursor != null) {
			fCursor.dispose();
			fCursor = null;
		}
	}

	private void repairRepresentation() {

		if (fActiveRegion == null)
			return;

		int offset = fActiveRegion.getOffset();
		int length = fActiveRegion.getLength();
		fActiveRegion = null;

		resetCursor();

		// Invalidate ==> remove applied text presentation
		if (fTextViewer instanceof ITextViewerExtension2)
			((ITextViewerExtension2) fTextViewer).invalidateTextPresentation(offset, length);
		else
			fTextViewer.invalidateTextPresentation();

		// Remove underline
		if (fTextViewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension = (ITextViewerExtension5) fTextViewer;
			offset = extension.modelOffset2WidgetOffset(offset);
		}
		else {
			offset -= fTextViewer.getVisibleRegion().getOffset();
		}
		try {
			StyledText text = fTextViewer.getTextWidget();

			// needs to clean background due to StructuredTextEditor's
			// highlighter
			text.redrawRange(offset, length, true);

		}
		catch (IllegalArgumentException x) {
			// ignore - do not log
		}
	}

	/*
	 * @see PaintListener#paintControl(PaintEvent)
	 */
	public void paintControl(PaintEvent event) {
		if (fActiveRegion == null)
			return;

		StyledText text = fTextViewer.getTextWidget();
		if (text == null || text.isDisposed())
			return;

		int offset = 0;
		int length = 0;

		if (fTextViewer instanceof ITextViewerExtension5) {

			ITextViewerExtension5 extension = (ITextViewerExtension5) fTextViewer;
			IRegion widgetRange = extension.modelRange2WidgetRange(fActiveRegion);
			if (widgetRange == null)
				return;

			offset = widgetRange.getOffset();
			length = widgetRange.getLength();

		}
		else {

			IRegion region = fTextViewer.getVisibleRegion();
			if (!includes(region, fActiveRegion))
				return;

			offset = fActiveRegion.getOffset() - region.getOffset();
			length = fActiveRegion.getLength();
		}

		// support for BIDI
		Point minLocation = getMinimumLocation(text, offset, length);
		Point maxLocation = getMaximumLocation(text, offset, length);

		int x1 = minLocation.x;
		int x2 = maxLocation.x - 1;
		int y = minLocation.y + text.getLineHeight() - 1;

		GC gc = event.gc;
		if (fColor != null && !fColor.isDisposed())
			gc.setForeground(fColor);
		else if (fColor == null && !(offset < 0 && offset >= text.getCharCount())) {
			StyleRange style = text.getStyleRangeAtOffset(offset);
			if (style != null)
				gc.setForeground(style.foreground);
		}
		gc.drawLine(x1, y, x2, y);
	}

	private Point getMinimumLocation(StyledText text, int offset, int length) {
		int max = text.getCharCount();
		Rectangle bounds = text.getBounds();
		Point minLocation = new Point(bounds.width, bounds.height);
		for (int i = 0; i <= length; i++) {
			int k = offset + i;
			if (k < 0 || k > max)
				break;

			Point location = text.getLocationAtOffset(k);
			if (location.x < minLocation.x)
				minLocation.x = location.x;
			if (location.y < minLocation.y)
				minLocation.y = location.y;
		}

		return minLocation;
	}

	private Point getMaximumLocation(StyledText text, int offset, int length) {
		Point maxLocation = new Point(0, 0);

		for (int i = 0; i <= length; i++) {
			int k = offset + i;
			if (k < 0 || k > text.getCharCount())
				break;

			Point location = text.getLocationAtOffset(k);
			if (location.x > maxLocation.x)
				maxLocation.x = location.x;
			if (location.y > maxLocation.y)
				maxLocation.y = location.y;
		}

		return maxLocation;
	}

	private boolean includes(IRegion region, IRegion position) {
		return position.getOffset() >= region.getOffset() && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength();
	}

	/*
	 * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
	 */
	public void documentAboutToBeChanged(DocumentEvent event) {
		if (fActiveRegion != null) {
			fRememberedPosition = new Position(fActiveRegion.getOffset(), fActiveRegion.getLength());
			try {
				event.getDocument().addPosition(fRememberedPosition);
			}
			catch (BadLocationException x) {
				fRememberedPosition = null;
			}
		}
	}

	/*
	 * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
	 */
	public void documentChanged(DocumentEvent event) {
		if (fRememberedPosition != null) {
			if (!fRememberedPosition.isDeleted()) {

				event.getDocument().removePosition(fRememberedPosition);
				fActiveRegion = new Region(fRememberedPosition.getOffset(), fRememberedPosition.getLength());
				fRememberedPosition = null;

				StyledText widget = fTextViewer.getTextWidget();
				if (widget != null && !widget.isDisposed()) {
					widget.getDisplay().asyncExec(new Runnable() {
						public void run() {
							hideHyperlinks();
						}
					});
				}

			}
			else {
				fActiveRegion = null;
				fRememberedPosition = null;
				hideHyperlinks();
			}
		}
	}

	/*
	 * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument,
	 *      org.eclipse.jface.text.IDocument)
	 */
	public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
		if (oldInput == null)
			return;
		hideHyperlinks();
		oldInput.removeDocumentListener(this);
	}

	/*
	 * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument,
	 *      org.eclipse.jface.text.IDocument)
	 */
	public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
		if (newInput == null)
			return;
		newInput.addDocumentListener(this);
	}

	/**
	 * Creates a color from the information stored in the given preference
	 * store.
	 * 
	 * @param store
	 *            the preference store
	 * @param key
	 *            the key
	 * @param display
	 *            the display
	 * @return the color or <code>null</code> if there is no such
	 *         information available
	 */
	private Color createColor(IPreferenceStore store, String key, Display display) {

		RGB rgb = null;

		if (store.contains(key)) {

			if (store.isDefault(key))
				rgb = PreferenceConverter.getDefaultColor(store, key);
			else
				rgb = PreferenceConverter.getColor(store, key);

			if (rgb != null)
				return new Color(display, rgb);
		}

		return null;
	}

	/*
	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	public void propertyChange(PropertyChangeEvent event) {
		if (!HYPERLINK_COLOR.equals(event.getProperty()))
			return;

		if (fDisposeColor && fColor != null && !fColor.isDisposed())
			fColor.dispose();
		fColor = null;

		StyledText textWidget = fTextViewer.getTextWidget();
		if (textWidget != null && !textWidget.isDisposed())
			fColor = createColor(fPreferenceStore, HYPERLINK_COLOR, textWidget.getDisplay());
	}
}
