/*******************************************************************************
 * Copyright (c) 2008 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.mappings.db;

import java.util.Iterator;
import org.eclipse.jpt.core.JpaNode;
import org.eclipse.jpt.core.JpaProject;
import org.eclipse.jpt.db.Catalog;
import org.eclipse.jpt.db.Column;
import org.eclipse.jpt.db.ConnectionListener;
import org.eclipse.jpt.db.ConnectionProfile;
import org.eclipse.jpt.db.Database;
import org.eclipse.jpt.db.ForeignKey;
import org.eclipse.jpt.db.Schema;
import org.eclipse.jpt.db.Sequence;
import org.eclipse.jpt.db.Table;
import org.eclipse.jpt.ui.WidgetFactory;
import org.eclipse.jpt.ui.internal.Tracing;
import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
import org.eclipse.jpt.ui.internal.util.SWTUtil;
import org.eclipse.jpt.ui.internal.widgets.AbstractPane;
import org.eclipse.jpt.utility.internal.ClassTools;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.model.value.PropertyValueModel;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;

/**
 * This abstract implementation keeps a combo in sync with the database objects
 * when a connection is active.
 *
 * @see CatalogCombo
 * @see ColumnCombo
 * @see SchemaCombo
 * @see TableCombo
 *
 * @version 2.0
 * @since 2.0
 */
@SuppressWarnings("nls")
public abstract class AbstractDatabaseObjectCombo<T extends JpaNode> extends AbstractPane<T>
{
	/**
	 * The main widget of this pane.
	 */
	private CCombo combo;

	/**
	 * The listener added to the <code>ConnectionProfile</code> responsible to
	 * keep the combo in sync with the database metadata.
	 */
	private ConnectionListener connectionListener;

	/**
	 * Creates a new <code>AbstractDatabaseObjectCombo</code>.
	 *
	 * @param parentPane The parent container of this one
	 * @param parent The parent container
	 */
	protected AbstractDatabaseObjectCombo(AbstractPane<? extends T> parentPane,
	                                      Composite parent) {

		super(parentPane, parent);
	}

	/**
	 * Creates a new <code>AbstractDatabaseObjectCombo</code>.
	 *
	 * @param parentPane The parent container of this one
	 * @param subjectHolder The holder of this pane's subject
	 * @param parent The parent container
	 */
	protected AbstractDatabaseObjectCombo(AbstractPane<?> parentPane,
	                                      PropertyValueModel<? extends T> subjectHolder,
	                                      Composite parent) {

		super(parentPane, subjectHolder, parent);
	}

	/**
	 * Creates a new <code>AbstractDatabaseObjectCombo</code>.
	 *
	 * @param subjectHolder The holder of the subject
	 * @param parent The parent container
	 * @param widgetFactory The factory used to create various common widgets
	 */
	protected AbstractDatabaseObjectCombo(PropertyValueModel<? extends T> subjectHolder,
	                                      Composite parent,
	                                      WidgetFactory widgetFactory)
	{
		super(subjectHolder, parent, widgetFactory);
	}

