/*******************************************************************************
 * Copyright (c) 2007, 2013 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0, which accompanies this distribution
 * and is available at https://www.eclipse.org/legal/epl-2.0/.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/

package org.eclipse.jpt.jpa.ui.internal.wizards.gen;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jpt.jpa.gen.internal.ORMGenColumn;
import org.eclipse.jpt.jpa.gen.internal.ORMGenCustomizer;
import org.eclipse.jpt.jpa.ui.internal.plugin.JptJpaUiPlugin;
import org.eclipse.jpt.jpa.ui.wizards.gen.JptJpaUiWizardsEntityGenMessages;
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.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.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Text;

/**
 * The panel used in the <code>TablesAndColumnsPage</code> wizard page 
 * to edit the column generation properties.
 * An instance of this class is created by the <code>ORMGenWizard</code> 
 * implementation.

 */
public class ColumnGenPanel 
{
	TablesAndColumnsCustomizationWizardPage wizardPage ; 
	Composite parent;	//parent control with grid layout
	int columns; 		//total columns in the parent composite
	
	ORMGenCustomizer customizer;
	
	private ORMGenColumn mColumn;
	private boolean mPanelInited;
	private boolean mIsUpdatingControls;
	
	private Group columnMappingGroup;
	private Button mGeneratedCheckbox;
	private Text mPropNameField;
	private Combo mMappingKindCombo;
	private Combo mPropTypeCombo;
	private Button mUpdateableCheckBox;
	private Button mInsertableCheckBox;
	
	private Group domainClassGroup ;
	private ScopePanel mPropGetScopePanel;
	private ScopePanel mPropSetScopePanel;
	
	private boolean isDynamic;
	
	public ColumnGenPanel(Composite parent, int columns, ORMGenCustomizer customizer, TablesAndColumnsCustomizationWizardPage wizardPage, boolean isDynamic) {
		this.wizardPage = wizardPage;
		this.customizer = customizer;
		this.parent =parent;
		this.columns = columns;
		this.isDynamic = isDynamic;
		
		initPanel();
	}
	/**
	 * Changes the table edited by the panel.
	 * This is supposed to update the panel editing controls 
	 * using the column values.
	 */
	public void setColumn(ORMGenColumn column) {
		mColumn = column;
		
		/*lazy init panel because it uses mColumn*/
		if (!mPanelInited) {
			initPanel();
			mPanelInited = true;
		}
		
		updateControls();
	}
	private void updateControls() {
		if (mIsUpdatingControls) {
			return;
		}
		
		mIsUpdatingControls = true;
		boolean isGenerated = mColumn.isGenerated();
		mGeneratedCheckbox.setSelection( isGenerated);
		mGeneratedCheckbox.setEnabled(true);
		enableControls(isGenerated);
		try {
			mPropNameField.setText(mColumn.getPropertyName());

			mPropTypeCombo.setText( mColumn.getPropertyType());
			
			mMappingKindCombo.setText( mColumn.getMappingKind());
			
			mUpdateableCheckBox.setSelection( mColumn.isUpdateable());
			
			mInsertableCheckBox.setSelection(mColumn.isInsertable());
			
			if(!this.isDynamic){
				mPropGetScopePanel.enableComponents(isGenerated);
				mPropGetScopePanel.setScope(mColumn.getPropertyGetScope());
				
				mPropSetScopePanel.enableComponents( isGenerated );
				mPropSetScopePanel.setScope(mColumn.getPropertySetScope());
			}

			if( mColumn.isPartOfCompositePrimaryKey()){
				enableControls(false);
				mPropNameField.setEnabled(true);
				mGeneratedCheckbox.setEnabled(false);
			}
			
		} catch (Exception e) {
			JptJpaUiPlugin.instance().logError(e);
		} finally {
			mIsUpdatingControls = false;
		}
	}
	private void enableControls(boolean isGenerated) {
		Control[] controls;
		if(!this.isDynamic) {
			controls = this.domainClassGroup.getChildren();
			for( Control c: controls){
				c.setEnabled( isGenerated );
			}
		}

		controls = this.columnMappingGroup.getChildren();
		for( Control c: controls){
			c.setEnabled( isGenerated );
		}
	}
	/**
	 * Initializes the panel by adding the editing controls.
	 * @param columns 
	 * @param parent 
	 */
	protected void initPanel() {
		createControls(parent, columns);
		this.mPanelInited = true;
	}
	
