/*******************************************************************************
 * Copyright (c) 2001, 2004 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui.internal.openon;

import java.util.StringTokenizer;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
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.ITextViewerExtension5;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
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.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.wst.sse.ui.extensions.openon.IOpenOn;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.openon.OpenOnProvider;
import org.eclipse.wst.sse.ui.util.EditorUtility;


/**
 * @deprecated Use org.eclipse.jface.text.hyperlink.HyperlinkManager
 */
public class OpenFileHyperlinkTracker implements KeyListener, MouseListener, MouseMoveListener, FocusListener, PaintListener, IPropertyChangeListener, IDocumentListener, ITextInputListener {

	/** The session is active. */
	private boolean fActive;

	/** The currently active style range. */
	private IRegion fActiveRegion;
	/** Preference key for browser-like links to be enabled */
	private String fBrowserLikeLinksKeyModifierKey;

	/** The link color. */
	private Color fColor;
	/** The hand cursor. */
	private Cursor fCursor;
	/** The key modifier mask. */
	private int fKeyModifierMask;
	/** Preference key for hyperlink underline color */
	private String fLinkColorKey;
	/** The preference store */
	private IPreferenceStore fPreferenceStore;
	/** The currently active style range as position. */
	private Position fRememberedPosition;

	/** The text viewer this hyperlink tracker is associated with */
	private ITextViewer fTextViewer;

	/**
	 *  
	 */
	public OpenFileHyperlinkTracker(ITextViewer textViewer) {
		fTextViewer = textViewer;
	}