	private ConnectionListener buildConnectionListener() {

		return new ConnectionListener() {

			public void aboutToClose(ConnectionProfile profile) {
				log(Tracing.UI_DB, "aboutToClose");
			}

			public void catalogChanged(ConnectionProfile profile,
			                          final Catalog catalog) {

				SWTUtil.asyncExec(new Runnable() {
					public void run() {
						log(Tracing.UI_DB, "catalogChanged: " + catalog.getName());

						if (!getCombo().isDisposed()) {
							AbstractDatabaseObjectCombo.this.catalogChanged(catalog);
						}
					}
				});
			}

			public void closed(ConnectionProfile profile) {

				SWTUtil.asyncExec(new Runnable() {
					public void run() {
						log(Tracing.UI_DB, "closed");

						if (!getCombo().isDisposed()) {
							AbstractDatabaseObjectCombo.this.repopulate();
						}
					}
				});
			}

			public void columnChanged(ConnectionProfile profile,
			                         final Column column) {

				SWTUtil.asyncExec(new Runnable() {
					public void run() {
						log(Tracing.UI_DB, "columnChanged: " + column.getName());

						if (!getCombo().isDisposed()) {
							AbstractDatabaseObjectCombo.this.columnChanged(column);
						}
					}
				});
			}

			public void databaseChanged(ConnectionProfile profile,
			                            Database database) {

				log(Tracing.UI_DB, "databaseChanged");
			}

			public void foreignKeyChanged(ConnectionProfile profile,
			                         final ForeignKey foreignKey) {

				SWTUtil.asyncExec(new Runnable() {
					public void run() {
						log(Tracing.UI_DB, "foreignKeyChanged: " + foreignKey.getName());

						if (!getCombo().isDisposed()) {
							AbstractDatabaseObjectCombo.this.foreignKeyChanged(foreignKey);
						}
					}
				});
			}

			public void modified(ConnectionProfile profile) {
				SWTUtil.asyncExec(new Runnable() {
					public void run() {
						log(Tracing.UI_DB, "modified");

						if (!getCombo().isDisposed()) {
							AbstractDatabaseObjectCombo.this.repopulate();
						}
					}
				});
			}

			public boolean okToClose(ConnectionProfile profile) {
				log(Tracing.UI_DB, "okToClose");
				return true;
			}

			public void opened(ConnectionProfile profile) {

				SWTUtil.asyncExec(new Runnable() {
					public void run() {
						log(Tracing.UI_DB, "opened");

						if (!getCombo().isDisposed()) {
							AbstractDatabaseObjectCombo.this.repopulate();
						}
					}
				});
			}

			public void schemaChanged(ConnectionProfile profile,
			                          final Schema schema) {

				SWTUtil.asyncExec(new Runnable() {
					public void run() {
						log(Tracing.UI_DB, "schemaChanged: " + schema.getName());

						if (!getCombo().isDisposed()) {
							AbstractDatabaseObjectCombo.this.schemaChanged(schema);
						}
					}
				});
			}

			public void sequenceChanged(ConnectionProfile profile,
			                          final Sequence sequence) {

				SWTUtil.asyncExec(new Runnable() {
					public void run() {
						log(Tracing.UI_DB, "sequenceChanged: " + sequence.getName());

						if (!getCombo().isDisposed()) {
							AbstractDatabaseObjectCombo.this.sequenceChanged(sequence);
						}
					}
				});
			}

			public void tableChanged(ConnectionProfile profile,
			                         final Table table) {

				SWTUtil.asyncExec(new Runnable() {
					public void run() {
						log(Tracing.UI_DB, "tableChanged: " + table.getName());

						if (!getCombo().isDisposed()) {
							AbstractDatabaseObjectCombo.this.tableChanged(table);
						}
					}
				});
			}
		};
	}

