/*******************************************************************************
 * Copyright (c) 2008, 2010 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.ui.internal.util;

import java.util.Locale;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.AssertionFailedException;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jpt.ui.internal.widgets.NullPostExecution;
import org.eclipse.jpt.ui.internal.widgets.PostExecution;
import org.eclipse.jpt.utility.internal.ReflectionTools;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.ScrolledForm;

/**
 * A suite of utility methods related to the user interface.
 *
 * @version 2.0
 * @since 1.0
 */
@SuppressWarnings("nls")
public class SWTUtil {

	/**
	 * Causes the <code>run()</code> method of the given runnable to be invoked
	 * by the user-interface thread at the next reasonable opportunity. The caller
	 * of this method continues to run in parallel, and is not notified when the
	 * runnable has completed.
	 *
	 * @param runnable Code to run on the user-interface thread
	 * @exception org.eclipse.swt.SWTException
	 * <ul>
	 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
	 * </ul>
	 * @see #syncExec
	 */
	public static void asyncExec(Runnable runnable) {
		getStandardDisplay().asyncExec(runnable);
	}

	/**
	 * Tweaks the given <code>CCombo</code> to remove the default value when the
	 * widget receives the focus and to show the default when the widget loses
	 * the focus.
	 *
	 * @param combo The widget having a default value that is always at the
	 * beginning of the list
	 */
	public static void attachDefaultValueHandler(CCombo combo) {
		CComboHandler handler = new CComboHandler();
		combo.addFocusListener(handler);
		combo.addModifyListener(handler);
	}

	/**
	 * Tweaks the given <code>Combo</code> to remove the default value when the
	 * widget receives the focus and to show the default when the widget loses
	 * the focus.
	 *
	 * @param combo The widget having a default value that is always at the
	 * beginning of the list
	 */
	public static void attachDefaultValueHandler(Combo combo) {
		ComboHandler handler = new ComboHandler();
		combo.addFocusListener(handler);
		combo.addModifyListener(handler);
	}

	/**
	 * Retrieves the localized string from the given NLS class by creating the
	 * key. That key is the concatenation of the composite's short class name
	 * with the toString() of the given value separated by an underscore.
	 *
	 * @param nlsClass The NLS class used to retrieve the localized text
	 * @param compositeClass The class used for creating the key, its short class
	 * name is the beginning of the key
	 * @param value The value used to append its toString() to the generated key
	 * @return The localized text associated with the value
	 */
	public static String buildDisplayString(Class<?> nlsClass,
	                                        Class<?> compositeClass,
	                                        Object value) {

		StringBuilder sb = new StringBuilder();
		sb.append(compositeClass.getSimpleName());
		sb.append("_");
		sb.append(value.toString().toLowerCase(Locale.ENGLISH));//bug 234953
		//TODO in a future release we should not be converting the key using toLowerCase()

		return (String) ReflectionTools.getStaticFieldValue(nlsClass, sb.toString());
	}

	/**
	 * Retrieves the localized string from the given NLS class by creating the
	 * key. That key is the concatenation of the composite's short class name
	 * with the toString() of the given value separated by an underscore.
	 *
	 * @param nlsClass The NLS class used to retrieve the localized text
	 * @param composite The object used to retrieve the short class name that is
	 * the beginning of the key
	 * @param value The value used to append its toString() to the generated key
	 * @return The localized text associated with the value
	 */
	public static final String buildDisplayString(Class<?> nlsClass,
	                                              Object composite,
	                                              Object value) {

		return buildDisplayString(nlsClass, composite.getClass(), value);
	}

	/**
	 * Creates the <code>Runnable</code> that will invoke the given
	 * <code>PostExecution</code> in order to its execution to be done in the
	 * UI thread.
	 *
	 * @param dialog The dialog that was just diposed
	 * @param postExecution The post execution once the dialog is disposed
	 * @return The <code>Runnable</code> that will invoke
	 * {@link PostExecution#execute(Dialog)}
	 */
	@SuppressWarnings("unchecked")
	private static <D1 extends Dialog, D2 extends D1>
		Runnable buildPostExecutionRunnable(
			final D1 dialog,
			final PostExecution<D2> postExecution) {

		return new Runnable() {
			public void run() {
				setUserInterfaceActive(false);
				try {
					postExecution.execute((D2) dialog);
				}
				finally {
					setUserInterfaceActive(true);
				}
			}
		};
	}

	/**
	 * Convenience method for getting the current shell. If the current thread is
	 * not the UI thread, then an invalid thread access exception will be thrown.
	 *
	 * @return The shell, never <code>null</code>
	 */
	public static Shell getShell() {

		// Retrieve the active shell, which can be the shell from any window
		Shell shell = getStandardDisplay().getActiveShell();

		// No shell could be found, revert back to the active workbench window
		if (shell == null) {
			shell = getWorkbench().getActiveWorkbenchWindow().getShell();
		}

		// Make sure it's never null
		if (shell == null) {
			shell = new Shell(getStandardDisplay().getActiveShell());
		}

		return shell;
	}