	private void activateCursor(ITextViewer viewer) {
		StyledText text = viewer.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 int computeStateMask(String modifiers) {
		if (modifiers == null)
			return -1;

		if (modifiers.length() == 0)
			return SWT.NONE;

		int stateMask = 0;
		StringTokenizer modifierTokenizer = new StringTokenizer(modifiers, ",;.:+-* "); //$NON-NLS-1$
		while (modifierTokenizer.hasMoreTokens()) {
			int modifier = EditorUtility.findLocalizedModifier(modifierTokenizer.nextToken());
			if (modifier == 0 || (stateMask & modifier) == modifier)
				return -1;
			stateMask = stateMask | modifier;
		}
		return stateMask;
	}

	/**
	 * Creates a color from the information stored in the given preference
	 * store. Returns <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);
		}

		return EditorUtility.getColor(rgb);
	}

	public void deactivate() {
		deactivate(false);
	}

	public void deactivate(boolean redrawAll) {
		if (!fActive)
			return;

		repairRepresentation(redrawAll);
		fActive = false;
	}

	/*
	 * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
	 */
	public void documentAboutToBeChanged(DocumentEvent event) {
		if (fActive && 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;

				ITextViewer viewer = getTextViewer();
				if (viewer != null) {
					StyledText widget = viewer.getTextWidget();
					if (widget != null && !widget.isDisposed()) {
						widget.getDisplay().asyncExec(new Runnable() {
							public void run() {
								deactivate();
							}
						});
					}
				}

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

	/*
	 * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
	 */
	public void focusGained(FocusEvent e) {
	}

	/*
	 * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
	 */
	public void focusLost(FocusEvent event) {
		deactivate();
	}

	private int getCurrentTextOffset() {
		try {
			StyledText text = getTextViewer().getTextWidget();
			if (text == null || text.isDisposed())
				return -1;

			Display display = text.getDisplay();
			Point absolutePosition = display.getCursorLocation();
			Point relativePosition = text.toControl(absolutePosition);

			int widgetOffset = text.getOffsetAtLocation(relativePosition);
			if (getTextViewer() instanceof ITextViewerExtension5) {
				ITextViewerExtension5 extension = (ITextViewerExtension5) getTextViewer();
				return extension.widgetOffset2ModelOffset(widgetOffset);
			} else {
				return widgetOffset + getTextViewer().getVisibleRegion().getOffset();
			}

		} catch (IllegalArgumentException e) {
			return -1;
		}
	}

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

		for (int i = 0; i <= length; i++) {
			Point location = text.getLocationAtOffset(offset + i);

			if (location.x > maxLocation.x)
				maxLocation.x = location.x;
			if (location.y > maxLocation.y)
				maxLocation.y = location.y;
		}

		return maxLocation;
	}

	private Point getMinimumLocation(StyledText text, int offset, int length) {
		Point minLocation = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);

		for (int i = 0; i <= length; i++) {
			Point location = text.getLocationAtOffset(offset + i);

			if (location.x < minLocation.x)
				minLocation.x = location.x;
			if (location.y < minLocation.y)
				minLocation.y = location.y;
		}

		return minLocation;
	}

	private IPreferenceStore getNewPreferenceStore() {
		return fPreferenceStore;
	}

	private ITextViewer getTextViewer() {
		return fTextViewer;
	}

	private void highlightRegion(ITextViewer viewer, IRegion region) {

		if (region.equals(fActiveRegion))
			return;

		repairRepresentation();

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


		// Underline
		int offset = 0;
		int length = 0;
		if (viewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
			IRegion widgetRange = extension.modelRange2WidgetRange(new Region(region.getOffset(), region.getLength()));
			if (widgetRange == null)
				return;

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

		} else {
			offset = region.getOffset() - viewer.getVisibleRegion().getOffset();
			length = region.getLength();
		}
		// need clearBackground to be true for paint event to be fired
		text.redrawRange(offset, length, true);

		fActiveRegion = region;
	}

	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.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument,
	 *      org.eclipse.jface.text.IDocument)
	 */
	public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
		if (oldInput == null)
			return;
		deactivate();
		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);
	}

	public void install(IPreferenceStore store) {
		fPreferenceStore = store;
		ITextViewer textViewer = getTextViewer();
		if (textViewer == null)
			return;

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

		updateColor(textViewer);

		textViewer.addTextInputListener(this);

		IDocument document = textViewer.getDocument();
		if (document != null)
			document.addDocumentListener(this);

		text.addKeyListener(this);
		text.addMouseListener(this);
		text.addMouseMoveListener(this);
		text.addFocusListener(this);
		text.addPaintListener(this);

		updateKeyModifierMask();

		fPreferenceStore.addPropertyChangeListener(this);
	}

	/*
	 * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
	 */
	public void keyPressed(KeyEvent event) {

		if (fActive) {
			deactivate();
			return;
		}

		if (event.keyCode != fKeyModifierMask) {
			deactivate();
			return;
		}

		fActive = true;

		//			removed for #25871
		//
		//			ISourceViewer viewer= getSourceViewer();
		//			if (viewer == null)
		//				return;
		//			
		//			IRegion region= getCurrentTextRegion(viewer);
		//			if (region == null)
		//				return;
		//			
		//			highlightRegion(viewer, region);
		//			activateCursor(viewer);
	}

	/*
	 * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
	 */
	public void keyReleased(KeyEvent event) {

		if (!fActive)
			return;

		deactivate();
	}

	/*
	 * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseDoubleClick(MouseEvent e) {
	}

	/*
	 * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseDown(MouseEvent event) {

		if (!fActive)
			return;

		if (event.stateMask != fKeyModifierMask) {
			deactivate();
			return;
		}

		if (event.button != 1) {
			deactivate();
			return;
		}
	}

	/*
	 * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseMove(MouseEvent event) {

		if (event.widget instanceof Control && !((Control) event.widget).isFocusControl()) {
			deactivate();
			return;
		}

		if (!fActive) {
			if (event.stateMask != fKeyModifierMask)
				return;
			// modifier was already pressed
			fActive = true;
		}

		ITextViewer viewer = getTextViewer();
		if (viewer == null) {
			deactivate();
			return;
		}

		StyledText text = viewer.getTextWidget();
		if (text == null || text.isDisposed()) {
			deactivate();
			return;
		}

		if ((event.stateMask & SWT.BUTTON1) != 0 && text.getSelectionCount() != 0) {
			deactivate();
			return;
		}

		IRegion region = null;
		int offset = getCurrentTextOffset();
		IOpenOn openOn = OpenOnProvider.getInstance().getOpenOn(getTextViewer().getDocument(), offset);
		if (openOn != null) {
			region = openOn.getOpenOnRegion(getTextViewer().getDocument(), offset);
		}
		if (region == null || region.getLength() == 0) {
			repairRepresentation();
			return;
		}

		highlightRegion(viewer, region);
		activateCursor(viewer);
	}

	/*
	 * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseUp(MouseEvent e) {

		if (!fActive)
			return;

		if (e.button != 1) {
			deactivate();
			return;
		}

		boolean wasActive = fCursor != null;
		IRegion previousRegion = fActiveRegion;

		deactivate();

		if (wasActive) {
			IOpenOn openOn = OpenOnProvider.getInstance().getOpenOn(getTextViewer().getDocument(), previousRegion.getOffset());
			if (openOn != null) {
				openOn.openOn(getTextViewer().getDocument(), previousRegion);
			}
		}
	}

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

		ITextViewer viewer = getTextViewer();
		if (viewer == null)
			return;

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


		int offset = 0;
		int length = 0;

		if (viewer instanceof ITextViewerExtension5) {

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

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

		} else {

			IRegion region = viewer.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 = minLocation.x + maxLocation.x - minLocation.x - 1;
		int y = minLocation.y + text.getLineHeight() - 1;

		GC gc = event.gc;
		if (fColor != null && !fColor.isDisposed())
			gc.setForeground(fColor);
		gc.drawLine(x1, y, x2, y);
	}

	/*
	 * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
	 */
	public void propertyChange(PropertyChangeEvent event) {
		if (event.getProperty().equals(fLinkColorKey)) {
			ITextViewer viewer = getTextViewer();
			if (viewer != null)
				updateColor(viewer);
		} else if (event.getProperty().equals(fBrowserLikeLinksKeyModifierKey)) {
			updateKeyModifierMask();
		}
	}

	private void repairRepresentation() {
		repairRepresentation(false);
	}

	private void repairRepresentation(boolean redrawAll) {

		if (fActiveRegion == null)
			return;

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

		ITextViewer viewer = getTextViewer();
		if (viewer != null) {

			resetCursor(viewer);

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

				// need clearBackground to be true for paint event to be fired
				text.redrawRange(offset, length, true);
			} catch (IllegalArgumentException x) {
				Logger.logException(x);
			}
		}
	}

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

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

	public void setHyperlinkPreferenceKeys(String linkColorKey, String browserLikeLinksKeyModifierKey) {
		fLinkColorKey = linkColorKey;
		fBrowserLikeLinksKeyModifierKey = browserLikeLinksKeyModifierKey;
	}

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

		ITextViewer textViewer = getTextViewer();
		if (textViewer == null)
			return;

		textViewer.removeTextInputListener(this);

		IDocument document = textViewer.getDocument();
		if (document != null)
			document.removeDocumentListener(this);

		IPreferenceStore preferenceStore = getNewPreferenceStore();
		if (preferenceStore != null)
			preferenceStore.removePropertyChangeListener(this);

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

		text.removeKeyListener(this);
		text.removeMouseListener(this);
		text.removeMouseMoveListener(this);
		text.removeFocusListener(this);
		text.removePaintListener(this);
	}

	private void updateColor(ITextViewer viewer) {
		StyledText text = viewer.getTextWidget();
		if (text == null || text.isDisposed())
			return;

		Display display = text.getDisplay();
		fColor = createColor(getNewPreferenceStore(), fLinkColorKey, display);
	}

	private void updateKeyModifierMask() {
		String modifiers = getNewPreferenceStore().getString(fBrowserLikeLinksKeyModifierKey);
		fKeyModifierMask = computeStateMask(modifiers);
	}
}