	//-------------------------------------------
	//----- ScopePanel class --------------------
	//-------------------------------------------
	/**
	 * A panel containing 3 radios (public, protected, private)
	 */
	private class ScopePanel 
	{
		private Button mPublicRadio;
		private Button mProtectedRadio;
		private Button mPrivateRadio;
		
		public ScopePanel(Composite comp, SelectionListener listener) {
			//super(3, 20/*hspacing*/, 0/*vspacing*/);
			
			Composite radioGroup = new Composite( comp, SWT.NONE);
			radioGroup.setLayout(new GridLayout(3, true));
			GridData gd = new GridData();
			gd.horizontalSpan = 3;
			radioGroup.setLayoutData(gd);
			
			/*string not localized intentionally, they are used as the actual 
			 * scope value (see getText() usage)*/
			mPublicRadio = new Button( radioGroup, SWT.RADIO );
			mPublicRadio.setText( "public");
			mPublicRadio.setLayoutData(new GridData());
			mProtectedRadio = new Button( radioGroup, SWT.RADIO );
			mProtectedRadio.setText("protected");
			mProtectedRadio.setLayoutData(new GridData());
			mPrivateRadio = new Button(radioGroup, SWT.RADIO );
			mPrivateRadio.setText( "private");
			mPrivateRadio.setLayoutData(new GridData());
			
			mPublicRadio.addSelectionListener(listener);
			mProtectedRadio.addSelectionListener(listener);
			mPrivateRadio.addSelectionListener(listener);
				
		}
		public void enableComponents(boolean b) {
			mPublicRadio.setEnabled(b);
			mProtectedRadio.setEnabled(b);
			mPrivateRadio.setEnabled(b);
		}
		/**
		 * Returns the currently selected scope.
		 */
		public String getScope() {
			Button radio = null;
			if (mPublicRadio.getSelection()) {
				radio = mPublicRadio;
			} else if (mProtectedRadio.getSelection() ) {
				radio = mProtectedRadio;
			} else if (mPrivateRadio.getSelection() ) {
				radio = mPrivateRadio;
			}
			return radio != null ? radio.getText() : null;
		}
		public void setScope(String scope) {
			mPublicRadio.setSelection(false);
			mProtectedRadio.setSelection(false);
			mPrivateRadio.setSelection(false);
			if( scope == null )
				return;
			if (scope.equals(ORMGenColumn.PUBLIC_SCOPE)) {
				mPublicRadio.setSelection(true);
			} else if (scope.equals(ORMGenColumn.PROTECTED_SCOPE)) {
				mProtectedRadio.setSelection(true);
			} else if (scope.equals(ORMGenColumn.PRIVATE_SCOPE)) {
				mPrivateRadio.setSelection(true);
			}
		}
	}
	
