/*******************************************************************************
 * 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.ui.internal.wizards.gen;

import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.jpt.gen.internal.ORMGenTable;
import org.eclipse.jpt.ui.JptUiPlugin;
import org.eclipse.swt.SWT;
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.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
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.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

/**
 * The UI panel for setting the default and specific 
 * table entity generation properties.
 * 
 */
class TableGenPanel
{
	WizardPage wizardPage ; 
	
	private Text classNameField; // used in setting individual table/entity generation only
	
	private Combo idGeneratorCombo;
	private Text sequenceNameField;
	
	private Button entityAccessField;
	private Button entityAccessProperty;
	private Button associationFetchDefault;
	private Button associationFetchEager;
	private Button associationFetchLazy;
	
	private Button collectionTypeSet;
	private Button collectionTypeList;
	
	private Button generateOptionalAnnotations;
	
	private Label sequenceNameNoteLabel; 
	
	private boolean isUpdatingControls;
	
	private ORMGenTable mTable;
	
	private boolean isDefaultTable = false;
	
	public TableGenPanel(Composite parent, int columns , boolean isDefaultTable, WizardPage wizardPage   ){
		super();
		this.wizardPage = wizardPage;
		this.isDefaultTable = isDefaultTable;
		createTableMappingPropertiesGroup(parent, columns);
		SWTUtil.createLabel(parent, 4, ""); //$NON-NLS-1$
	}
	
	protected void createTableMappingPropertiesGroup(Composite composite, int columns) {
		Group parent = new Group(composite, SWT.NONE );
		parent.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_tableMapping);
		parent.setLayout(new GridLayout(columns, false));
		GridData layoutData = new GridData();
		layoutData.horizontalSpan = columns;
		layoutData.verticalAlignment = SWT.FILL;
		layoutData.horizontalAlignment = SWT.FILL;
		layoutData.grabExcessHorizontalSpace = true;
		layoutData.grabExcessVerticalSpace = false;
		parent.setLayoutData(layoutData);
		
		createClassNameControl(parent, columns);
		
		createIdGeneratorControls(parent, columns);
		createEntityAccessControls(parent, columns);
		
