/*******************************************************************************
 * Copyright (c) 2000, 2008 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.jdt.internal.ui.text;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

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.core.runtime.Assert;

import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextEvent;

import org.eclipse.jdt.internal.ui.text.TypingRun.ChangeType;


/**
 * When connected to a text viewer, a <code>TypingRunDetector</code> observes
 * <code>TypingRun</code> events. A typing run is a sequence of similar text
 * modifications, such as inserting or deleting single characters.
 * <p>
 * Listeners are informed about the start and end of a <code>TypingRun</code>.
 * </p>
 *
 * @since 3.0
 */
public class TypingRunDetector {
	/*
	 * Implementation note: This class is independent of JDT and may be pulled
	 * up to jface.text if needed.
	 */

	/** Debug flag. */
	private static final boolean DEBUG= false;

	/**
	 * Instances of this class abstract a text modification into a simple
	 * description. Typing runs consists of a sequence of one or more modifying
	 * changes of the same type. Every change records the type of change
	 * described by a text modification, and an offset it can be followed by
	 * another change of the same run.
	 */
	private static final class Change {
		private ChangeType fType;
		private int fNextOffset;

		/**
		 * Creates a new change of type <code>type</code>.
		 *
		 * @param type the <code>ChangeType</code> of the new change
		 * @param nextOffset the offset of the next change in a typing run
		 */
		public Change(ChangeType type, int nextOffset) {
			fType= type;
			fNextOffset= nextOffset;
		}

		/**
		 * Returns <code>true</code> if the receiver can extend the typing run
		 * the last change of which is described by <code>change</code>.
		 *
		 * @param change the last change in a typing run
		 * @return <code>true</code> if the receiver is a valid extension to
		 *         <code>change</code>, <code>false</code> otherwise
		 */
		public boolean canFollow(Change change) {
			if (fType == TypingRun.NO_CHANGE)
				return true;
			if (fType.equals(TypingRun.UNKNOWN))
				return false;
			if (fType.equals(change.fType)) {
				if (fType == TypingRun.DELETE)
					return fNextOffset == change.fNextOffset - 1;
				else if (fType == TypingRun.INSERT)
					return fNextOffset == change.fNextOffset + 1;
				else if (fType == TypingRun.OVERTYPE)
					return fNextOffset == change.fNextOffset + 1;
				else if (fType == TypingRun.SELECTION)
					return true;
			}
			return false;
		}

		/**
		 * Returns <code>true</code> if the receiver describes a text
		 * modification, <code>false</code> if it describes a focus /
		 * selection change.
		 *
		 * @return <code>true</code> if the receiver is a text modification
		 */
		public boolean isModification() {
			return fType.isModification();
		}

		/*
		 * @see java.lang.Object#toString()
		 */
		@Override
		public String toString() {
			return fType.toString() + "@" + fNextOffset; //$NON-NLS-1$
		}

		/**
		 * Returns the change type of this change.
		 *
		 * @return the change type of this change
		 */
		public ChangeType getType() {
			return fType;
		}
	}

	/**
	 * Observes any events that modify the content of the document displayed in
	 * the editor. Since text events may start a new run, this listener is
	 * always registered if the detector is connected.
	 */
	private class TextListener implements ITextListener {

		/*
		 * @see org.eclipse.jface.text.ITextListener#textChanged(org.eclipse.jface.text.TextEvent)
		 */
		public void textChanged(TextEvent event) {
			handleTextChanged(event);
		}
	}

	/**
	 * Observes non-modifying events that will end a run, such as clicking into
	 * the editor, moving the caret, and the editor losing focus. These events
	 * can never start a run, therefore this listener is only registered if
	 * there is an ongoing run.
	 */
	private class SelectionListener implements MouseListener, KeyListener, FocusListener {

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

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

		/*
		 * @see MouseListener#mouseDoubleClick
		 */
		public void mouseDoubleClick(MouseEvent e) {
		}

		/*
		 * If the right mouse button is pressed, the current editing command is closed
		 * @see MouseListener#mouseDown
		 */
		public void mouseDown(MouseEvent e) {
			if (e.button == 1)
				handleSelectionChanged();
		}

