/*******************************************************************************
 * Copyright (c) 2001, 2006 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 com.ibm.icu.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.internal.Logger;
import org.eclipse.wst.sse.ui.internal.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);
	}
}
