/*******************************************************************************
 * Copyright (c) 2006, 2009 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.wizards;

import java.util.EventListener;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.jpt.common.utility.internal.ListenerList;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.core.JpaProject;
import org.eclipse.jpt.jpa.db.ConnectionAdapter;
import org.eclipse.jpt.jpa.db.ConnectionListener;
import org.eclipse.jpt.jpa.db.ConnectionProfile;
import org.eclipse.jpt.jpa.db.Schema;
import org.eclipse.jpt.jpa.db.SchemaContainer;
import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
import org.eclipse.jpt.ui.internal.JptUiMessages;
import org.eclipse.jpt.ui.internal.properties.JpaProjectPropertiesPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil;

/**
 * Most of the behavior is in DatabaseGroup....
 * 
 * We open the wizard page with the JPA project's connection profile and
 * default schema selected (if possible), but then the selections are driven
 * by the user. If the user re-selects the JPA project's connection profile,
 * we will pre-select the project's default schema if possible.
 */
public class DatabaseSchemaWizardPage extends WizardPage {

	final JpaProject jpaProject;

	private final ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);

	private DatabaseGroup databaseGroup;


	public DatabaseSchemaWizardPage(JpaProject jpaProject) {
		super("Database Schema"); //$NON-NLS-1$
		if (jpaProject == null) {
			throw new NullPointerException();
		}
		this.jpaProject = jpaProject;
		this.setTitle(JptUiMessages.DatabaseSchemaWizardPage_title);
		this.setMessage(JptUiMessages.DatabaseSchemaWizardPage_desc);
	}

	public void createControl(Composite parent) {
		this.setPageComplete(false);
		this.setControl(this.buildTopLevelControl(parent));
	}

	private Control buildTopLevelControl(Composite parent) {
		Composite composite = new Composite(parent, SWT.NULL);
		composite.setLayout(new GridLayout());
		this.databaseGroup = new DatabaseGroup(composite);
		Dialog.applyDialogFont(parent);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, JpaHelpContextIds.PROPERTIES_JAVA_PERSISTENCE_CONNECTION);
		return composite;
	}

	public ConnectionProfile getJpaProjectConnectionProfile() {
		return this.jpaProject.getConnectionProfile();
	}
	
	public Schema getSelectedSchema() {
		return this.databaseGroup.getSelectedSchema();
	}

	@Override
	public void dispose() {
		this.databaseGroup.dispose();
		super.dispose();
	}


	// ********** listeners **********

	public void addListener(Listener listener) {
		this.listenerList.add(listener);
	}

	public void removeListener(Listener listener) {
		this.listenerList.remove(listener);
	}

	void fireSchemaChanged(Schema schema) {
		this.setPageComplete(schema != null);
		for (Listener listener : this.listenerList.getListeners()) {
			listener.selectedSchemaChanged(schema);
		}
	}


	// ********** listener interface **********

	/**
	 * Allows clients to listen for changes to the selected connection profile
	 * and schema.
	 */
	public interface Listener extends EventListener {
		void selectedSchemaChanged(Schema schema);
	}


	// ********** database group **********

	/**
	 * schema combo-box
	 * add project connection link
	 * reconnect link
	 */
	class DatabaseGroup {

		// these are kept in synch with the selection
		private Schema selectedSchema;

		private final Combo schemaComboBox;

		private final Link reconnectLink;

		private Link addJpaProjectConnectionLink;
		
		private final ConnectionListener connectionListener;


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

		DatabaseGroup(Composite composite) {
			super();

			Group group = new Group(composite, SWT.NONE);
			group.setLayout(new GridLayout(2, false));  // false = do not make columns equal width
			group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			group.setText(JptUiMessages.DatabaseSchemaWizardPage_schemaSettings);
			// TODO PlatformUI.getWorkbench().getHelpSystem().setHelp(this.group, JpaHelpContextIds.XXX);

			// schema combo-box
			this.buildLabel(group, 1, JptUiMessages.DatabaseSchemaWizardPage_schema);
			this.schemaComboBox = this.buildComboBox(group, this.buildSchemaComboBoxSelectionListener());
			
			String message = (this.projectHasAConnection()) ?
				JptUiMessages.DatabaseSchemaWizardPage_schemaInfo :
				JptUiMessages.DatabaseSchemaWizardPage_connectionInfo;
			
			this.buildLabel(group, 2, message);

			// add project's connection link
			if( ! this.projectHasAConnection()) {
				this.addJpaProjectConnectionLink = this.buildLink(group, 
							JptUiMessages.DatabaseSchemaWizardPage_addConnectionToProject, 
							this.buildAddJpaProjectConnectionLinkListener());
			}

			// reconnect link
			this.reconnectLink = this.buildLink(group, JptUiMessages.DatabaseSchemaWizardPage_connectLink, this.buildReconnectLinkSelectionListener());
			this.reconnectLink.setEnabled(true);

			this.selectedSchema = this.getDefaultSchema();

			if (this.selectedSchema != null) {
				DatabaseSchemaWizardPage.this.fireSchemaChanged(this.selectedSchema);
			}

			this.connectionListener = this.buildConnectionListener();
			this.addJpaProjectConnectionProfileListener(this.connectionListener);

			this.updateSchemaComboBox();
			this.updateReconnectLink();
		}


		// ********** intra-wizard methods **********

		Schema getSelectedSchema() {
			return this.selectedSchema;
		}

		void dispose() {
			if(this.projectHasAConnection()) {
				this.getJpaProjectConnectionProfile().removeConnectionListener(this.connectionListener);
			}
		}


		// ********** internal methods **********

		void addJpaProjectConnectionListener() {
			this.addJpaProjectConnectionProfileListener(this.connectionListener);
		}
		
		
		private void addJpaProjectConnectionProfileListener(ConnectionListener listener) {
			if(this.projectHasAConnection()) {
				this.getJpaProjectConnectionProfile().addConnectionListener(listener);
			}
		}

		private boolean projectHasAConnection() {
			return this.getJpaProjectConnectionProfile() != null;
		}
		
		/**
		 * this can return null;
		 * called at start-up and when the selected connection profile changes
		 */
		private ConnectionProfile getJpaProjectConnectionProfile() {
			return DatabaseSchemaWizardPage.this.jpaProject.getConnectionProfile();
		}

		/**
		 * this can return null;
		 * called at start-up and when the selected connection profile changes
		 */
		private Schema getDefaultSchema() {
			return DatabaseSchemaWizardPage.this.jpaProject.getDefaultDbSchema();
		}

		private SchemaContainer getDefaultSchemaContainer() {
			return DatabaseSchemaWizardPage.this.jpaProject.getDefaultDbSchemaContainer();
		}

		/**
		 * called at start-up and when the selected connection profile changes
		 */
		private void updateReconnectLink() {
			this.reconnectLink.setEnabled(this.reconnectLinkCanBeEnabled());
		}

		void updateAddJpaProjectConnectionLink() {
			this.addJpaProjectConnectionLink.setEnabled(this.addJpaProjectConnectionLinkCanBeEnabled());
		}

		private boolean reconnectLinkCanBeEnabled() {
			if(this.projectHasAConnection()) {
				return this.getJpaProjectConnectionProfile().isInactive();
			}
			return false;
		}

		private boolean addJpaProjectConnectionLinkCanBeEnabled() {
			return ! this.projectHasAConnection();
		}

		/**
		 * the schema combo-box is updated at start-up and
		 * when the selected connection profile changes
		 */
		private void updateSchemaComboBox() {
			this.schemaComboBox.removeAll();
			for (String name : this.getSchemaNames()) {
				this.schemaComboBox.add(name);
			}
			// the current schema *should* be in the current connection profile
			if (this.selectedSchema != null) {
				this.schemaComboBox.select(this.schemaComboBox.indexOf(this.selectedSchema.getName()));
			}
		}

		private Iterable<String> getSchemaNames() {
			SchemaContainer sc = this.getDefaultSchemaContainer();
			// use schema *names* since the combo-box is read-only
			return (sc != null) ? sc.getSortedSchemaNames() : EmptyIterable.<String>instance();
		}

		// ********** listener callbacks **********

		void selectedSchemaChanged() {
			Schema old = this.selectedSchema;
			this.selectedSchema = this.getDefaultSchemaContainer().getSchemaNamed(this.schemaComboBox.getText());
			if (this.selectedSchema != old) {
				DatabaseSchemaWizardPage.this.fireSchemaChanged(this.selectedSchema);
			}
		}

		void reconnect() {
			this.getJpaProjectConnectionProfile().connect();
			// everything should be synchronized when we get the resulting open event
		}

		/**
		 * called when
		 *     - a connection is set to the Jpa project
		 *     - the connection was opened
		 *     - the connection was closed (never happens?)
		 * we need to update the schema stuff and the reconnect link
		 */
		void connectionChanged() {
			Schema old = this.selectedSchema;
			this.selectedSchema = this.getDefaultSchema();
			if (this.selectedSchema != old) {
				DatabaseSchemaWizardPage.this.fireSchemaChanged(this.selectedSchema);
			}
			this.updateSchemaComboBox();
			this.updateReconnectLink();
		}


		// ********** listeners **********

		private SelectionListener buildSchemaComboBoxSelectionListener() {
			return new SelectionListener() {
				public void widgetDefaultSelected(SelectionEvent event) {
					// nothing special for "default" (double-click?)
					this.widgetSelected(event);
				}
				public void widgetSelected(SelectionEvent event) {
					DatabaseGroup.this.selectedSchemaChanged();
				}
				@Override
				public String toString() {
					return "DatabaseSchemaWizardPage schema combo-box selection listener"; //$NON-NLS-1$
				}
			};
		}

		private SelectionListener buildReconnectLinkSelectionListener() {
			return new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent event) {
					DatabaseGroup.this.reconnect();
				}
				@Override
				public String toString() {
					return "DatabaseSchemaWizardPage reconnect link selection listener"; //$NON-NLS-1$
				}
			};
		}

		private ConnectionListener buildConnectionListener() {
			return new ConnectionAdapter() {
				@Override
				public void opened(ConnectionProfile cp) {
					this.connectionChanged();
				}
				@Override  // this probably won't ever get called...
				public void closed(ConnectionProfile cp) {
					this.connectionChanged();
				}
				private void connectionChanged() {
					Display.getDefault().asyncExec(
						new Runnable() {
							public void run() {
								DatabaseGroup.this.connectionChanged();
							}
						}
					);
				}
				@Override
				public String toString() {
					return "DatabaseSchemaWizardPage connection listener"; //$NON-NLS-1$
				}
			};
		}

		private SelectionListener buildAddJpaProjectConnectionLinkListener() {
			return new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					DatabaseGroup.this.promptToConfigJpaProjectConnection();
					
					DatabaseGroup.this.addJpaProjectConnectionListener();
					DatabaseGroup.this.updateAddJpaProjectConnectionLink();
					DatabaseGroup.this.connectionChanged();
				}
				@Override
				public String toString() {
					return "DatabaseSchemaWizardPage AddProjectConnection link selection listener"; //$NON-NLS-1$
				}
			};
		}

		void promptToConfigJpaProjectConnection() {
			PreferenceDialog dialog =
				PreferencesUtil.createPropertyDialogOn(
					getShell(), DatabaseSchemaWizardPage.this.jpaProject.getProject(),
					JpaProjectPropertiesPage.PROP_ID,
					null,
					null);
			dialog.open();
		}

		// ********** UI components **********

		/**
		 * build and return a label
		 */
		private Label buildLabel(Composite parent, int span, String text) {
			Label label = new Label(parent, SWT.NONE);
			label.setText(text);
			GridData gd = new GridData();
			gd.horizontalSpan = span;
			label.setLayoutData(gd);
			return label;
		}

		/**
		 * build and return a combo-box
		 */
		private Combo buildComboBox(Composite parent, SelectionListener listener) {
			Combo combo = new Combo(parent, SWT.BORDER | SWT.READ_ONLY);
			combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			combo.addSelectionListener(listener);
			return combo;
		}

		/**
		 * build and return a link
		 */
		private Link buildLink(Composite parent, String text, SelectionListener listener) {
			Link link = new Link(parent, SWT.NONE);
			GridData data = new GridData(GridData.END, GridData.CENTER, false, false);
			data.horizontalSpan = 2;
			link.setLayoutData(data);
			link.setText(text);
			link.addSelectionListener(listener);
			return link;
		}

	}

}