	private ModifyListener buildModifyListener() {
		return new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				if (!isPopulating()) {
					CCombo combo = (CCombo) e.widget;
					if (combo.getData("populating") != Boolean.TRUE) {//check !TRUE because null is a possibility as well
						valueChanged(combo.getText());
					}
				}
			}
		};
	}

	/**
	 * If the value changes but the subject is null, then is invoked in order to
	 * create the subject.
	 */
	protected void buildSubject() {
	}

	/**
	 * The
	 *
	 * @param catalog
	 */
	protected void catalogChanged(Catalog catalog) {
	}

	/**
	 * Makes sure the combo shows nothing instead of the default value because
	 * the focus is still on the combo. The user can start typing something and
	 * we don't want to start the typing after the default value.
	 */
	private void clearDefaultValue() {

		if (this.combo.isFocusControl()) {

			setPopulating(true);

			try {
				combo.setText("");
			}
			finally {
				setPopulating(false);
			}
		}
	}

	/**
	 * The
	 *
	 * @param column
	 */
	protected void columnChanged(Column column) {
	}

	/**
	 * Returns the JPA project's connection profile, which is never
	 * <code>null</code>.
	 *
	 * @return The connection set in the project's properties or <code>null</code>
	 * if it could not being retrieved
	 */
	protected final ConnectionProfile connectionProfile() {
		JpaProject jpaProject = jpaProject();

		if (jpaProject != null) {
			return jpaProject.getConnectionProfile();
		}

		return null;
	}

	/**
	 * Returns the database associated with the active connection profile.
	 *
	 * @return The online database or a <code>null</code> instance if no
	 * connection profile was set or the
	 */
	protected final Database database() {
		return connectionProfile().getDatabase();
	}

	/**
	 * Returns the default value, or <code>null</code> if no default is
	 * specified.
	 *
	 * @return The value that represents the default when no value was specified
	 */
	protected abstract String defaultValue();

	/*
	 * (non-Javadoc)
	 */
	@Override
	protected void disengageListeners(T subject) {
		super.disengageListeners(subject);

		JpaProject jpaProject = jpaProject();

		if (jpaProject != null) {
			jpaProject.getConnectionProfile().removeConnectionListener(this.connectionListener);
		}
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	protected void doPopulate() {

		super.doPopulate();
		populateCombo();
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	public void enableWidgets(boolean enabled) {

		super.enableWidgets(enabled);

		if (!this.combo.isDisposed()) {
			this.combo.setEnabled(enabled);
		}
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	protected void engageListeners(T subject) {
		super.engageListeners(subject);

		JpaProject jpaProject = jpaProject();

		if (jpaProject != null) {
			jpaProject.getConnectionProfile().addConnectionListener(this.connectionListener);
		}
	}

	/**
	 * The
	 *
	 * @param foreignKey
	 */
	protected void foreignKeyChanged(ForeignKey foreignKey) {
	}

	public final CCombo getCombo() {
		return this.combo;
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	protected void initialize() {
		super.initialize();
		this.connectionListener = buildConnectionListener();
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	protected void initializeLayout(Composite container) {

		this.combo = buildEditableCCombo(container);
		this.combo.addModifyListener(buildModifyListener());
		SWTUtil.attachDefaultValueHandler(this.combo);
	}

	/**
	 * Determines if the subject should be created when the value changes.
	 *
	 * @return <code>false</code> is the default behavior
	 */
	protected boolean isBuildSubjectAllowed() {
		return false;
	}

	/**
	 * Retrives the <code>IJpaProject</code> that is required to register a
	 * <code>ConnectionListener</code> in order to keep the combo in sync with
	 * the associated online database.
	 *
	 * @return The JPA project
	 */
	protected JpaProject jpaProject() {
		return subject() == null ? null : subject().getJpaProject();
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	protected void log(String flag, String message) {

		super.log(flag, message);

		if (Tracing.UI_DB.equals(flag) &&
		    Tracing.booleanDebugOption(Tracing.UI_DB))
		{
			Class<?> thisClass = getClass();
			String className = ClassTools.shortNameFor(thisClass);

			if (thisClass.isAnonymousClass()) {
				className = className.substring(0, className.indexOf('$'));
				className += "->" + ClassTools.shortNameFor(thisClass.getSuperclass());
			}

			Tracing.log(className + ": " + message);
		}
	}

	/**
	 * Populates the combo's list by adding first the default value is available
	 * and then the possible choices.
	 */
	private void populateCombo() {

		combo.removeAll();
		populateDefaultValue();

		ConnectionProfile connectionProfile = connectionProfile();

		if ((connectionProfile != null) && connectionProfile.isActive()) {

			for (Iterator<String> iter = CollectionTools.sort(values()); iter.hasNext(); ) {
				combo.add(iter.next());
			}
		}

		updateSelectedItem();
	}

	/**
	 * Adds the default value to the combo if one exists.
	 */
	private void populateDefaultValue() {

		String defaultValue = (subject() != null) ? defaultValue() : null;

		if (defaultValue != null) {
			combo.add(NLS.bind(
				JptUiMappingsMessages.ColumnComposite_defaultWithOneParam,
				defaultValue
			));
		}
		else {
			combo.add(JptUiMappingsMessages.ColumnComposite_defaultEmpty);
		}
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	protected void propertyChanged(String propertyName) {
		super.propertyChanged(propertyName);
		updateSelectedItem();
	}

	/**
	 * The
	 *
	 * @param schema
	 */
	protected void schemaChanged(Schema schema) {
	}

	/**
	 * The
	 *
	 * @param sequence
	 */
	protected void sequenceChanged(Sequence sequence) {
	}

	/**
	 * Sets the given value as the new value.
	 *
	 * @param value The new value to send to the model object
	 */
	protected abstract void setValue(String value);

	/**
	 * The
	 *
	 * @param table
	 */
	protected void tableChanged(Table table) {
	}

	/**
	 * Updates the selected item by selected the current value, if not
	 * <code>null</code>, or select the default value if one is available,
	 * otherwise remove the selection.
	 * <p>
	 * <b>Note:</b> It seems the text can be shown as truncated, changing the
	 * selection to (0, 0) makes the entire text visible.
	 */
	private void updateSelectedItem() {

		T subject = subject();

		String value         = (subject != null) ? value()        : null;
		String defaultValue  = (subject != null) ? defaultValue() : null;
		String displayString = JptUiMappingsMessages.ColumnComposite_defaultEmpty;

		if (defaultValue != null) {
			displayString = NLS.bind(
				JptUiMappingsMessages.ColumnComposite_defaultWithOneParam,
				defaultValue
			);
		}

		// Make sure the default value is up to date
		if (!combo.getItem(0).equals(displayString)) {
			combo.remove(0);
			combo.add(displayString, 0);
		}

		// Select the new value
		if (value != null) {
			if (!value.equals(combo.getText())) {
				//this prevents the cursor from being set back to the beginning of the line (bug 234418).
				//The reason we are hitting this updateSelectedItem() code at all
				//is because the context model is  updating from the resource model
				//in a way that causes change notifications to be fired (the annotation is added 
				//to the resource model, change notification occurs on the update thread, 
				//and then the name is set, these 2 threads can get in the wrong order).
				//The valueChanged() method sets the populating flag to true, but in this case
				//it is already set back to false when we receive notification back from the model
				//because it has moved to the update thread and then jumps back on the UI thread.
				combo.setText(value);
			}
		}
		// Select the default value
		else {
			combo.select(0);
			
			//i think we can remove this, I don't believe the problem explained
			//in the comments of this method is happening anymore. Not removing it now because we are working on 2.0RC3
			combo.setSelection(new Point(0, 0));
		}
	}

	/**
	 * Requests the current value from the model object.
	 *
	 * @return The current value
	 */
	protected abstract String value();

	/**
	 * The selection has changed, update the model if required.
	 *
	 * @param value The new value
	 */
	protected void valueChanged(String value) {

		JpaNode subject = subject();

		if ((subject == null) && !isBuildSubjectAllowed()) {
			return;
		}

		String oldValue = (subject != null) ? value() : null;

		// Check for null value
		if (StringTools.stringIsEmpty(value)) {
			value = null;

			if (StringTools.stringIsEmpty(oldValue)) {
				return;
			}
		}

		// Convert the default value to null
		if (value != null &&
		    getCombo().getItemCount() > 0 &&
		    value.equals(getCombo().getItem(0)))
		{
			value = null;
		}

		// Nothing to change
		if ((oldValue == value) && value == null) {
			clearDefaultValue();
			return;
		}

		// Build the subject before setting the value
		if (subject == null) {
			buildSubject();
		}

		// Set the new value
		if ((value != null) && (oldValue == null) ||
		   ((oldValue != null) && !oldValue.equals(value))) {

			setPopulating(true);
			combo.setData("populating", Boolean.TRUE);

			try {
				setValue(value);
			}
			finally {
				setPopulating(false);
				combo.setData("populating", Boolean.FALSE);
			}

			if (value == null) {
				clearDefaultValue();
			}
		}
	}

	/**
	 * Retrieves the possible values, which will be added to the combo during
	 * population.
	 *
	 * @return A non-<code>null</code> <code>Iterator</code> of the possible
	 * choices to be added to the combo
	 */
	protected abstract Iterator<String> values();
}