		/*
		 * @see MouseListener#mouseUp
		 */
		public void mouseUp(MouseEvent e) {
		}

		/*
		 * @see KeyListener#keyPressed
		 */
		public void keyReleased(KeyEvent e) {
		}

		/*
		 * On cursor keys, the current editing command is closed
		 * @see KeyListener#keyPressed
		 */
		public void keyPressed(KeyEvent e) {
			switch (e.keyCode) {
				case SWT.ARROW_UP:
				case SWT.ARROW_DOWN:
				case SWT.ARROW_LEFT:
				case SWT.ARROW_RIGHT:
				case SWT.END:
				case SWT.HOME:
				case SWT.PAGE_DOWN:
				case SWT.PAGE_UP:
					handleSelectionChanged();
					break;
			}
		}
	}

	/** The listeners. */
	private final Set<ITypingRunListener> fListeners= new HashSet<ITypingRunListener>();
	/**
	 * The viewer we work upon. Set to <code>null</code> in
	 * <code>uninstall</code>.
	 */
	private ITextViewer fViewer;
	/** The text event listener. */
	private final TextListener fTextListener= new TextListener();
	/**
	 * The selection listener. Set to <code>null</code> when no run is active.
	 */
	private SelectionListener fSelectionListener;

	/* state variables */

	/** The most recently observed change. Never <code>null</code>. */
	private Change fLastChange;
	/** The current run, or <code>null</code> if there is none. */
	private TypingRun fRun;

	/**
	 * Installs the receiver with a text viewer.
	 *
	 * @param viewer the viewer to install on
	 */
	public void install(ITextViewer viewer) {
		Assert.isLegal(viewer != null);
		fViewer= viewer;
		connect();
	}

	/**
	 * Initializes the state variables and registers any permanent listeners.
	 */
	private void connect() {
		if (fViewer != null) {
			fLastChange= new Change(TypingRun.UNKNOWN, -1);
			fRun= null;
			fSelectionListener= null;
			fViewer.addTextListener(fTextListener);
		}
	}

	/**
	 * Uninstalls the receiver and removes all listeners. <code>install()</code>
	 * must be called for events to be generated.
	 */
	public void uninstall() {
		if (fViewer != null) {
			fListeners.clear();
			disconnect();
			fViewer= null;
		}
	}

	/**
	 * Disconnects any registered listeners.
	 */
	private void disconnect() {
		fViewer.removeTextListener(fTextListener);
		ensureSelectionListenerRemoved();
	}

	/**
	 * Adds a listener for <code>TypingRun</code> events. Repeatedly adding
	 * the same listener instance has no effect. Listeners may be added even
	 * if the receiver is neither connected nor installed.
	 *
	 * @param listener the listener add
	 */
	public void addTypingRunListener(ITypingRunListener listener) {
		Assert.isLegal(listener != null);
		fListeners.add(listener);
		if (fListeners.size() == 1)
			connect();
	}

	/**
	 * Removes the listener from this manager. If <code>listener</code> is not
	 * registered with the receiver, nothing happens.
	 *
	 * @param listener the listener to remove, or <code>null</code>
	 */
	public void removeTypingRunListener(ITypingRunListener listener) {
		fListeners.remove(listener);
		if (fListeners.size() == 0)
			disconnect();
	}

	/**
	 * Handles an incoming text event.
	 *
	 * @param event the text event that describes the text modification
	 */
	void handleTextChanged(TextEvent event) {
		Change type= computeChange(event);
		handleChange(type);
	}

	/**
	 * Computes the change abstraction given a text event.
	 *
	 * @param event the text event to analyze
	 * @return a change object describing the event
	 */
	private Change computeChange(TextEvent event) {
		DocumentEvent e= event.getDocumentEvent();
		if (e == null)
			return new Change(TypingRun.NO_CHANGE, -1);

		int start= e.getOffset();
		int end= e.getOffset() + e.getLength();
		String newText= e.getText();
		if (newText == null)
			newText= new String();

		if (start == end) {
			// no replace / delete / overwrite
			if (newText.length() == 1)
				return new Change(TypingRun.INSERT, end + 1);
		} else if (start == end - 1) {
			if (newText.length() == 1)
				return new Change(TypingRun.OVERTYPE, end);
			if (newText.length() == 0)
				return new Change(TypingRun.DELETE, start);
		}

		return new Change(TypingRun.UNKNOWN, -1);
	}