	/**
	 * Returns the standard display to be used. The method first checks, if the
	 * thread calling this method has an associated display. If so, this display
	 * is returned. Otherwise the method returns the default display.
	 *
	 * @return The current display if not <code>null</code> otherwise the default
	 * display is returned
	 */
	public static Display getStandardDisplay()
	{
		Display display = Display.getCurrent();

		if (display == null) {
			display = Display.getDefault();
		}

		return display;
	}

	public static int getTableHeightHint(Table table, int rows) {
		if (table.getFont().equals(JFaceResources.getDefaultFont()))
			table.setFont(JFaceResources.getDialogFont());
		int result= table.getItemHeight() * rows + table.getHeaderHeight();
		if (table.getLinesVisible())
			result+= table.getGridLineWidth() * (rows - 1);
		return result;
	}

   /**
	 * Returns the Platform UI workbench.
	 *
	 * @return The workbench for this plug-in
	 */
	public static IWorkbench getWorkbench() {
		return PlatformUI.getWorkbench();
	}

	/**
	 * Relays out the parents of the <code>Control</code>. This was taken from
	 * the widget <code>Section</code>.
	 *
	 * @param pane The pane to revalidate as well as its parents
	 */
	public static void reflow(Composite pane) {

		for (Composite composite = pane; composite != null; ) {
			composite.setRedraw(false);
			composite = composite.getParent();

			if (composite instanceof ScrolledForm || composite instanceof Shell) {
				break;
			}
		}

		for (Composite composite = pane; composite != null; ) {
			composite.layout(true);
			composite = composite.getParent();

			if (composite instanceof ScrolledForm) {
				((ScrolledForm) composite).reflow(true);
				break;
			}
		}

		for (Composite composite = pane; composite != null; ) {
			composite.setRedraw(true);
			composite = composite.getParent();

			if (composite instanceof ScrolledForm || composite instanceof Shell) {
				break;
			}
		}
	}

	/**
	 * Sets whether the entire shell and its widgets should be enabled or
	 * everything should be unaccessible.
	 *
	 * @param active <code>true</code> to make all the UI active otherwise
	 * <code>false</code> to deactivate it
	 */
	public static void setUserInterfaceActive(boolean active) {
		Shell[] shells = getStandardDisplay().getShells();

		for (Shell shell : shells) {
			shell.setEnabled(active);
		}
	}

	/**
	 * Asynchronously launches the specified dialog in the UI thread.
	 *
	 * @param dialog The dialog to show on screen
	 * @param postExecution This interface let the caller to invoke a piece of
	 * code once the dialog is disposed
	 */
	public static <D1 extends Dialog, D2 extends D1>
		void show(final D1 dialog, final PostExecution<D2> postExecution) {

		try {
			Assert.isNotNull(dialog,        "The dialog cannot be null");
			Assert.isNotNull(postExecution, "The PostExecution cannot be null");
		}
		catch (AssertionFailedException e) {
			// Make sure the UI is interactive
			setUserInterfaceActive(true);
			throw e;
		}

		new Thread() {
			@Override
			public void run() {
				asyncExec(
					new Runnable() { public void run() {
						showImp(dialog, postExecution);
					}
				}
			);
		}}.start();
	}

	/**
	 * Asynchronously launches the specified dialog in the UI thread.
	 *
	 * @param dialog The dialog to show on screen
	 */
	public static void show(Dialog dialog) {
		show(dialog, NullPostExecution.<Dialog>instance());
	}

	/**
	 * Asynchronously launches the specified dialog in the UI thread.
	 *
	 * @param dialog The dialog to show on screen
	 * @param postExecution This interface let the caller to invoke a piece of
	 * code once the dialog is disposed
	 */
	private static <D1 extends Dialog, D2 extends D1>
		void showImp(D1 dialog, PostExecution<D2> postExecution) {

		setUserInterfaceActive(true);
		dialog.open();

		if (postExecution != NullPostExecution.<D2>instance()) {
			asyncExec(buildPostExecutionRunnable(dialog, postExecution));
		}
	}

	/**
	 * Causes the <code>run()</code> method of the given runnable to be invoked
	 * by the user-interface thread at the next reasonable opportunity. The
	 * thread which calls this method is suspended until the runnable completes.
	 *
	 * @param runnable code to run on the user-interface thread.
	 * @see #asyncExec
	 */
	public static void syncExec(Runnable runnable) {
		getStandardDisplay().syncExec(runnable);
	}

	/**
	 * Determines if the current thread is the UI event thread.
	 *
	 * @return <code>true</code> if it's the UI event thread, <code>false</code>
	 * otherwise
	 */
	public static boolean uiThread() {
		return getStandardDisplay().getThread() == Thread.currentThread();
	}

