/*******************************************************************************
 * Copyright (c) 2006, 2012 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.jpa.ui;

import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jpt.common.utility.internal.AbstractBooleanReference;
import org.eclipse.jpt.jpa.core.JpaProjectManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

/**
 * Dali UI plug-in.
 * <p>
 * Provisional API: This interface is part of an interim API that is still
 * under development and expected to change significantly before reaching
 * stability. It is available at this early stage to solicit feedback from
 * pioneering adopters on the understanding that any code that uses this API
 * will almost certainly be broken (repeatedly) as the API evolves.
 */
@SuppressWarnings("nls")
public class JptJpaUiPlugin
	extends AbstractUIPlugin
{
	/**
	 * @see #focusIn(Control)
	 */
	private final AsyncEventListenerFlag asyncEventListenerFlag = new AsyncEventListenerFlag();
	private final Listener focusListener;


	// ********** constants **********

	/**
	 * The plug-in identifier of JPA UI support (value {@value}).
	 */
	public static final String PLUGIN_ID = "org.eclipse.jpt.jpa.ui";
	public static final String PLUGIN_ID_ = PLUGIN_ID + '.';

	private static final String DALI_UI_KEY = PLUGIN_ID;
	private static final Object DALI_UI_DATA = new Object();


	// ********** Preference keys **********

	/**
	 * The preference key used to retrieve the case used for JPQL identifiers.
	 */
	public static final String JPQL_IDENTIFIER_CASE_PREF_KEY = PLUGIN_ID + ".jpqlIdentifier.case";
	public static final String JPQL_IDENTIFIER_LOWERCASE_PREF_VALUE = "lowercase";
	public static final String JPQL_IDENTIFIER_UPPERCASE_PREF_VALUE = "uppercase";
	public static final String JPQL_IDENTIFIER_MATCH_FIRST_CHARACTER_CASE_PREF_KEY = PLUGIN_ID + ".jpqlIdentifier.matchFirstCharacterCase";


	// ********** singleton **********

	private static JptJpaUiPlugin INSTANCE;

	/**
	 * Returns the singleton JPT UI plug-in.
	 */
	public static JptJpaUiPlugin instance() {
		return INSTANCE;
	}


	// ********** logging **********

	/**
	 * Log the specified message.
	 */
	public static void log(String msg) {
        log(msg, null);
    }

	/**
	 * Log the specified exception or error.
	 */
	public static void log(Throwable throwable) {
		log(throwable.getLocalizedMessage(), throwable);
	}

	/**
	 * Log the specified message and exception or error.
	 */
	public static void log(String msg, Throwable throwable) {
		log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, msg, throwable));
	}

	/**
	 * Log the specified status.
	 */
	public static void log(IStatus status) {
        INSTANCE.getLog().log(status);
    }


	// ********** images **********

	/**
	 * Return an image descriptor for the specified <code>.gif<code>
	 * file in the icons folder.
	 */
	public static ImageDescriptor getImageDescriptor(String key) {
		if ( ! key.startsWith("icons/")) {
			key = "icons/" + key;
		}
		if ( ! key.endsWith(".gif")) {
			key = key + ".gif";
		}
		return imageDescriptorFromPlugin(PLUGIN_ID, key);
	}

	/**
	 * Return an image for the specified <code>.gif<code>
	 * file in the icons folder.
	 */
	//TODO we are using the ImageRegistry here and storing all our icons for the life of the plugin,
	//which means until the workspace is closed.  This is better than before where we constantly
	//created new images. Bug 306437 is about cleaning this up and using Local Resource Managers
	//on our views so that closing the JPA perspective would mean our icons are disposed.
	public static Image getImage(String key) {
		ImageRegistry imageRegistry = instance().getImageRegistry();
		Image image = imageRegistry.get(key);
		if (image == null) {
			imageRegistry.put(key, getImageDescriptor(key));
			image = imageRegistry.get(key);
		}
		return image;
	}


	// ********** construction **********

	public JptJpaUiPlugin() {
		super();
		this.focusListener = this.buildFocusListener();
		if (INSTANCE != null) {
			throw new IllegalStateException();
		}
		INSTANCE = this;
	}

	/**
	 * We are registered to receive only {@link SWT#FocusIn} events
	 */
	private Listener buildFocusListener() {
		return new Listener() {
			public void handleEvent(Event event) {
				JptJpaUiPlugin.this.focusIn((Control) event.widget);
			}
		};
	}


	// ********** focus handling **********

	/**
	 * This method is called whenever a {@link SWT#FocusIn} event is generated.
	 * <p>
	 * If the control gaining focus is part of one the Dali composites
	 * (typically the JPA Details View), we deactivate the Dali Java change
	 * listener so we ignore any changes to the Java source code that probably
	 * originated from Dali. This means we will miss any changes to the Java
	 * source code that is caused by non-UI activity; but, we hope, these
	 * changes are unrelated to JPA annotations etc.
	 * <p>
	 * If the control gaining focus is <em>not</em> part of one of the Dali
	 * composites, we start listening to the Java change events again. This
	 * method is called whenever a non-Dali UI control gains the UI focus. When
	 * this happens we activate the Dali Java change listener so that we begin
	 * to keep the Dali model synchronized with the Java source code.
	 */
	/* CU private */ void focusIn(Control control) {
		this.asyncEventListenerFlag.setValue(this.controlIsNonDali(control));
	}

	/**
	 * Return whether the specified control is <em><b>neither</b></em>
	 * a Dali UI component <em><b>nor</b></em> contained by a Dali UI component.
	 */
	private boolean controlIsNonDali(Control control) {
		return ! this.controlIsDali(control);
	}

	/**
	 * Return whether the specified control, or any of its ancestors, is a Dali
	 * UI component.
	 * 
	 * @see #controlAffectsJavaSource(Control)
	 */
	private boolean controlIsDali(Control control) {
		while (control != null) {
			if (control.getData(DALI_UI_KEY) == DALI_UI_DATA) {
				return true;
			}
			control = control.getParent();
		}
		return false;
	}

	/**
	 * Tag the specified control so that whenever it (or any of its descendants)
	 * has the focus, the Dali model ignores any Java change events. This method
	 * is to be called when the control is first constructed.
	 * 
	 * @see #controlIsDali(Control)
	 */
	public void controlAffectsJavaSource(Control control) {
		control.setData(DALI_UI_KEY, DALI_UI_DATA);
	}


	// ********** plug-in implementation **********

	/**
	 * Register our SWT listener with the display so we receive notification
	 * of every "focus in" event.
	 */
	@Override
	public void start(BundleContext context) throws Exception {
		super.start(context);
		this.getJpaProjectManager().addAsyncEventListenerFlag(this.asyncEventListenerFlag);
		Display.getDefault().addFilter(SWT.FocusIn, this.focusListener);
	}

	private JpaProjectManager getJpaProjectManager() {
		return (JpaProjectManager) ResourcesPlugin.getWorkspace().getAdapter(JpaProjectManager.class);
	}

	/**
	 * Unregister our SWT listener with the display.
	 */
	@Override
	public void stop(BundleContext context) throws Exception {
		try {
			Display.getDefault().removeFilter(SWT.FocusIn, this.focusListener);
			this.getJpaProjectManager().removeAsyncEventListenerFlag(this.asyncEventListenerFlag);
		} finally {
			super.stop(context);
		}
	}


	/**
	 * This flag's value depends on the current thread. If the current thread is
	 * the background Java Reconciler thread, the flag's value is determined by
	 * the current UI focus (i.e. whether the focus is somewhere other than a
	 * Dali view); otherwise the flag's value is <code>true</code>.
	 * In other words, if a Dali view has the focus and a Java event is fired
	 * on the Java Reconciler thread, the event is ignored; if the event is
	 * fired on some other thread (typically synchronously on the Main thread),
	 * the event is forwarded to the JPA projects.
	 */
	/* CU private */ static class AsyncEventListenerFlag
		extends AbstractBooleanReference
	{
		private volatile boolean value = true;

		@SuppressWarnings("restriction")
		private static final String JAVA_RECONCILER_THREAD_NAME = org.eclipse.jdt.internal.ui.text.JavaReconciler.class.getName();

		AsyncEventListenerFlag() {
			super();
		}

		public boolean getValue() {
			if (Thread.currentThread().getName().equals(JAVA_RECONCILER_THREAD_NAME)) {
				return this.value;
			}
			return true;
		}

		public boolean setValue(boolean value) {
			boolean old = this.value;
			this.value = value;
			return old;
		}
	}
}