	/**
	 * Handles an incoming selection event.
	 */
	void handleSelectionChanged() {
		handleChange(new Change(TypingRun.SELECTION, -1));
	}

	/**
	 * State machine. Changes state given the current state and the incoming
	 * change.
	 *
	 * @param change the incoming change
	 */
	private void handleChange(Change change) {
		if (change.getType() == TypingRun.NO_CHANGE)
			return;

		if (DEBUG)
			System.err.println("Last change: " + fLastChange); //$NON-NLS-1$

		if (!change.canFollow(fLastChange))
			endIfStarted(change);
		fLastChange= change;
		if (change.isModification())
			startOrContinue();

		if (DEBUG)
			System.err.println("New change: " + change); //$NON-NLS-1$
	}

	/**
	 * Starts a new run if there is none and informs all listeners. If there
	 * already is a run, nothing happens.
	 */
	private void startOrContinue() {
		if (!hasRun()) {
			if (DEBUG)
				System.err.println("+Start run"); //$NON-NLS-1$
			fRun= new TypingRun(fLastChange.getType());
			ensureSelectionListenerAdded();
			fireRunBegun(fRun);
		}
	}

	/**
	 * Returns <code>true</code> if there is an active run, <code>false</code>
	 * otherwise.
	 *
	 * @return <code>true</code> if there is an active run, <code>false</code>
	 *         otherwise
	 */
	private boolean hasRun() {
		return fRun != null;
	}

	/**
	 * Ends any active run and informs all listeners. If there is none, nothing
	 * happens.
	 *
	 * @param change the change that triggered ending the active run
	 */
	private void endIfStarted(Change change) {
		if (hasRun()) {
			ensureSelectionListenerRemoved();
			if (DEBUG)
				System.err.println("-End run"); //$NON-NLS-1$
			fireRunEnded(fRun, change.getType());
			fRun= null;
		}
	}

	/**
	 * Adds the selection listener to the text widget underlying the viewer, if
	 * not already done.
	 */
	private void ensureSelectionListenerAdded() {
		if (fSelectionListener == null) {
			fSelectionListener= new SelectionListener();
			StyledText textWidget= fViewer.getTextWidget();
			textWidget.addFocusListener(fSelectionListener);
			textWidget.addKeyListener(fSelectionListener);
			textWidget.addMouseListener(fSelectionListener);
		}
	}

	/**
	 * If there is a selection listener, it is removed from the text widget
	 * underlying the viewer.
	 */
	private void ensureSelectionListenerRemoved() {
		if (fSelectionListener != null) {
			StyledText textWidget= fViewer.getTextWidget();
			textWidget.removeFocusListener(fSelectionListener);
			textWidget.removeKeyListener(fSelectionListener);
			textWidget.removeMouseListener(fSelectionListener);
			fSelectionListener= null;
		}
	}

	/**
	 * Informs all listeners about a newly started <code>TypingRun</code>.
	 *
	 * @param run the new run
	 */
	private void fireRunBegun(TypingRun run) {
		List<ITypingRunListener> listeners= new ArrayList<ITypingRunListener>(fListeners);
		for (Iterator<ITypingRunListener> it= listeners.iterator(); it.hasNext();) {
			ITypingRunListener listener= it.next();
			listener.typingRunStarted(fRun);
		}
	}

	/**
	 * Informs all listeners about an ended <code>TypingRun</code>.
	 *
	 * @param run the previously active run
	 * @param reason the type of change that caused the run to be ended
	 */
	private void fireRunEnded(TypingRun run, ChangeType reason) {
		List<ITypingRunListener> listeners= new ArrayList<ITypingRunListener>(fListeners);
		for (Iterator<ITypingRunListener> it= listeners.iterator(); it.hasNext();) {
			ITypingRunListener listener= it.next();
			listener.typingRunEnded(fRun, reason);
		}
	}
}