	/**
	 * Determines if the current thread is the UI event thread by using the
	 * thread from which the given viewer's display was instantiated.
	 *
	 * @param viewer The viewer used to determine if the current thread
	 * is the UI event thread
	 * @return <code>true</code> if the current thread is the UI event thread;
	 * <code>false</code> otherwise
	 */
	public static boolean uiThread(Viewer viewer) {
		return uiThread(viewer.getControl());
	}

	/**
	 * Determines if the current thread is the UI event thread by using the
	 * thread from which the given widget's display was instantiated.
	 *
	 * @param widget The widget used to determine if the current thread
	 * is the UI event thread
	 * @return <code>true</code> if the current thread is the UI event thread;
	 * <code>false</code> otherwise
	 */
	public static boolean uiThread(Widget widget) {
		return widget.getDisplay().getThread() == Thread.currentThread();
	}

	/**
	 * This handler is responsible for removing the default value when the combo
	 * has the focus or when the selected item is the default value and to select
	 * it when the combo loses the focus.
	 */
	private static class CComboHandler implements ModifyListener,
	                                              FocusListener {


		public void focusGained(FocusEvent e) {
			CCombo combo = (CCombo) e.widget;
			
			if (combo.getSelectionIndex() == 0) {
				// The text selection has to be changed outside of the context of this
				// listener otherwise the combo won't update because it's currently
				// notifying its listeners
				asyncExec(new SelectText(combo));
			}
		}

		public void focusLost(FocusEvent e) {
			//do nothing
		}

		public void modifyText(ModifyEvent e) {

			CCombo combo = (CCombo) e.widget;

			if (combo.isFocusControl() &&
			    combo.getSelectionIndex() <= 0) {

				// Make sure the current text is the default value
				String currentValue = combo.getText();

				if (currentValue.length() > 0 &&
				    combo.getItemCount()  > 0 &&
				    !currentValue.equals(combo.getItem(0))) {

					return;
				}

				// The text has to be changed outside of the context of this
				// listener otherwise the combo won't update because it's currently
				// notifying its listeners
				asyncExec(new ModifyText(combo));
			}
		}
		
		private class SelectText implements Runnable {
			private final CCombo combo;

			public SelectText(CCombo combo) {
				super();
				this.combo = combo;
			}

			public void run() {
				if (this.combo.isDisposed()) {
					return;
				}
				String text = this.combo.getText();
				this.combo.setSelection(new Point(0, text.length()));
			}
		}

		private class ModifyText implements Runnable {
			private final CCombo combo;

			public ModifyText(CCombo combo) {
				super();
				this.combo = combo;
			}

			public void run() {
				if (this.combo.isDisposed()) {
					return;
				}
				String text = this.combo.getText();

				if (text.length() == 0) {
					text = this.combo.getItem(0);
					this.combo.setText(text);
				}

				this.combo.setSelection(new Point(0, text.length()));
			}
		}
	}

	/**
	 * This handler is responsible for removing the default value when the combo
	 * has the focus or when the selected item is the default value and to select
	 * it when the combo loses the focus.
	 */
	private static class ComboHandler implements ModifyListener,
	                                             FocusListener {

		public void focusGained(FocusEvent e) {
			Combo combo = (Combo) e.widget;

			if (combo.getSelectionIndex() == 0) {	
				// The text selection has to be changed outside of the context of this
				// listener otherwise the combo won't update because it's currently
				// notifying its listeners
				asyncExec(new SelectText(combo));
			}
		}

		public void focusLost(FocusEvent e) {
			//do nothing
		}

		public void modifyText(ModifyEvent e) {

			Combo combo = (Combo) e.widget;

			if (combo.isFocusControl() &&
			    combo.getSelectionIndex() == 0) {

				// The text has to be changed outside of the context of this
				// listener otherwise the combo won't update because it's currently
				// notifying its listeners
				asyncExec(new ModifyText(combo));
			}
		}

		private class ModifyText implements Runnable {
			private final Combo combo;

			public ModifyText(Combo combo) {
				super();
				this.combo = combo;
			}

			public void run() {
				if (this.combo.isDisposed()) {
					return;
				}
				String text = this.combo.getText();

				if (text.length() == 0) {
					text = this.combo.getItem(0);
					this.combo.setText(text);
				}

				this.combo.setSelection(new Point(0, text.length()));
			}
		}

		private class SelectText implements Runnable {
			private final Combo combo;

			public SelectText(Combo combo) {
				super();
				this.combo = combo;
			}

			public void run() {
				if (this.combo.isDisposed()) {
					return;
				}
				String text = this.combo.getText();
				this.combo.setSelection(new Point(0, text.length()));
			}
		}
	}
}