/*******************************************************************************
 * Copyright (c) 2006, 2007 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.Collection;
import java.util.Collections;
import java.util.Iterator;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.jpt.core.internal.IJpaProject;
import org.eclipse.jpt.db.internal.Connection;
import org.eclipse.jpt.db.internal.ConnectionListener;
import org.eclipse.jpt.db.internal.ConnectionProfile;
import org.eclipse.jpt.db.internal.ConnectionProfileRepository;
import org.eclipse.jpt.db.internal.Database;
import org.eclipse.jpt.db.internal.JptDbPlugin;
import org.eclipse.jpt.db.internal.Schema;
import org.eclipse.jpt.db.internal.Table;
import org.eclipse.jpt.db.ui.internal.DTPUiTools;
import org.eclipse.jpt.ui.internal.IJpaHelpContextIds;
import org.eclipse.jpt.ui.internal.JptUiMessages;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.ui.PlatformUI;

public class DatabaseReconnectWizardPage extends WizardPage {
	private IJpaProject jpaProject;

	private Connection connection;
	private ConnectionListener connectionListener;
	private DatabaseGroup databaseGroup;

	public DatabaseReconnectWizardPage( IJpaProject jpaProject) {
		super( "Database Settings"); //$NON-NLS-1$
		this.jpaProject = jpaProject;
		setTitle( JptUiMessages.DatabaseReconnectWizardPage_databaseConnection);
		setMessage( JptUiMessages.DatabaseReconnectWizardPage_reconnectToDatabase);
	}

	public void createControl( Composite parent) {
		this.setPageComplete( false);
		Composite top = this.createTopLevelComposite( parent);
		this.setControl( top);
	}

	protected Composite createTopLevelComposite( Composite parent) {
		Composite composite = new Composite( parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		composite.setLayout( layout);
		this.databaseGroup = new DatabaseGroup( composite);
		Dialog.applyDialogFont( parent);
		// TODO Add Help - testing
		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJpaHelpContextIds.PROPERTIES_JAVA_PERSISTENCE_CONNECTION);
		return composite;
	}

	private Label createLabel( Composite container, int span, String text) {
		Label label = new Label( container, SWT.NONE);
		label.setText( text);
		GridData gd = new GridData();
		gd.horizontalIndent = 30;
		gd.horizontalSpan = span;
		label.setLayoutData( gd);
		return label;
	}

	private Combo createCombo( Composite container, boolean fillHorizontal) {
		Combo combo = new Combo( container, SWT.BORDER | SWT.SINGLE);
		if ( fillHorizontal) {
			combo.setLayoutData( new GridData( GridData.FILL_HORIZONTAL));
		}
		else {
			combo.setLayoutData( new GridData());
		}
		return combo;
	}

	/**
	 * Initialize a grid layout with the default Dialog settings.
	 */
	protected GridLayout initGridLayout( GridLayout layout, boolean margins) {
		layout.horizontalSpacing = this.convertHorizontalDLUsToPixels( IDialogConstants.HORIZONTAL_SPACING);
		layout.verticalSpacing = this.convertVerticalDLUsToPixels( IDialogConstants.VERTICAL_SPACING);
		if ( margins) {
			layout.marginWidth = this.convertHorizontalDLUsToPixels( IDialogConstants.HORIZONTAL_MARGIN);
			layout.marginHeight = this.convertVerticalDLUsToPixels( IDialogConstants.VERTICAL_MARGIN);
		}
		else {
			layout.marginWidth = 0;
			layout.marginHeight = 0;
		}
		return layout;
	}

	public Collection<Table> getTables() {
		Schema schema = this.getDefaultSchema();
		if ( schema != null && schema.getName() != null) {
			return CollectionTools.collection( schema.tables());
		}
		return Collections.<Table>emptyList();
	}

	private void updateGenerateEntitiesPage( Schema schema) {
		GenerateEntitiesWizard generateEntitiesWizard = (( GenerateEntitiesWizard) this.getWizard());
		generateEntitiesWizard.updatePossibleTables( CollectionTools.collection( schema.tables()));
	}

	public void dispose() {
		this.removeConnectionListener();
		super.dispose();
	}

	private void removeConnectionListener() {
		if ( this.connectionListener != null) {
			if ( this.connection != null) {
				this.connection.removeConnectionListener( this.connectionListener);
			}
			this.connectionListener = null;
		}
	}
	

	ConnectionProfile getProjectConnectionProfile() {
		String profileName = this.jpaProject.getDataSource().getConnectionProfileName();
		return JptDbPlugin.getDefault().getConnectionProfileRepository().profileNamed( profileName);
	}

	Schema getDefaultSchema() {
		ConnectionProfile profile = getProjectConnectionProfile();
		return profile.getDatabase().schemaNamed( profile.getDefaultSchema());
	}

	// ********** member classes **********

	private final class DatabaseGroup {
		private final Group group;
		private final Label connectionLabel;
		private final Combo connectionCombo;
		private final Label schemaLabel;
		private final Combo schemaCombo;
		private final Label schemaInfoLabel;
		
		private Link addConnectionLink;
		private Link reconnectLink;

		public DatabaseGroup( Composite composite) {
			this.group = new Group( composite, SWT.NONE);
			GridLayout layout = new GridLayout();
			layout.numColumns = 2;
			this.group.setLayout( layout);
			this.group.setLayoutData( new GridData( GridData.FILL_HORIZONTAL));
			this.group.setText( JptUiMessages.DatabaseReconnectWizardPage_database);
			//TODO Add Help
//			PlatformUI.getWorkbench().getHelpSystem().setHelp( this.group, IDaliHelpContextIds.XXX);
			this.connectionLabel = createLabel( this.group, 1, JptUiMessages.DatabaseReconnectWizardPage_connection);
			this.connectionCombo = createCombo( this.group, true);
			this.connectionCombo.addSelectionListener( new SelectionAdapter() {
				public void widgetDefaultSelected( SelectionEvent e) {
					widgetSelected( e);
				}

				public void widgetSelected( SelectionEvent e) {
					handleConnectionChange();
				}
			});
			this.schemaLabel = createLabel( this.group, 1, JptUiMessages.DatabaseReconnectWizardPage_schema);
			this.schemaCombo = createCombo( this.group, true);
			this.schemaCombo.addSelectionListener( new SelectionAdapter() {
				public void widgetDefaultSelected( SelectionEvent e) {
					widgetSelected( e);
				}

				public void widgetSelected( SelectionEvent e) {
					handleSchemaChange();
				}
			});
			schemaInfoLabel = createLabel( this.group, 2, JptUiMessages.DatabaseReconnectWizardPage_schemaInfo);
			this.addConnectionLink = new Link( this.group, SWT.NONE);
			GridData data = new GridData( GridData.END, GridData.CENTER, false, false);
			data.horizontalSpan = 2;
			this.addConnectionLink.setLayoutData( data);
			this.addConnectionLink.setText( JptUiMessages.DatabaseReconnectWizardPage_addConnectionLink);
			this.addConnectionLink.addSelectionListener( new SelectionAdapter() {
				public void widgetSelected( SelectionEvent e) {
					openNewConnectionWizard();
				}
			});
			this.reconnectLink = new Link( this.group, SWT.NONE);
			data = new GridData( GridData.END, GridData.CENTER, false, false);
			data.horizontalSpan = 2;
			this.reconnectLink.setLayoutData( data);
			this.reconnectLink.setText( JptUiMessages.DatabaseReconnectWizardPage_reconnectLink);
			this.reconnectLink.setEnabled( false);
			this.reconnectLink.addSelectionListener( new SelectionAdapter() {
				public void widgetSelected( SelectionEvent e) {
					openConnectionProfileNamed( connectionCombo.getText());
				}
			});
			this.populateConnectionCombo();
			this.populateSchemaCombo();
		}

		private ConnectionProfile getConnectionProfileNamed( String profileName) {
			return JptDbPlugin.getDefault().getConnectionProfileRepository().profileNamed( profileName);
		}
		
		private Iterator<String> dtpConnectionProfileNames() {
			return JptDbPlugin.getDefault().getConnectionProfileRepository().profileNames();
		}

		private String getProjectConnectionProfileName() {
			return jpaProject.getDataSource().getConnectionProfileName();
		}

		Schema getDefaultSchema() {
			ConnectionProfile profile = getProjectConnectionProfile();
			return profile.getDatabase().schemaNamed( profile.getDefaultSchema());
		}

		private void openConnectionProfileNamed( String connectionProfileName) {
			if( DatabaseReconnectWizardPage.this.connection != null) {
				DatabaseReconnectWizardPage.this.removeConnectionListener();
			}
			ConnectionProfile profile = JptDbPlugin.getDefault().getConnectionProfileRepository().profileNamed( connectionProfileName);
			profile.connect();
			DatabaseReconnectWizardPage.this.connection = profile.getConnection();
			if( DatabaseReconnectWizardPage.this.connection != null) {
				this.populateSchemaCombo();
				DatabaseReconnectWizardPage.this.connectionListener = this.buildConnectionListener();
				DatabaseReconnectWizardPage.this.connection.addConnectionListener( DatabaseReconnectWizardPage.this.connectionListener);
			}
			return;
		}
		
		private void populateConnectionCombo() {
			// clear out connection entries from previous login.
			this.connectionCombo.removeAll();
			for ( Iterator<String> i = CollectionTools.sort( this.dtpConnectionProfileNames()); i.hasNext();) {
				this.connectionCombo.add( ( String) i.next());
			}

			String connectionName = getProjectConnectionProfileName();
			if ( !StringTools.stringIsEmpty( connectionName)) {
				this.connectionCombo.select( connectionCombo.indexOf( connectionName));
				this.reconnectLink.setEnabled( true);
			}
		}

		private void handleConnectionChange() {
			this.reconnectLink.setEnabled( true);
			this.populateSchemaCombo();
		}

		private void handleSchemaChange() {
			ConnectionProfile connectionProfile = this.getConnectionProfileNamed( getConnectionProfileName());
			Schema schema =  connectionProfile.getDatabase().schemaNamed( this.getSchemaName());
			DatabaseReconnectWizardPage.this.updateGenerateEntitiesPage( schema);
			DatabaseReconnectWizardPage.this.setPageComplete( true);
		}

		private void populateSchemaCombo() {
			// clear out schema entries from previous connection selection
			this.schemaCombo.removeAll();
			ConnectionProfile connectionProfile = this.getConnectionProfileNamed( getConnectionProfileName());
			for ( Iterator<String> stream = CollectionTools.sort( connectionProfile.getDatabase().schemaNames()); stream.hasNext();) {
				this.schemaCombo.add( ( String) stream.next());
			}
			// set login user name as default schema
			Schema schema = this.getDefaultSchema();
			if ( schema != null && schema.getName() != null) {
				schema =  connectionProfile.getDatabase().schemaNamed( schema.getName()); // verify schema exist
				if ( schema != null) {
					this.schemaCombo.select( this.schemaCombo.indexOf( schema.getName()));
					updateGenerateEntitiesPage( schema);
					setPageComplete( true);
				}
			}
		}

		private String getConnectionProfileName() {
			return this.connectionCombo.getText();
		}

		private String getSchemaName() {
			return this.schemaCombo.getText();
		}

		private void openNewConnectionWizard() {
			String addedProfileName = DTPUiTools.createNewProfile();
			  
			ConnectionProfile addedProfile = ConnectionProfileRepository.instance().profileNamed( addedProfileName);
		
			if( !addedProfile.isNull()) {
				this.populateConnectionCombo();
				this.connectionCombo.select( connectionCombo.indexOf( addedProfile.getName()));
				this.handleConnectionChange();
			}
		}

		private ConnectionListener buildConnectionListener() {
			return new ConnectionListener() {

				public void modified( Connection connection) {
				// not interested to this event.
				}

				public boolean okToClose( Connection connection) {
				// not interested to this event.
					return true;
				}

				public void opened( Connection connection) {
					if( DatabaseReconnectWizardPage.this.connection.equals( connection)) {
						DatabaseGroup.this.populateSchemaCombo();
					}
				}

				public void aboutToClose( Connection connection) {
					if( DatabaseReconnectWizardPage.this.connection.equals( connection)) {
						DatabaseReconnectWizardPage.this.removeConnectionListener();
					}
				}

				public void closed( Connection connection) {
				// not interested to this event.
				}

				public void databaseChanged(Connection connection, final Database database) {
				// not interested to this event.
				}

				public void schemaChanged(Connection connection, final Schema schema) {
				// not interested to this event.
				}

				public void tableChanged(Connection connection, final Table table) {
				// not interested to this event.
				}
			};
		}
	}
}