		//AssociationFetch and CollectionType only available for default table generation
		if ( isDefaultTable ) {
			createAssociationFetchControls(parent, columns);
			createCollectionTypeControls(parent, columns);
			createGenerateOptionalAnnotationControls(parent, columns);
		}
	}
	
	private void createGenerateOptionalAnnotationControls(Group parent, int columns) {
		generateOptionalAnnotations = new Button(parent, SWT.CHECK );
		generateOptionalAnnotations.setText( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations);
		generateOptionalAnnotations.setToolTipText(JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_genOptionalAnnotations_desc);

		GridData gd = new GridData();
		gd.horizontalSpan = columns;
		generateOptionalAnnotations.setLayoutData(gd);
		generateOptionalAnnotations.addSelectionListener(new SelectionListener(){
			public void widgetDefaultSelected(SelectionEvent e) {}
			public void widgetSelected(SelectionEvent e) {
				boolean selected = generateOptionalAnnotations.getSelection();
				mTable.setGenerateDDLAnnotations(selected);
			}
		});
	}

	private void createClassNameControl(Composite parent, int columns) {
		//Customize class name for specific table only
		if ( !isDefaultTable ) {
			SWTUtil.createLabel( parent, 1 , JptUiEntityGenMessages.GenerateEntitiesWizard_tablePanel_className );
			
			classNameField = new Text(parent, SWT.SINGLE | SWT.BORDER );
			//mPackageNameField.setEditable(false);
			SWTUtil.fillColumns(classNameField,3);
			classNameField.addModifyListener(new ModifyListener(){
				@SuppressWarnings({  "deprecation" })
				public void modifyText(ModifyEvent e) {
					if (e.getSource() == null || !isUpdatingControls) {
						String className = classNameField.getText();
						IStatus status = JavaConventions.validateJavaTypeName( className );
						if( !status.matches(IStatus.ERROR) ){
							mTable.setClassName(  className );
							wizardPage.setErrorMessage(null);
						}else{
							wizardPage.setErrorMessage(status.getMessage());
						}
					}
				}			
			});
		}
	}
	
	class AssociationFetchListener implements SelectionListener{
		public void widgetDefaultSelected(SelectionEvent e) {}
		public void widgetSelected(SelectionEvent e) {
			if (!isUpdatingControls) {
				Button radioBtn = (Button)e.getSource();
				mTable.setDefaultFetch( radioBtn.getData().toString());
			}
		}
	}

	private void createAssociationFetchControls(Composite composite, int columns) {
		SWTUtil.createLabel(composite, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_fetch );
		
		Composite parent = new Composite( composite, SWT.NONE);
		parent.setLayout(new RowLayout());
		SWTUtil.fillColumns( parent , 3);
		associationFetchDefault	= new Button( parent, SWT.RADIO );
		associationFetchDefault.setText( "Default");
		associationFetchDefault.setData( ORMGenTable.DEFAULT_FETCH );	
		
		associationFetchEager = new Button( parent, SWT.RADIO );
		associationFetchEager.setText( "&Eager");
		associationFetchEager.setData( ORMGenTable.EAGER_FETCH );

		associationFetchLazy = new Button( parent, SWT.RADIO );
		associationFetchLazy.setText( "La&zy");
		associationFetchLazy.setData( ORMGenTable.LAZY_FETCH );
		
		AssociationFetchListener associationFetchListener = new AssociationFetchListener();
		associationFetchDefault.addSelectionListener( associationFetchListener );
		associationFetchLazy.addSelectionListener( associationFetchListener );
		associationFetchEager.addSelectionListener( associationFetchListener );
	}

	class CollectionTypeListener implements SelectionListener {
		public void widgetDefaultSelected(SelectionEvent e) {}
		public void widgetSelected(SelectionEvent e) {
			if (!isUpdatingControls) {
				Button radioBtn = (Button)e.getSource();
				mTable.setDefaultCollectionType( radioBtn.getData().toString());
			}
		}
	}	
	
	private void createCollectionTypeControls(Composite composite, int columns) {
		SWTUtil.createLabel(composite, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_collType );
		
		Composite parent = new Composite( composite, SWT.NONE);
		parent.setLayout(new RowLayout());
		SWTUtil.fillColumns( parent , 3);
		
		this.collectionTypeSet = new Button( parent, SWT.RADIO);
		this.collectionTypeSet.setText( "java.util.Se&t");
		this.collectionTypeSet.setData( ORMGenTable.SET_COLLECTION_TYPE );
		this.collectionTypeList = new Button( parent, SWT.RADIO);
		this.collectionTypeList.setText("java.util.&List");
		this.collectionTypeList.setData(ORMGenTable.LIST_COLLECTION_TYPE); 
		
		CollectionTypeListener collectionTypeListener = new CollectionTypeListener();
		collectionTypeList.addSelectionListener( collectionTypeListener );
		collectionTypeSet.addSelectionListener( collectionTypeListener );
	}


	public void setORMGenTable(ORMGenTable table) {
		mTable = table;
		
		isUpdatingControls = true;
				
		try {
			//ClassNameField is not available for default table
			if(classNameField!= null )
				classNameField.setText( mTable.getClassName() );
			
			final List<String> schemes = this.mTable.getCustomizer().getAllIdGenerators();
			String[] values = new String[schemes.size()];
			schemes.toArray(values);
			idGeneratorCombo.setItems( values );
			String idGenerator = mTable.getIdGenerator();
			idGeneratorCombo.setText( idGenerator);
			
			boolean isSequence = this.mTable.getCustomizer().getSequenceIdGenerators().contains(idGenerator);		
			String sequenceName = mTable.isDefaultsTable() ? mTable.getSequence() : mTable.getFormattedSequence();
			sequenceName  = ( sequenceName == null ? "" : sequenceName ); 
			sequenceNameField.setText( sequenceName );
			if ( isSequence ) {
				sequenceNameField.setEnabled(true);
				sequenceNameNoteLabel.setEnabled(true);
			} else {
				sequenceNameField.setEnabled(false);
				sequenceNameNoteLabel.setEnabled(false);
			}
			
			String access = mTable.getAccess() ;
			if (  ORMGenTable.FIELD_ACCESS.equals( access ) ) {
				this.entityAccessField.setSelection( true );
				this.entityAccessProperty.setSelection( false );
			} else {
				this.entityAccessProperty.setSelection( true );
				this.entityAccessField.setSelection( false );
			}
	
			if (associationFetchLazy != null && associationFetchEager != null ) {
				String defaultFetch = mTable.getDefaultFetch();
				//reset all three buttons
				associationFetchDefault.setSelection(false);
				associationFetchEager.setSelection(false);
				associationFetchLazy.setSelection(false);
				if( ORMGenTable.DEFAULT_FETCH.equals( defaultFetch ) )
					associationFetchDefault.setSelection(true);
				else if( ORMGenTable.EAGER_FETCH.equals( defaultFetch ) )
					associationFetchEager.setSelection(true);
				else
					associationFetchLazy.setSelection(true);
			}
			
			//DefaultTable only
			if (collectionTypeList != null) {
				String cType = mTable.getDefaultCollectionType();
				if ( ORMGenTable.LIST_COLLECTION_TYPE.equals( cType ) ) {
					this.collectionTypeList.setSelection( true );
					this.collectionTypeSet.setSelection( false );
				} else {
					this.collectionTypeSet.setSelection( true );
					this.collectionTypeList.setSelection( false );
				}
				
				this.generateOptionalAnnotations.setSelection( mTable.isGenerateDDLAnnotations());
			}
			
		} catch (Exception e) {
			JptUiPlugin.log(e);
		}
		
		isUpdatingControls = false;
	}

	private void createIdGeneratorControls(Composite parent, int columns) {
		SWTUtil.createLabel(parent, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_keyGen );

		idGeneratorCombo = new Combo(parent,SWT.SINGLE | SWT.READ_ONLY);
		SWTUtil.fillColumns(idGeneratorCombo, 3);
		
		idGeneratorCombo.addSelectionListener( new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {}

			public void widgetSelected(SelectionEvent e) {
				if (isUpdatingControls) {
					return;
				}
				
				idGenChanged();
			}});

		SWTUtil.createLabel(parent, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_sequence );
		sequenceNameField = new Text( parent, SWT.SINGLE | SWT.BORDER );
		
		SWTUtil.fillColumns(sequenceNameField, 3);
		sequenceNameField.addModifyListener(new ModifyListener(){
			public void modifyText(ModifyEvent e) {
				if (e.getSource() == null || !isUpdatingControls) {

					if ( idGeneratorCombo.getText().equals("sequence")) { //$NON-NLS-1$
						String sequenceName = sequenceNameField.getText();
						if ( sequenceName.toLowerCase().indexOf("$table") >= 0 ||  //$NON-NLS-1$
								sequenceName.toLowerCase().indexOf("$pk") >= 0 ) { //$NON-NLS-1$
							sequenceName = convertVarToLowerCase("$table", sequenceName); //$NON-NLS-1$
							sequenceName = convertVarToLowerCase("$pk", sequenceName); //$NON-NLS-1$
						}
						if ( sequenceName.trim().length() != 0 ) {
							mTable.setSequence( sequenceName );
						} else{
							mTable.setSequence( "" ); //$NON-NLS-1$
						}
					}
				}
			}

			private String convertVarToLowerCase(String var, String sequenceName) {
				int n = sequenceName.toLowerCase().indexOf( var );
				if( n==0 ) {
					return var + sequenceName.substring( var.length());
				} else if( n >0 ) {
					return sequenceName.substring(0,n) + var + sequenceName.substring( n + var.length());
				}
				return sequenceName;
			}			
		});
		
		SWTUtil.newLabel(parent, "");//$NON-NLS-1$
		sequenceNameNoteLabel = new Label(parent, SWT.NONE);
		String text =String.format( JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_sequenceNote, 
				ORMGenTable.TABLE_SEQ_PATTERN, ORMGenTable.PK_SEQ_PATTERN);
		sequenceNameNoteLabel.setText( text ) ;
		sequenceNameNoteLabel.setEnabled(false);
		SWTUtil.fillColumns( sequenceNameNoteLabel, 3);
	}

	private void idGenChanged() {
		String scheme = idGeneratorCombo.getText();
		mTable.setIdGenerator(scheme);
		
		boolean isSequence = this.mTable.getCustomizer().getSequenceIdGenerators().contains(scheme);		
		if (!isSequence) {
			sequenceNameField.setText("");
			sequenceNameField.setEnabled(false);
			mTable.setSequence(null);
			sequenceNameNoteLabel.setEnabled(false);
		} else {
			sequenceNameField.setEnabled(true);
			Color NOTE_LABEL_COLOR = new Color( Display.getDefault(), 102,102,102);
			sequenceNameNoteLabel.setForeground( NOTE_LABEL_COLOR );
			NOTE_LABEL_COLOR.dispose();
			sequenceNameNoteLabel.setEnabled(true);
			if ( sequenceNameField.getText().length()==0 ) {
				String newMessage = "Please specify a sequence name";
				this.wizardPage.setMessage(newMessage);
				this.wizardPage.setPageComplete(true);
			} else {
				this.wizardPage.setErrorMessage(null);
				this.wizardPage.setPageComplete(true);
			}
		}
	}
	
	class EntityAccessFetchListener implements SelectionListener{
		public void widgetDefaultSelected(SelectionEvent e) {}
		public void widgetSelected(SelectionEvent e) {
			if (!isUpdatingControls) {
				Button radioBtn = (Button)e.getSource();
				mTable.setAccess( radioBtn.getData().toString() );
			}
		}
	}
	
	private void createEntityAccessControls(Composite composite, int columns) {
		SWTUtil.createLabel(composite, 1, JptUiEntityGenMessages.GenerateEntitiesWizard_defaultTablePage_access );
		
		Composite parent = new Composite( composite, SWT.NONE);
		SWTUtil.fillColumns( parent , 3);
		parent.setLayout(new RowLayout());

		entityAccessField = new Button( parent, SWT.RADIO );
		entityAccessField.setText( "&Field" ); //$NON-NLS1$
		entityAccessField.setData( ORMGenTable.FIELD_ACCESS);

		entityAccessProperty = new Button( parent, SWT.RADIO );
		entityAccessProperty.setText(  "&Property" );//$NON-NLS1$
		entityAccessProperty.setData( ORMGenTable.PROPERTY_ACCESS );
		
		EntityAccessFetchListener entityAccessFetchListener = new EntityAccessFetchListener();
		entityAccessField.addSelectionListener( entityAccessFetchListener );
		entityAccessProperty.addSelectionListener( entityAccessFetchListener );
	}
	
}
