/*******************************************************************************
 * 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.details.db;

import org.eclipse.jpt.core.JpaDataSource;
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.listeners.SWTConnectionListenerWrapper;
import org.eclipse.jpt.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
import org.eclipse.jpt.ui.internal.widgets.ComboPane;
import org.eclipse.jpt.ui.internal.widgets.Pane;
import org.eclipse.jpt.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
import org.eclipse.jpt.utility.model.value.PropertyValueModel;
import org.eclipse.swt.widgets.Composite;

/**
 * This abstract pane keeps a combo in sync with the database objects
 * when a connection is active.
 *
 * @see CatalogCombo
 * @see ColumnCombo
 * @see SchemaCombo
 * @see SequenceCombo
 * @see TableCombo
 */
@SuppressWarnings("nls")
public abstract class DatabaseObjectCombo<T extends JpaNode>
	extends ComboPane<T>
{
	/**
	 * The listener added to the <code>ConnectionProfile</code>.
	 * It keeps the combo in sync with the database metadata.
	 */
	private ConnectionListener connectionListener;
	
	private PropertyChangeListener connectionProfileListener;
	
	
	// ********** constructors **********
	
	protected DatabaseObjectCombo(
			Pane<? extends T> parentPane, 
			Composite parent) {
		
		super(parentPane, parent);
	}
	
	protected DatabaseObjectCombo(
			Pane<?> parentPane,
			PropertyValueModel<? extends T> subjectHolder,
			Composite parent) {
		
		super(parentPane, subjectHolder, parent);
	}
	
	protected DatabaseObjectCombo(
			PropertyValueModel<? extends T> subjectHolder,
			Composite parent,
			WidgetFactory widgetFactory) {
		
		super(subjectHolder, parent, widgetFactory);
	}
	
	
	// ********** initialization **********
	
	@Override
	protected void initialize() {
		super.initialize();
		this.connectionListener = this.buildConnectionListener();
		this.connectionProfileListener = this.buildConnectionProfileListener();
	}
	
	protected ConnectionListener buildConnectionListener() {
		return new SWTConnectionListenerWrapper(this.buildConnectionListener_());
	}
	
	protected ConnectionListener buildConnectionListener_() {
		return new LocalConnectionListener();
	}
	
	protected PropertyChangeListener buildConnectionProfileListener() {
		return new SWTPropertyChangeListenerWrapper(this.buildConnectionProfileListener_());
	}
	
	protected PropertyChangeListener buildConnectionProfileListener_() {
		return new PropertyChangeListener(){
		
			public void propertyChanged(PropertyChangeEvent event) {
				connectionProfileChanged(event);
			}
		};
	}
	
	protected void connectionProfileChanged(PropertyChangeEvent event) {
		if (event.getOldValue() != null) {
			((ConnectionProfile) event.getOldValue()).removeConnectionListener(this.connectionListener);
		}
		if (event.getNewValue() != null) {
			((ConnectionProfile) event.getNewValue()).addConnectionListener(this.connectionListener);			
		}
		this.repopulateComboBox();
	}
	
	
	// ********** overrides **********
	
	@Override
	protected void engageListeners_(T subject) {
		super.engageListeners_(subject);

		subject.getJpaProject().getDataSource().addPropertyChangeListener(JpaDataSource.CONNECTION_PROFILE_PROPERTY, this.connectionProfileListener);
		ConnectionProfile cp = subject.getJpaProject().getConnectionProfile();
		if (cp != null) {
			cp.addConnectionListener(this.connectionListener);
		}
	}
	
	@Override
	protected void disengageListeners_(T subject) {
		ConnectionProfile cp = subject.getJpaProject().getConnectionProfile();
		if (cp != null) {
			cp.removeConnectionListener(this.connectionListener);
		}
		subject.getJpaProject().getDataSource().removePropertyChangeListener(JpaDataSource.CONNECTION_PROFILE_PROPERTY, this.connectionProfileListener);

		super.disengageListeners_(subject);
	}
	
	@Override
	protected final Iterable<String> getValues() {
		return this.connectionProfileIsActive() ? this.getValues_() : EmptyIterable.<String>instance();
	}
	
	/**
	 * Called only when connection profile is active
	 */
	protected abstract Iterable<String> getValues_();
	
	
	// ********** convenience methods **********
	
	/**
	 * Return the subject's JPA project.
	 * Allow subclasses to override this method, so we can still get the JPA
	 * project even when the subject is null.
	 */
	protected JpaProject getJpaProject() {
		T subject = this.getSubject();
		return (subject == null) ? null : subject.getJpaProject();
	}
	
	/**
	 * Return the subject's connection profile.
	 */
	protected final ConnectionProfile getConnectionProfile() {
		JpaProject jpaProject = this.getJpaProject();
		return (jpaProject == null) ? null : jpaProject.getConnectionProfile();
	}
	
	/**
	 * Return whether the subject's connection profile is active.
	 */
	protected final boolean connectionProfileIsActive() {
		ConnectionProfile cp = this.getConnectionProfile();
		return (cp != null) && cp.isActive();
	}
	
	/**
	 * Returns the subject's database.
	 */
	protected final Database getDatabase() {
		ConnectionProfile cp = this.getConnectionProfile();
		return (cp == null) ? null : cp.getDatabase();
	}
	
	
	// ********** connection listener callbacks **********
	
	protected final void databaseChanged(Database database) {
		if ( ! this.comboBox.isDisposed()) {
			this.databaseChanged_(database);
		}
	}
	
	protected void databaseChanged_(@SuppressWarnings("unused") Database database) {
		// do nothing by default
	}
	
	protected final void catalogChanged(Catalog catalog) {
		if ( ! this.comboBox.isDisposed()) {
			this.catalogChanged_(catalog);
		}
	}
	
	protected void catalogChanged_(@SuppressWarnings("unused") Catalog catalog) {
		// do nothing by default
	}
	
	protected final void schemaChanged(Schema schema) {
		if ( ! this.comboBox.isDisposed()) {
			this.schemaChanged_(schema);
		}
	}
	
	protected void schemaChanged_(@SuppressWarnings("unused") Schema schema) {
		// do nothing by default
	}
	
	protected final void sequenceChanged(Sequence sequence) {
		if ( ! this.comboBox.isDisposed()) {
			this.sequenceChanged_(sequence);
		}
	}
	
	protected void sequenceChanged_(@SuppressWarnings("unused") Sequence sequence) {
		// do nothing by default
	}
	
	protected final void tableChanged(Table table) {
		if ( ! this.comboBox.isDisposed()) {
			this.tableChanged_(table);
		}
	}
	
	protected void tableChanged_(@SuppressWarnings("unused") Table table) {
		// do nothing by default
	}
	
	protected final void columnChanged(Column column) {
		if ( ! this.comboBox.isDisposed()) {
			this.columnChanged_(column);
		}
	}
	
	protected void columnChanged_(@SuppressWarnings("unused") Column column) {
		// do nothing by default
	}
	
	protected final void foreignKeyChanged(ForeignKey foreignKey) {
		if ( ! this.comboBox.isDisposed()) {
			this.foreignKeyChanged_(foreignKey);
		}
	}
	
	protected void foreignKeyChanged_(@SuppressWarnings("unused") ForeignKey foreignKey) {
		// do nothing by default
	}
	
	@Override
	protected void log(String flag, String message) {
		if (flag.equals(Tracing.UI_DB) && Tracing.booleanDebugOption(Tracing.UI_DB)) {
			this.log(message);
		} else {
			super.log(flag, message);
		}
	}

	// broaden accessibility a bit
	@Override
	protected void repopulateComboBox() {
		super.repopulateComboBox();
	}
	
	
	// ********** connection listener **********
	
	protected class LocalConnectionListener 
		implements ConnectionListener 
	{
		protected LocalConnectionListener() {
			super();
		}
		
		public void opened(ConnectionProfile profile) {
			this.log("opened: " + profile.getName());
			DatabaseObjectCombo.this.repopulateComboBox();
		}
		
		public void modified(ConnectionProfile profile) {
			this.log("modified: " + profile.getName());
			DatabaseObjectCombo.this.repopulateComboBox();
		}
		
		public boolean okToClose(ConnectionProfile profile) {
			this.log("OK to close: " + profile.getName());
			return true;
		}
		
		public void aboutToClose(ConnectionProfile profile) {
			this.log("about to close: " + profile.getName());
		}
		
		public void closed(ConnectionProfile profile) {
			this.log("closed: " + profile.getName());
			DatabaseObjectCombo.this.repopulateComboBox();
		}
		
		public void databaseChanged(ConnectionProfile profile, Database database) {
			this.log("database changed: " + database.getName());
			DatabaseObjectCombo.this.databaseChanged(database);
		}
		
		public void catalogChanged(ConnectionProfile profile, Catalog catalog) {
			this.log("catalog changed: " + catalog.getName());
			DatabaseObjectCombo.this.catalogChanged(catalog);
		}
		
		public void schemaChanged(ConnectionProfile profile, Schema schema) {
			this.log("schema changed: " + schema.getName());
			DatabaseObjectCombo.this.schemaChanged(schema);
		}
		
		public void sequenceChanged(ConnectionProfile profile, Sequence sequence) {
			this.log("sequence changed: " + sequence.getName());
			DatabaseObjectCombo.this.sequenceChanged(sequence);
		}
		
		public void tableChanged(ConnectionProfile profile, Table table) {
			this.log("table changed: " + table.getName());
			DatabaseObjectCombo.this.tableChanged(table);
		}
		
		public void columnChanged(ConnectionProfile profile, Column column) {
			this.log("column changed: " + column.getName());
			DatabaseObjectCombo.this.columnChanged(column);
		}
		
		public void foreignKeyChanged(ConnectionProfile profile, ForeignKey foreignKey) {
			this.log("foreign key changed: " + foreignKey.getName());
			DatabaseObjectCombo.this.foreignKeyChanged(foreignKey);
		}
		
		protected void log(String message) {
			DatabaseObjectCombo.this.log(Tracing.UI_DB, message);
		}
	}	
}
