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

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
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.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.wst.sse.core.internal.util.Debug;
import org.eclipse.wst.sse.core.internal.util.Utilities;
import org.eclipse.wst.sse.ui.internal.view.events.CaretEvent;
import org.eclipse.wst.sse.ui.internal.view.events.ICaretListener;

/**
 * Has the responsibility of listening for key events, and mouse events,
 * deciding if the caret has moved (without a text change), and if so, will
 * notify CaretListeners that the caret has moved. Objects which are
 * interested in ALL caret postion changes will also have to listen for
 * textChanged events.
 */
public class CaretMediator implements Listener {

	class CaretMediatorListener implements KeyListener, MouseListener {
		public void keyPressed(KeyEvent e) {
			internalKeyPressed(e);
		}

		public void keyReleased(KeyEvent e) {
			internalKeyReleased(e);
		}

		public void mouseDoubleClick(MouseEvent e) {
		}

		public void mouseDown(MouseEvent e) {
			internalMouseDown(e);
		}

		public void mouseUp(MouseEvent e) {
			internalMouseUp(e);
		}
	}

	class RefreshDelayJob extends Job {
		private int fDelay = 0;
		RefreshDelayJob(int delay) {
			super(SSEUIMessages.caret_update); //$NON-NLS-1$
			setSystem(true);
			fDelay = delay;
		}

		/**
		 * Setup a delayed CaretEvent firing
		 */
		void touch() {
			cancel();
			schedule(fDelay);
		}

		protected IStatus run(IProgressMonitor monitor) {
			handleEvent(null);
			return Status.OK_STATUS;
		}
	}
	
	RefreshDelayJob fDelayer = null;
	private static final int DELAY = 300;

	/** used just for debug print outs */
	private long endTime;
	private long startTime;

	protected ICaretListener[] fCaretListeners;
	protected CaretMediatorListener internalListener;
	protected StyledText textWidget;

	/**
	 * CaretMediator constructor comment.
	 */
	public CaretMediator() {
		super();
	}

	/**
	 * CaretMediator constructor comment. Must always provide the widget its
	 * supposed to listen to.
	 */
	public CaretMediator(StyledText styledTextWidget) {
		this();
		setTextWidget(styledTextWidget);
	}

	public synchronized void addCaretListener(ICaretListener listener) {
		if (Debug.debugStructuredDocument) {
			System.out.println("CaretMediator::addCaretListener. Request to add an instance of " + listener.getClass() + " as a listener on caretlistner.");//$NON-NLS-2$//$NON-NLS-1$
		}
		// make sure listener is not already in listening array
		// (and if it is, print a warning to aid debugging, if needed)

		if (Utilities.contains(fCaretListeners, listener)) {
			if (Debug.displayWarnings) {
				System.out.println("CaretMediator::addCaretListener. listener " + listener + " was added more than once. ");//$NON-NLS-2$//$NON-NLS-1$
			}
		} else {
			if (Debug.debugStructuredDocument) {
				System.out.println("CaretMediator::addCaretListener. Adding an instance of " + listener.getClass() + " as a listener on caret mediator.");//$NON-NLS-2$//$NON-NLS-1$
			}
			int oldSize = 0;
			if (fCaretListeners != null) {
				// normally won't be null, but we need to be sure, for first
				// time through
				oldSize = fCaretListeners.length;
			}
			int newSize = oldSize + 1;
			ICaretListener[] newListeners = new ICaretListener[newSize];
			if (fCaretListeners != null) {
				System.arraycopy(fCaretListeners, 0, newListeners, 0, oldSize);
			}
			// add listener to last position
			newListeners[newSize - 1] = listener;
			//
			// now switch new for old
			fCaretListeners = newListeners;

		}
	}