	//-------------------------------------------
	//----- private methods ---------------------
	//-------------------------------------------
	private void createControls(Composite composite, int columns) {
		mGeneratedCheckbox = new Button(composite, SWT.CHECK);
		mGeneratedCheckbox.setText( JptJpaUiWizardsEntityGenMessages.GENERATE_ENTITIES_WIZARD_COL_PANEL_GEN_PROP);
		mGeneratedCheckbox.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {}
			public void widgetSelected(SelectionEvent e) {
				if (!mIsUpdatingControls) {
					mColumn.setGenerated(mGeneratedCheckbox.getSelection() );
					updateControls();
				}
			}});
		SWTUtil.fillColumns(mGeneratedCheckbox, columns);
		
		columnMappingGroup = new Group( composite, SWT.NONE);
		columnMappingGroup.setText( JptJpaUiWizardsEntityGenMessages.GENERATE_ENTITIES_WIZARD_COL_PANEL_COL_MAPPING);
		columnMappingGroup.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;
		layoutData.horizontalIndent = 20 ;
		columnMappingGroup.setLayoutData(layoutData);
		
		SWTUtil.createLabel(columnMappingGroup, 1, JptJpaUiWizardsEntityGenMessages.GENERATE_ENTITIES_WIZARD_COL_PANEL_PROP_NAME );
		mPropNameField = new Text(columnMappingGroup, SWT.BORDER | SWT.SINGLE );
		mPropNameField.addModifyListener(new ModifyListener(){
			@SuppressWarnings("restriction")
			public void modifyText(ModifyEvent e) {
				if (!mIsUpdatingControls) {
					String fldName = mPropNameField.getText();
					IStatus status = JavaConventions.validateIdentifier( fldName, 
						JavaCore.VERSION_1_3, JavaCore.VERSION_1_3 );
					if( !status.matches(IStatus.ERROR)){
						mColumn.setPropertyName(fldName);
						wizardPage.setErrorMessage(null);
					}else{
						wizardPage.setErrorMessage(status.getMessage());
					}
				}
			}			
		});
		SWTUtil.fillColumns(mPropNameField ,3);
		
		SWTUtil.createLabel(columnMappingGroup, 1, JptJpaUiWizardsEntityGenMessages.GENERATE_ENTITIES_WIZARD_COL_PANEL_PROP_TYPE );
		mPropTypeCombo = new Combo(columnMappingGroup, SWT.SINGLE | SWT.READ_ONLY);
		mPropTypeCombo.setItems( this.customizer.getAllPropertyTypes());
		mPropTypeCombo.addModifyListener( new ModifyListener(){
			public void modifyText(ModifyEvent e) {
				if (!mIsUpdatingControls) {
					mColumn.setPropertyType(mPropTypeCombo.getText());
				}
			}
		});
		SWTUtil.fillColumns(mPropTypeCombo,3);
		
		SWTUtil.createLabel(columnMappingGroup, 1, JptJpaUiWizardsEntityGenMessages.GENERATE_ENTITIES_WIZARD_COL_PANEL_MAP_KIND );
		mMappingKindCombo = new Combo(columnMappingGroup, SWT.SINGLE | SWT.READ_ONLY);
		mMappingKindCombo.setItems( this.customizer.getAllMappingKinds());
		mMappingKindCombo.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {}
			public void widgetSelected(SelectionEvent e) {
				if (!mIsUpdatingControls) {
					mColumn.setMappingKind((String)mMappingKindCombo.getText());
				}
				
			}});
		SWTUtil.fillColumns(mMappingKindCombo ,3);
		
		mUpdateableCheckBox = new Button(columnMappingGroup, SWT.CHECK);
		mUpdateableCheckBox.setText( JptJpaUiWizardsEntityGenMessages.GENERATE_ENTITIES_WIZARD_COL_PANEL_COL_UPDATEABLE);
		mUpdateableCheckBox.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {}
			public void widgetSelected(SelectionEvent e) {
				if (!mIsUpdatingControls) {
					mColumn.setUpdateable(mUpdateableCheckBox.getSelection() );
				}
			}});
		SWTUtil.fillColumns(mUpdateableCheckBox ,4);
		
		mInsertableCheckBox = new Button(columnMappingGroup, SWT.CHECK);
		mInsertableCheckBox.setText( JptJpaUiWizardsEntityGenMessages.GENERATE_ENTITIES_WIZARD_COL_PANEL_COL_INSERTABLE);
		mInsertableCheckBox.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {}
			public void widgetSelected(SelectionEvent e) {
				if (!mIsUpdatingControls) {
					mColumn.setInsertable(mInsertableCheckBox.getSelection());
				}
			}});
		SWTUtil.fillColumns(mInsertableCheckBox ,4);
		
		SWTUtil.createLabel(composite, 4,""); 
		if (!this.wizardPage.isDynamic()) {
			createJavaBeanPropertyControls(composite, columns);
		}
	}
	
	void createJavaBeanPropertyControls(Composite composite, int columns){
		//Java class generation properties 
		domainClassGroup = new Group(composite, SWT.NONE);
		domainClassGroup.setText( JptJpaUiWizardsEntityGenMessages.GENERATE_ENTITIES_WIZARD_COL_PANEL_BEAN_PROP );
		domainClassGroup.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;
		layoutData.horizontalIndent = 20;
		domainClassGroup.setLayoutData(layoutData);

		SWTUtil.createLabel(domainClassGroup, 1, JptJpaUiWizardsEntityGenMessages.GENERATE_ENTITIES_WIZARD_COL_PANEL_GETTER_SCOPE );
		mPropGetScopePanel = new ScopePanel(domainClassGroup, new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {}

			public void widgetSelected(SelectionEvent e) {
				if (!mIsUpdatingControls) {
					if( ((Button)e.getSource()).getSelection() )
						mColumn.setPropertyGetScope(mPropGetScopePanel.getScope());
				}
				
			}});
		
		SWTUtil.createLabel(domainClassGroup, 1, JptJpaUiWizardsEntityGenMessages.GENERATE_ENTITIES_WIZARD_COL_PANEL_SETTER_SCOPE );
		mPropSetScopePanel = new ScopePanel(domainClassGroup, new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {}

			public void widgetSelected(SelectionEvent e) {
				if (!mIsUpdatingControls) {
					if( ((Button)e.getSource()).getSelection() )
						mColumn.setPropertySetScope(mPropSetScopePanel.getScope());
				}
			}});
		
	}
}
