/*******************************************************************************
 * Copyright (c) 2007, 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.jpa.ui.internal.wizards.gen;


import static org.eclipse.jpt.jpa.ui.internal.wizards.gen.SWTUtil.fillColumns;
import static org.eclipse.jpt.jpa.ui.internal.wizards.gen.SWTUtil.newLabel;
import static org.eclipse.jpt.jpa.ui.internal.wizards.gen.SWTUtil.newLabelWithIndent;

import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.ui.dialogs.StatusUtil;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.jpt.jpa.core.JpaProject;
import org.eclipse.jpt.jpa.gen.internal.Association;
import org.eclipse.jpt.jpa.gen.internal.AssociationRole;
import org.eclipse.jpt.jpa.gen.internal.ORMGenColumn;
import org.eclipse.jpt.jpa.gen.internal.ORMGenCustomizer;
import org.eclipse.jpt.jpa.ui.internal.ImageRepository;
import org.eclipse.jpt.jpa.ui.internal.JpaHelpContextIds;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.help.IWorkbenchHelpSystem;

public class TableAssociationsWizardPage extends WizardPage {

	private JpaProject jpaProject;
	private ORMGenCustomizer customizer ;
	
	private AssociationsListComposite associationList; 
	private Association selectedAssociation;
	private Button deleteAssociationLink ;
	private Button createAssociationLink ;
	
	//Controls in Association Edit Panel
	private Composite associationsEditPanel ;
	private Button generateAssociationCheckBox; 
	private Label cardinalityLabel ;
	private Combo cardinalityCombo ;
	/*whether to generate the referrer-->referenced role.*/
	private Button referrerRoleCheckBox; 
	/*the name of the property in the referrer-->referenced role.*/
	private Label referrerRolePropertyLabel;
	private Text referrerRolePropertyField ;
	/*the cascade in the referrer-->referenced role.*/
	@SuppressWarnings("restriction")
	private StringButtonDialogField referrerRoleCascadeField;
	/*whether to generate the referenced->referrer role.*/
	private Button referencedRoleCheckBox;
	/*the name of the property in the referenced->referrer role.*/
	private Label referencedRolePropertyLabel;
	private Text referencedRolePropertyField ;
	/*the cascade in the referenced->referrer role.*/
	@SuppressWarnings("restriction")
	private StringButtonDialogField referencedRoleCascadeField;
	private Label joinConditionLabel;
	private Text joinConditionText; 
	
	private Composite detailPanel;
	private StackLayout detailPanelStatckLayout;
	private Composite emptyPanel;
	
	protected final ResourceManager resourceManager;

	protected TableAssociationsWizardPage(JpaProject jpaProject, ResourceManager resourceManager) {
		super("Table Associations"); //$NON-NLS-1$
		this.jpaProject = jpaProject;
		this.resourceManager = resourceManager;
		setTitle(JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_title);
		setMessage(JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_desc);
		
	}

	public void createControl(Composite parent) {
		initializeDialogUnits(parent);
		
		Composite composite = new Composite(parent, SWT.NULL);
		int nColumns= 2 ;
		GridLayout layout = new GridLayout();
		layout.numColumns = nColumns;
		composite.setLayout(layout);
		this.getHelpSystem().setHelp(composite, JpaHelpContextIds.GENERATE_ENTITIES_WIZARD_TABLE_ASSOCIATIONS);

		Label label = new Label(composite, SWT.NONE);
		label.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_label );
		GridData gd = new GridData();
		gd.horizontalSpan = 2;
		label.setLayoutData( gd );
		
		createAssociationsListPanel(composite);
		createAddDeleteButtons(composite, nColumns);
		SWTUtil.createSeparator(composite, nColumns);
		
		createDetailPanel(composite);
		setControl(composite);
		
		composite.layout(true);
		this.setPageComplete( true);
		
	}

	private void createAddDeleteButtons(Composite composite, int columns) {
		
		Composite c = new Composite( composite, SWT.NONE);
		fillColumns(c, 1);
		c.setLayout( new GridLayout(1,true) );
		
		createAssociationLink = new Button(c, SWT.NONE);
		createAssociationLink.setToolTipText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_newAssoc );
		createAssociationLink.setImage( ImageRepository.getAddButtonImage(this.resourceManager) );
		createAssociationLink.addSelectionListener(new SelectionListener(){
			public void widgetDefaultSelected(SelectionEvent e) {}	
			public void widgetSelected(SelectionEvent e) {
				launchNewAssociationsWizard();
			}	
			
		});
		
		deleteAssociationLink = new Button(c, SWT.NONE);
		Color foreground = new Color(Display.getDefault(), 0,0,255);
		deleteAssociationLink.setForeground(foreground);
		foreground.dispose();
		deleteAssociationLink.setImage( ImageRepository.getDeleteButtonImage(this.resourceManager));
		deleteAssociationLink.setToolTipText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_delAssoc );
		deleteAssociationLink.addSelectionListener(new SelectionListener(){
			public void widgetDefaultSelected(SelectionEvent e) {}	
			public void widgetSelected(SelectionEvent e) {
				Association association = associationList.getSelectedAssociation();
				if( association != null ){
					ORMGenCustomizer customizer = getCustomizer();
					customizer.deleteAssociation(association);
					List<Association> associations = customizer.getAssociations();
					associationList.updateAssociations(associations);
					if( associations.size()==0 ){
						hideAssociationDetail();
					}
				}
			}	
		});
		deleteAssociationLink.setEnabled(false);
		
	}

	private void createGenerateAssociationCheckbox(Composite composite,  int columns) {
		generateAssociationCheckBox = new Button(composite, SWT.CHECK);
		generateAssociationCheckBox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_genAssoc);
		generateAssociationCheckBox.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {}
		
			public void widgetSelected(SelectionEvent e) {
				Association association = associationList.getSelectedAssociation();
				if( association == null )
					return;
				association.setGenerated(generateAssociationCheckBox.getSelection());
				
				updateAssociationEditPanel(association);
				associationList.updateSelectedAssociation();
			}

		});

		fillColumns(generateAssociationCheckBox, columns-1);
		newLabel(composite, "");
	}

	@SuppressWarnings("restriction")
	private void createGenerateReferrerRoleControls(Composite parent,  int columns) {
		referrerRoleCheckBox = new Button(parent, SWT.CHECK);
		referrerRoleCheckBox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_entityRef );
		referrerRoleCheckBox.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {}
		
			public void widgetSelected(SelectionEvent e) {
				boolean generate = referrerRoleCheckBox.getSelection();
				//referrerRolePropertyField.setEditable( generate );
				referrerRolePropertyLabel.setEnabled( generate );
				referrerRolePropertyField.setEnabled( generate );
				referrerRoleCascadeField.setEnabled(generate);
				
				//If both referencedRoleCheckBox and referencedRoleCheckBox unchecked, 
				//the association itself shouldn't be generated 
				if( !generate && !referencedRoleCheckBox.getSelection()){
					generateAssociationCheckBox.setSelection(false);
					cardinalityLabel.setEnabled( false );
					cardinalityCombo.setEnabled(false);
					referrerRoleCheckBox.setEnabled(false);
					referencedRoleCheckBox.setEnabled(false);
				}
				
				directionalityCheckBoxChanged( );			
				
				if( generate ){
					AssociationRole role = selectedAssociation.getReferrerRole();
					referrerRolePropertyField.setText( role.getPropertyName() );
				}
			}

		});

		SWTUtil.fillColumnsWithIndent(referrerRoleCheckBox , columns-1, 20 );
		newLabel(parent, "");//$NON-NLS-1$
		
		referrerRolePropertyLabel = newLabelWithIndent( parent,  JptUiEntityGenMessages.property, 40 );
		referrerRolePropertyField = new Text( parent, SWT.BORDER);
		fillColumns(referrerRolePropertyField, 2);
		referrerRolePropertyField.addModifyListener(new ModifyListener(){
			@SuppressWarnings("deprecation")
			public void modifyText(ModifyEvent e) {
				if( selectedAssociation.getReferrerRole() == null )
					return;
				String fieldName = referrerRolePropertyField.getText();
				IStatus status = JavaConventions.validateFieldName( fieldName );
				if( !status.matches(IStatus.ERROR) ){
					selectedAssociation.getReferrerRole().setPropertyName(fieldName);
				}
				updateStatus(status);
			}			
		});

		Label label = new Label( parent, SWT.NONE);
		label.setText( "" );//$NON-NLS-1$
		label.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
		
		referrerRoleCascadeField = new StringButtonDialogField( new IStringButtonAdapter(){
			public void changeControlPressed(DialogField field) {
				if( editCascade( selectedAssociation.getReferrerRole() )){
					referrerRoleCascadeField.setText(selectedAssociation.getReferrerRole().getCascade());
				}
			}	
		}) ;
		referrerRoleCascadeField.setLabelText( JptUiEntityGenMessages.cascade );
		referrerRoleCascadeField.setButtonLabel(""); //$NON-NLS-1$
		referrerRoleCascadeField.doFillIntoGrid(parent, 3);
		referrerRoleCascadeField.getTextControl(parent).setEditable(false);
		int maxFieldWidth = convertWidthInCharsToPixels(40);
		LayoutUtil.setWidthHint(referrerRoleCascadeField.getTextControl(null), maxFieldWidth );
		Button btn = referrerRoleCascadeField.getChangeControl(null);
		GridData data = (GridData)btn.getLayoutData();
		btn.setImage( ImageRepository.getBrowseButtonImage(this.resourceManager) );
		data.horizontalAlignment = SWT.BEGINNING;
		data.widthHint = 30;
		btn.setLayoutData(data);
		
		Label labelCtrl  = referrerRoleCascadeField.getLabelControl(parent);
		data = (GridData)labelCtrl.getLayoutData();
		data.horizontalIndent = 40 ;
		labelCtrl.setLayoutData(data);
		
		
		label = new Label( parent, SWT.NONE);
		label.setText( "" );//$NON-NLS-1$
		label.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
		
	}	
	
	
	@Override
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		if( visible ){
			hideAssociationDetail();
			updateAssociationsListPanel();
		}
	}

	private void hideAssociationDetail( ){
		this.detailPanelStatckLayout.topControl = emptyPanel;
		this.detailPanel.layout();
		this.detailPanel.getParent().layout();
	}
	
	/**
	 * Updates the status line and the OK button according to the given status
	 * 
	 * @param status status to apply
	 */
	@SuppressWarnings("restriction")
	protected void updateStatus(IStatus status) {
		setPageComplete(!status.matches(IStatus.ERROR));
		
		StatusUtil.applyToStatusLine(this, status);
		if( status.getCode() == Status.OK ){
			setMessage(JptUiEntityGenMessages.GenerateEntitiesWizard_assocPage_desc);
		}
	}
	
	@SuppressWarnings("restriction")
	private void createGenerateReferencedRoleControls(Composite parent,  int columns) {
		referencedRoleCheckBox = new Button(parent, SWT.CHECK);
		referencedRoleCheckBox.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_setRef );
		referencedRoleCheckBox.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {}
		
			public void widgetSelected(SelectionEvent e) {
				boolean generate = referencedRoleCheckBox.getSelection();
				referencedRolePropertyLabel.setEnabled( generate);
				referencedRolePropertyField.setEnabled( generate);
				referencedRoleCascadeField.setEnabled(generate);
				
				if( !generate && !referrerRoleCheckBox.getSelection()){
					generateAssociationCheckBox.setSelection(false);
					cardinalityCombo.setEnabled(false);
					referrerRoleCheckBox.setEnabled(false);
					referencedRoleCheckBox.setEnabled(false);
				}
				directionalityCheckBoxChanged();
				if( generate ){
					AssociationRole role = selectedAssociation.getReferencedRole();
					referencedRolePropertyField.setText( role.getPropertyName() );
				}
			}

		});

		SWTUtil.fillColumnsWithIndent( referencedRoleCheckBox , columns-1, 20 );
		newLabel(parent, "");//$NON-NLS-1$
		
		referencedRolePropertyLabel = SWTUtil.newLabelWithIndent(parent,  JptUiEntityGenMessages.property, 40 );
		
		referencedRolePropertyField = new Text( parent, SWT.BORDER);
		fillColumns(referencedRolePropertyField, 2);
		referencedRolePropertyField.addModifyListener(new ModifyListener(){
			public void modifyText(ModifyEvent e) {
				if( selectedAssociation.getReferencedRole() == null )
					return ;
				
				String fieldName = referencedRolePropertyField.getText();
				IStatus status = JavaConventions.validateIdentifier(fieldName,
						JavaCore.VERSION_1_3, JavaCore.VERSION_1_3);
				if( !status.matches(IStatus.ERROR) ){
					if( !fieldName.equals(selectedAssociation.getReferencedRole().getPropertyName()) )
						selectedAssociation.getReferencedRole().setPropertyName(fieldName);
				}
				updateStatus(status);
			}			
		});
		

		Label label = new Label( parent, SWT.NONE);
		label.setText( "" );//$NON-NLS-1$
		label.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
		
		
		referencedRoleCascadeField = new StringButtonDialogField( new IStringButtonAdapter(){
			public void changeControlPressed(DialogField field) {
				if( editCascade( selectedAssociation.getReferencedRole() ) ){
					referencedRoleCascadeField.setText( selectedAssociation.getReferencedRole().getCascade() );
				}
			}	
		}) ;
		referencedRoleCascadeField.setLabelText( JptUiEntityGenMessages.cascade );
		referencedRoleCascadeField.setButtonLabel(""); //$NON-NLS-1$
		referencedRoleCascadeField.doFillIntoGrid(parent, 3);
		referencedRoleCascadeField.getTextControl(parent).setEditable( false);
		int maxFieldWidth = convertWidthInCharsToPixels(40);
		LayoutUtil.setWidthHint(referencedRoleCascadeField.getTextControl(null), maxFieldWidth );
		Button btn = referencedRoleCascadeField.getChangeControl(null);
		btn.setImage( ImageRepository.getBrowseButtonImage(this.resourceManager) );
		GridData data = (GridData)btn.getLayoutData();
		data.horizontalAlignment = SWT.BEGINNING;
		data.widthHint = 30;
		btn.setLayoutData(data);
		
		Label labelCtrl  = referencedRoleCascadeField.getLabelControl(parent);
		data = (GridData)labelCtrl.getLayoutData();
		data.horizontalIndent = 40 ;
		labelCtrl.setLayoutData(data);
		
		label = new Label( parent, SWT.NONE);
		label.setText( "" );//$NON-NLS-1$
		label.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
		
	}	
	
	private void createDetailPanel(Composite composite ) {
		
		this.detailPanel = new Composite( composite, SWT.NONE);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.grabExcessVerticalSpace = false;
		this.detailPanel.setLayoutData(gd);
		this.detailPanelStatckLayout = new StackLayout();
		this.detailPanel.setLayout( this.detailPanelStatckLayout );
		
		emptyPanel = new Composite( detailPanel, SWT.NONE);
		emptyPanel.setLayoutData(new GridData()); 
		detailPanelStatckLayout.topControl = emptyPanel;
		detailPanel.layout();
		
		composite.layout();
	}
	
	
	private Composite createAssociationsEditPanel(Composite composite, int columns) {
		Composite parent = new Composite( composite, SWT.NONE);
		fillColumns(parent, 4);

		createGenerateAssociationCheckbox(parent,columns);
		int nColumns= 4 ;
		GridLayout layout = new GridLayout();
		layout.numColumns = nColumns;
		parent.setLayout(layout);

		//Cardinality
		cardinalityLabel = new Label(parent, SWT.NONE);
		cardinalityLabel.setText( JptUiEntityGenMessages.cardinality);
		GridData gd = new GridData();
		gd.horizontalIndent = 20;
		cardinalityLabel.setLayoutData( gd );
		
		cardinalityCombo = new Combo(parent, SWT.SINGLE | SWT.READ_ONLY );
		
		fillColumns(cardinalityCombo, 1);
		
		cardinalityCombo.addSelectionListener(new SelectionListener(){
			public void widgetDefaultSelected(SelectionEvent e) {}
			public void widgetSelected(SelectionEvent e) {
				selectedAssociation.setCardinality( cardinalityCombo.getText());
				associationList.updateSelectedAssociation();
			}
		});
		
		//Adding a filler column
		Label label = new Label( parent, SWT.NONE);
		label.setText( "");//$NON-NLS-1$
		GridData layoutData = new GridData();
		layoutData.horizontalSpan = 2;
		layoutData.horizontalAlignment = SWT.FILL;
		layoutData.grabExcessHorizontalSpace = true;
		label.setLayoutData(layoutData);
		
		//Table join condition
		joinConditionLabel = newLabelWithIndent(parent, JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_tableJoin, 20 );
		
		joinConditionText = new Text( parent, SWT.MULTI | SWT.BORDER );
		joinConditionText.setEditable(false);
		joinConditionText.setText(JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_joinedWhen);
		layoutData = new GridData();
		layoutData.horizontalSpan = 2;
		layoutData.verticalAlignment = SWT.TOP;
		layoutData.horizontalAlignment = SWT.FILL;
		layoutData.grabExcessHorizontalSpace = true;
		layoutData.grabExcessVerticalSpace = false;
		layoutData.heightHint = 50;
		joinConditionText.setLayoutData(layoutData);
		newLabel(parent, "");//$NON-NLS-1$

		//Generate UI controls for ReferrerRole
		createGenerateReferrerRoleControls(parent, columns);

		//Generate UI controls for ReferencedRole
		createGenerateReferencedRoleControls(parent, columns);
		
		
		return parent;
	}

	public boolean editCascade(AssociationRole role) {
		CascadeDialog dlg = CascadeDialog.create(role);
		if (dlg.open() == Window.CANCEL ) {
			return false;
		}
		
		return true;
	}	

	private void createAssociationsListPanel(Composite parent) {
		Composite composite = new Composite( parent, SWT.NULL );
		composite.setLayout( new FillLayout());
		Color backgroundColor = new Color(Display.getDefault(),255, 0,0);
		composite.setBackground(backgroundColor);
		backgroundColor.dispose();
		GridData layoutData = new GridData();
		layoutData.horizontalSpan = 1;
		layoutData.verticalAlignment = SWT.FILL;
		layoutData.horizontalAlignment = SWT.FILL;
		layoutData.grabExcessHorizontalSpace = false;
		layoutData.grabExcessVerticalSpace = true;
		layoutData.widthHint = 400;
		layoutData.heightHint = 400;
		composite.setLayoutData(layoutData);
		
		associationList = new AssociationsListComposite(composite, this, this.resourceManager);
	}
	
	private void launchNewAssociationsWizard() {
		ORMGenCustomizer customizer = getCustomizer();
		NewAssociationWizard wizard = new NewAssociationWizard(this.jpaProject, customizer, this.resourceManager);
		
		WizardDialog dialog = new WizardDialog( this.getShell(), wizard);
		dialog.create();
		int returnCode = dialog.open();
		if (returnCode == Window.OK) {
			Association association = wizard.getNewAssociation();
			if( association !=null ){
				customizer.addAssociation(association);
				updateForeignKeyColumnGenProperty(association);
				updateAssociationsListPanel();
			}
		}		
	}
	/**
	 * For user created association:
	 * If association is to be generated, no need to generate the getter/setter for the column itself
	 */
	private void updateForeignKeyColumnGenProperty(Association association) {
		//Need to process MANY_TO_ONE only since the the associations list are optimized to have MANY_TO_ONE
		if( association.isCustom() && association.getCardinality().equals( Association.MANY_TO_ONE ) ){
			boolean generateColumn =  !association.isGenerated();
			//The "MANY" side DB table
			//ORMGenTable table1 = association.getReferrerTable();
			//The "ONE" side DB table
			//ORMGenTable table2 = association.getReferencedTable();
			//The list of foreign key columns in the MANY side, should not be generated
			//The list of primary keys in the ONE side, will be generated
			//List<ORMGenColumn> list2 = association.getReferencedColumns();	
			List<ORMGenColumn> list1 = association.getReferrerColumns();	
			for(ORMGenColumn c : list1 ){
				if( c.isGenerated() != generateColumn){
					if( !generateColumn && c.getDbColumn().isPartOfPrimaryKey() ){
						continue;
					}
					c.setGenerated(generateColumn);
					c.setInsertable(generateColumn);
					c.setUpdateable(generateColumn);
				}
			}
		}
	}

	private void updateAssociationsListPanel() {
			ORMGenCustomizer customizer = getCustomizer();
			//If user changed the connection or schema
			if( this.customizer != customizer ){
				this.customizer = customizer; 
			}
			List<Association> associations = customizer.getAssociations();
			this.associationList.updateAssociations( associations );
	}

	@SuppressWarnings("restriction")
	public void updateAssociationEditPanel(Association association) {
		this.selectedAssociation = association;

		boolean enabled = association.isCustom();
		this.deleteAssociationLink.setEnabled(enabled);
		
		//Create and display the associationsEditPanel if it was hidden before
		if( associationsEditPanel == null ){
			associationsEditPanel = this.createAssociationsEditPanel(this.detailPanel, 4);
		}
		this.detailPanelStatckLayout.topControl = associationsEditPanel;
		this.detailPanel.layout();
		this.detailPanel.getParent().layout();

		//Update the UI controls from the model
		String table1Name = association.getReferrerTableName();
		String table2Name = association.getReferencedTableName();
		String joinTableName = association.getJoinTableName();
		
		boolean isGenerated = association.isGenerated();
		this.generateAssociationCheckBox.setSelection(isGenerated);
		this.referrerRolePropertyLabel.setEnabled( isGenerated );
		this.referrerRolePropertyField.setEnabled( isGenerated );
		this.referrerRoleCheckBox.setEnabled( isGenerated );
		this.referencedRolePropertyLabel.setEnabled( isGenerated );
		this.referencedRolePropertyField.setEnabled( isGenerated );
		this.referencedRoleCheckBox.setEnabled( isGenerated );
		this.cardinalityLabel.setEnabled(isGenerated);
		this.cardinalityCombo.setEnabled(isGenerated);
		this.joinConditionLabel.setEnabled( isGenerated );
		this.joinConditionText.setEnabled( isGenerated );
		
		String cardinality = association.getCardinality();
		if( Association.MANY_TO_MANY.equals( cardinality ) ){
			cardinalityCombo.removeAll();
			cardinalityCombo.add( Association.MANY_TO_MANY);
		}else{
			cardinalityCombo.removeAll();
			cardinalityCombo.add( Association.MANY_TO_ONE);
			cardinalityCombo.add( Association.ONE_TO_ONE);
		}
		
		cardinalityCombo.setText(cardinality);
		cardinalityCombo.setEnabled(enabled);
		
		String text = null;
		//if MTM
		if( Association.MANY_TO_MANY.equals( cardinality ) ){
			text = String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_setRef, table2Name, table1Name);
		}else{
			text = String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_entityRef, table2Name, table1Name);
		}
		this.referrerRoleCheckBox.setText(text);

		//if OTO
		if( Association.ONE_TO_ONE.equals( cardinality ) ){
			text = String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_entityRef, table1Name, table2Name);
		}else{
			text = String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_setRef, table1Name, table2Name);
		}
		this.referencedRoleCheckBox.setText(text);

		//AssociationRole properties
		AssociationRole referrerRole = association.getReferrerRole();
		if( referrerRole != null){
			this.referrerRoleCheckBox.setSelection( true );
			this.referrerRolePropertyField.setEditable(true);
			this.referrerRolePropertyField.setText(referrerRole.getPropertyName());
			this.referrerRoleCascadeField.setEnabled(true);
			String cascade = referrerRole.getCascade();
			if( cascade!=null ) 
				this.referrerRoleCascadeField.setText( cascade );
			
			//if MTO: 
			if( Association.MANY_TO_ONE.equals( cardinality ) ){
				this.referrerRoleCheckBox.setEnabled( false );
			}
		}else{
			this.referrerRoleCheckBox.setSelection( false );
			this.referrerRolePropertyLabel.setEnabled(false);
			this.referrerRolePropertyField.setEditable(false);
			this.referrerRolePropertyField.setText("");
			this.referrerRoleCascadeField.setEnabled(false);
		}
		
		AssociationRole referencedRole = association.getReferencedRole();
		if( referencedRole != null){
			this.referencedRoleCheckBox.setSelection( true );
			this.referencedRolePropertyLabel.setEnabled(true);
			this.referencedRolePropertyField.setEditable(true);
			this.referencedRolePropertyField.setText(referencedRole.getPropertyName());
			this.referencedRoleCascadeField.setEnabled(true);
			String cascade = referencedRole.getCascade();
			if( cascade!=null ) 
				this.referencedRoleCascadeField.setText(cascade);
		}else{
			this.referencedRoleCheckBox.setSelection( false );
			this.referencedRolePropertyLabel.setEnabled(false);
			this.referencedRolePropertyField.setEditable(false);
			this.referencedRolePropertyField.setText("");
			this.referencedRoleCascadeField.setEnabled(false);
		}
		
		//Join conditions
		updateJoinConditions(association, table1Name, table2Name, joinTableName);
	}

	private void updateJoinConditions(Association association,
			String table1Name, String table2Name, String joinTableName) {
		String text = "%s";
		if( joinTableName == null ){
			StringBuilder strText = new StringBuilder();
			//text = JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_joinedWhen;
			List<String> columnList1 = association.getReferrerColumnNames() ;
			List<String> columnList2 = association.getReferencedColumnNames();
			for( int i=0; i < columnList1.size(); i++){
				strText.append( table1Name + "." + columnList1.get(i) );//$NON-NLS-1$
				strText.append( "=" );//$NON-NLS-1$
				strText.append( table2Name + "." + columnList2.get(i) );//$NON-NLS-1$
				if( i < columnList1.size()-1 )
					strText.append( "\n AND " );//$NON-NLS-1$
			}
			joinConditionText.setText( String.format( text , strText.toString()) ); 
		}else{
			StringBuilder strText = new StringBuilder();
			//text = JptUiEntityGenMessages.GenerateEntitiesWizard_assocEditor_joinedWhen;
			List<String> columnList1 = association.getReferrerColumnNames() ;
			List<String> joinColumnList1 = association.getReferrerJoinColumnNames()  ;
			for( int i=0; i < columnList1.size(); i++){
				strText.append( table1Name + "." + columnList1.get(i) );//$NON-NLS-1$
				strText.append( "=" );//$NON-NLS-1$
				strText.append( joinTableName + "." + joinColumnList1.get(i) );
				strText.append( "\n AND " );//$NON-NLS-1$
			}
			
			List<String> joinTableColumnList2 = association.getReferencedJoinColumnNames();
			List<String> columnList2 = association.getReferencedColumnNames();
			for( int i=0; i < joinTableColumnList2.size(); i++){
				strText.append( joinTableName + "." + joinTableColumnList2.get(i) );
				strText.append( "=" );//$NON-NLS-1$
				strText.append( table2Name + "." + columnList2.get(i) );//$NON-NLS-1$
				if( i < joinTableColumnList2.size()-1 )
					strText.append( "\n AND " );//$NON-NLS-1$
			}
			
			joinConditionText.setText( String.format( text , strText.toString()) ); 
			
		}
	}

	/**
	 * Called when one of referrerRoleCheckBox or referencedRoleCheckBox 
	 * changes value. 
	 *
	 */
	private void directionalityCheckBoxChanged() {
		String dir;
		if (referrerRoleCheckBox.getSelection()) {
			dir = referencedRoleCheckBox.getSelection() ? Association.BI_DI : Association.NORMAL_DI;
		} else {
			if (referencedRoleCheckBox.getSelection()) {
				dir = Association.OPPOSITE_DI;
			} else {
				dir = null;
			}
		}
		if (dir != null) {
			selectedAssociation.setDirectionality(dir);
		} else {
			selectedAssociation.setGenerated(false);
		}
		
		this.associationList.updateSelectedAssociation();
	}	
	
	private ORMGenCustomizer getCustomizer(){
		GenerateEntitiesFromSchemaWizard wizard = (GenerateEntitiesFromSchemaWizard) this.getWizard();
		return wizard.getCustomizer();
	}
	
	
    @Override
    public final void performHelp() 
    {
        this.getHelpSystem().displayHelp( GenerateEntitiesFromSchemaWizard.HELP_CONTEXT_ID );
    }
    
	protected final IWorkbenchHelpSystem getHelpSystem() {
		return PlatformUI.getWorkbench().getHelpSystem();
	}
	
	@Override
	public void dispose() {
		//when the JPA project wizard page is shown first, the other wizard pages are lazily built, thus
		//associationList can be null - bug 307894
		if (this.associationList != null) {
			this.associationList.dispose();
		}
		super.dispose();
	}
}