	protected void fireCaretEvent(CaretEvent event) {
		if (fCaretListeners != null) {
			// we must assign listeners to local variable to be thread safe,
			// since the add and remove listner methods
			// can change this object's actual instance of the listener array
			// from another thread
			// (and since object assignment is atomic, we don't need to
			// synchronize
			ICaretListener[] holdListeners = fCaretListeners;
			//
			for (int i = 0; i < holdListeners.length; i++) {
				holdListeners[i].caretMoved(event);
			}
		}
	}

	public void handleEvent(Event e) {
		Display display = null;

		if (Debug.debugCaretMediator) {
			endTime = System.currentTimeMillis();
			System.out.println("Timer fired: " + (endTime - startTime)); //$NON-NLS-1$
		}

		// check if 'okToUse'
		if (textWidget != null && !textWidget.isDisposed()) {
			display = textWidget.getDisplay();
			if ((display != null) && (!display.isDisposed())) {
				display.asyncExec(new Runnable() {
					public void run() {
						if (textWidget != null && !textWidget.isDisposed()) {
							fireCaretEvent(new CaretEvent(textWidget, textWidget.getCaretOffset()));
						}
					}
				});
			}
		}
	}

	protected void internalKeyPressed(KeyEvent e) {
		fDelayer.cancel();
	}

	protected void internalKeyReleased(KeyEvent e) {
		switch (e.keyCode) {
			case SWT.ARROW_DOWN :
			case SWT.ARROW_UP :
			case SWT.ARROW_LEFT :
			case SWT.ARROW_RIGHT :
			case SWT.HOME :
			case SWT.END :
			case SWT.PAGE_DOWN :
			case SWT.PAGE_UP : {
				fDelayer.touch();
				break;
			}
			default : {
				// always update cursor postion, even during normal typing
				// (the logic may look funny, since we always to the same
				// thing, but we haven't always done the same thing, so I
				// wanted to leave that fact documented via code.)
				fDelayer.touch();
			}
		}
	}

	protected void internalMouseDown(MouseEvent e) {
		fDelayer.cancel();
	}

	protected void internalMouseUp(MouseEvent e) {
		// Note, even during a swipe select, when the mouse button goes up,
		// and the widget is
		// queried for the current caret postion, it always returns the
		// beginning of the selection,
		// which is desirable (at least for the known use of this feature,
		// which is to signal
		// that the property sheet can update itself.
		fDelayer.touch();
	}

	public void release() {
		fDelayer.cancel();
		if (textWidget != null && !textWidget.isDisposed()) {
			textWidget.removeKeyListener(internalListener);
			textWidget.removeMouseListener(internalListener);
			textWidget = null;
		}
	}

	public synchronized void removeCaretListener(ICaretListener listener) {
		if ((fCaretListeners != null) && (listener != null)) {
			// if its not in the listeners, we'll ignore the request
			if (Utilities.contains(fCaretListeners, listener)) {
				int oldSize = fCaretListeners.length;
				int newSize = oldSize - 1;
				ICaretListener[] newListeners = new ICaretListener[newSize];
				int index = 0;
				for (int i = 0; i < oldSize; i++) {
					if (fCaretListeners[i] == listener) { // ignore
					} else {
						// copy old to new if its not the one we are removing
						newListeners[index++] = fCaretListeners[i];
					}
				}
				// now that we have a new array, let's switch it for the old
				// one
				fCaretListeners = newListeners;
			}
		}
	}

	public void setTextWidget(StyledText newTextWidget) {
		if(fDelayer == null) {
			fDelayer = new RefreshDelayJob(DELAY);
		}

		// unhook from previous, if any
		if (this.textWidget != null) {
			fDelayer.cancel();
			this.textWidget.removeKeyListener(internalListener);
			this.textWidget.removeMouseListener(internalListener);
		}

		this.textWidget = newTextWidget;

		if (internalListener == null) {
			internalListener = new CaretMediatorListener();
		}

		if (this.textWidget != null) {
			this.textWidget.addKeyListener(internalListener);
			this.textWidget.addMouseListener(internalListener);
		}
	}
}
