/*******************************************************************************
 * Copyright (c) 2007, 2016 IBM Corporation and others.
 *
 * 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/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.refactoring;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;

import org.eclipse.core.runtime.IStatus;

import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.window.Window;

import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;

import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
import org.eclipse.jdt.internal.corext.refactoring.ParameterInfo;
import org.eclipse.jdt.internal.corext.refactoring.structure.ChangeSignatureProcessor;
import org.eclipse.jdt.internal.corext.refactoring.structure.IntroduceParameterObjectProcessor;
import org.eclipse.jdt.internal.corext.util.JavaConventionsUtil;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.JavaElementLabels;

import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer;
import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
import org.eclipse.jdt.internal.ui.util.SWTUtil;

public class IntroduceParameterObjectWizard extends RefactoringWizard {

	private final IntroduceParameterObjectProcessor fProcessor;

	public IntroduceParameterObjectWizard(IntroduceParameterObjectProcessor processor, Refactoring refactoring) {
		super(refactoring, DIALOG_BASED_USER_INTERFACE);
		fProcessor= processor;
		setDefaultPageTitle(RefactoringMessages.IntroduceParameterObjectWizard_wizardpage_title);
	}

	@Override
	protected void addUserInputPages() {
		addPage(new IntroduceParameterObjectInputPage(fProcessor));
	}

	private static class IntroduceParameterObjectInputPage extends UserInputWizardPage {

		private static final String CREATE_TOP_LEVEL_SETTING= "CreateTopLevel"; //$NON-NLS-1$
		private static final String CREATE_SETTERS_SETTING= "CreateSetters"; //$NON-NLS-1$
		private static final String CREATE_GETTERS_SETTING= "CreateGetters"; //$NON-NLS-1$

		private final class ParameterObjectCreatorContentProvider implements IStructuredContentProvider {
			@Override
			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			}

			@Override
			public void dispose() {
			}

			@Override
			public Object[] getElements(Object inputElement) {
				if (inputElement instanceof IntroduceParameterObjectProcessor) {
					IntroduceParameterObjectProcessor refactoring= (IntroduceParameterObjectProcessor) inputElement;
					List<ParameterInfo> parameterInfos= refactoring.getParameterInfos();
					List<ParameterInfo> result= new ArrayList<>(parameterInfos.size());
					for (ParameterInfo pi : parameterInfos) {
						if (!pi.isAdded())
							result.add(pi);
					}
					return result.toArray();
				}
				return null;
			}
		}

		private abstract class ParameterInfoLabelProvider extends CellLabelProvider {
			@Override
			public void update(ViewerCell cell) {
				ParameterInfo pi= (ParameterInfo) cell.getElement();
				cell.setText(doGetValue(pi));
			}

			protected abstract String doGetValue(ParameterInfo pi);
		}

		private abstract class ParameterInfoEditingSupport extends EditingSupport {
			private CellEditor fTextEditor;

			private ParameterInfoEditingSupport(CellEditor textEditor, ColumnViewer tv) {
				super(tv);
				fTextEditor= textEditor;
			}

			@Override
			protected void setValue(Object element, Object value) {
				if (element instanceof ParameterInfo) {
					ParameterInfo pi= (ParameterInfo) element;
					doSetValue(pi, value.toString());
					getViewer().update(element, null);
				}
				validateRefactoring();
				updateSignaturePreview();
			}

			public abstract void doSetValue(ParameterInfo pi, String string);

			@Override
			protected Object getValue(Object element) {
				if (element instanceof ParameterInfo) {
					ParameterInfo pi= (ParameterInfo) element;
					return doGetValue(pi);
				}
				return null;
			}

			public abstract String doGetValue(ParameterInfo pi);

			@Override
			protected CellEditor getCellEditor(Object element) {
				return fTextEditor;
			}

			@Override
			protected boolean canEdit(Object element) {
				if (element instanceof ParameterInfo) {
					ParameterInfo pi= (ParameterInfo) element;
					return fTextEditor!=null && pi.isCreateField();
				}
				return false;
			}
		}

		private IntroduceParameterObjectProcessor fProcessor;
		private JavaSourceViewer fSignaturePreview;
		private Button fLeaveDelegateCheckBox;
		private Button fDeprecateDelegateCheckBox;

		public IntroduceParameterObjectInputPage(IntroduceParameterObjectProcessor processor) {
			super(RefactoringMessages.IntroduceParameterObjectWizard_wizardpage_name);
			fProcessor= processor;
			setTitle(RefactoringMessages.IntroduceParameterObjectWizard_wizardpage_title);
			setDescription(RefactoringMessages.IntroduceParameterObjectWizard_wizardpage_description);
		}

		@Override
		public void createControl(Composite parent) {
			initializeDialogUnits(parent);
			Composite result= new Composite(parent, SWT.NONE);
			result.setLayout(new GridLayout(2, false));
			Group group= createGroup(result, RefactoringMessages.IntroduceParameterObjectWizard_type_group);

			createClassNameInput(group);
			createLocationInput(group);

			createTable(group);
			createGetterInput(group);
			createSetterInput(group);

			group= createGroup(result, RefactoringMessages.IntroduceParameterObjectWizard_method_group);
			createParameterNameInput(group);
			createDelegateInput(group);
			createSignaturePreview(group);

			validateRefactoring();

			setControl(result);
		}

		private void createParameterNameInput(Group group) {
			Label l= new Label(group, SWT.NONE);
			l.setText(RefactoringMessages.IntroduceParameterObjectWizard_parameterfield_label);
			final Text text= new Text(group, SWT.BORDER);
			text.setText(fProcessor.getParameterName());
			text.addModifyListener(e -> {
				fProcessor.setParameterName(text.getText());
				updateSignaturePreview();
				validateRefactoring();
			});
			text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		}

		protected void validateRefactoring() {
			List<String> names= new ArrayList<>();
			boolean oneChecked= false;
			setMessage(null);
			setErrorMessage(null);
			setPageComplete(true);
			IJavaProject project= fProcessor.getMethod().getJavaProject();
			String sourceLevel= project.getOption(JavaCore.COMPILER_SOURCE, true);
			String compliance= project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
			String previewEnabled= project.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);

			for (ParameterInfo pi : fProcessor.getParameterInfos()) {
				if (names.contains(pi.getNewName())) {
					setErrorMessage(Messages.format(RefactoringMessages.IntroduceParameterObjectWizard_parametername_check_notunique, BasicElementLabels.getJavaElementName(pi.getNewName())));
					setPageComplete(false);
					return;
				}
				names.add(pi.getNewName());
				IStatus validateIdentifier= JavaConventions.validateIdentifier(pi.getNewName(), sourceLevel, compliance);
				if (isErrorMessage(validateIdentifier))
					return;
				if (pi.isCreateField())
					oneChecked= true;
			}
			if (!oneChecked) {
				setErrorMessage(RefactoringMessages.IntroduceParameterObjectWizard_parametername_check_atleastoneparameter);
				setPageComplete(false);
				return;
			}
			IStatus validateJavaTypeName= JavaConventions.validateJavaTypeName(fProcessor.getClassName(), sourceLevel, compliance, previewEnabled);
			if (isErrorMessage(validateJavaTypeName))
				return;
			if (fProcessor.getClassName().indexOf('.') != -1) {
				setErrorMessage(RefactoringMessages.IntroduceParameterObjectWizard_dot_not_allowed_error);
				setPageComplete(false);
			}
			if (!"".equals(fProcessor.getPackage())) { //$NON-NLS-1$
				IStatus validatePackageName= JavaConventions.validatePackageName(fProcessor.getPackage(), sourceLevel, compliance);
				if (isErrorMessage(validatePackageName))
					return;
			}
			try {
				IType type= project.findType(fProcessor.getNewTypeName());
				if (type != null) {
					String packageLabel= JavaElementLabels.getElementLabel(type.getPackageFragment(), JavaElementLabels.ALL_DEFAULT);
					if (fProcessor.isCreateAsTopLevel()) {
						setErrorMessage(Messages.format(RefactoringMessages.IntroduceParameterObjectWizard_type_already_exists_in_package_info,
								new Object[] { BasicElementLabels.getJavaElementName(fProcessor.getClassName()), packageLabel }));
						setPageComplete(false);
						return;
					} else {
						setErrorMessage(Messages.format(RefactoringMessages.IntroduceParameterObjectWizard_parametername_check_alreadyexists,
								new Object[] { BasicElementLabels.getJavaElementName(fProcessor.getClassName()), BasicElementLabels.getFileName(type.getCompilationUnit()) }));
						setPageComplete(false);
						return;
					}
				}
			} catch (JavaModelException e) {
				// Don't care. The error will popup later anyway..
			}
		}

		private boolean isErrorMessage(IStatus validationStatus) {
			if (!validationStatus.isOK()) {
				if (validationStatus.getSeverity() == IStatus.ERROR) {
					setErrorMessage(validationStatus.getMessage());
					setPageComplete(false);
					return true;
				} else {
					if (validationStatus.getSeverity() == IStatus.INFO)
						setMessage(validationStatus.getMessage(), IMessageProvider.INFORMATION);
					else
						setMessage(validationStatus.getMessage(), IMessageProvider.WARNING);
				}
			}
			return false;
		}

		private void createSignaturePreview(Composite composite) {
			Label previewLabel= new Label(composite, SWT.NONE);
			previewLabel.setText(RefactoringMessages.IntroduceParameterObjectWizard_signaturepreview_label);
			GridData gridData= new GridData(GridData.FILL_HORIZONTAL);
			gridData.horizontalSpan= 2;
			previewLabel.setLayoutData(gridData);

			fSignaturePreview= InputPageUtil.createSignaturePreview(composite);
			((GridData) fSignaturePreview.getControl().getLayoutData()).horizontalSpan= 2;

			updateSignaturePreview();
		}

		private void createDelegateInput(Group group) {
			fLeaveDelegateCheckBox= DelegateUIHelper.generateLeaveDelegateCheckbox(group, getRefactoring(), false);
			GridData gridData= new GridData(GridData.FILL_HORIZONTAL);
			gridData.horizontalSpan= 2;
			fLeaveDelegateCheckBox.setLayoutData(gridData);
			if (fLeaveDelegateCheckBox != null) {
				fDeprecateDelegateCheckBox= new Button(group, SWT.CHECK);
				GridData data= new GridData();
				data.horizontalAlignment= GridData.FILL;
				GridLayout layout= (GridLayout) group.getLayout();
				data.horizontalIndent= (layout.marginWidth + fDeprecateDelegateCheckBox.computeSize(SWT.DEFAULT, SWT.DEFAULT).x);
				data.horizontalSpan= 2;
				fDeprecateDelegateCheckBox.setLayoutData(data);
				fDeprecateDelegateCheckBox.setText(DelegateUIHelper.getDeprecateDelegateCheckBoxTitle());
				final ChangeSignatureProcessor refactoring= fProcessor;
				fDeprecateDelegateCheckBox.setSelection(DelegateUIHelper.loadDeprecateDelegateSetting(refactoring));
				refactoring.setDeprecateDelegates(fDeprecateDelegateCheckBox.getSelection());
				fDeprecateDelegateCheckBox.addSelectionListener(new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						refactoring.setDeprecateDelegates(fDeprecateDelegateCheckBox.getSelection());
						validateRefactoring();
					}
				});
				fDeprecateDelegateCheckBox.setEnabled(fLeaveDelegateCheckBox.getSelection());
				fLeaveDelegateCheckBox.addSelectionListener(new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						fDeprecateDelegateCheckBox.setEnabled(fLeaveDelegateCheckBox.getSelection());
					}
				});
			}
		}

		private Group createGroup(Composite result, String caption) {
			Group group= new Group(result, SWT.None);
			group.setLayout(new GridLayout(2, false));
			group.setText(caption);
			GridData gridData= new GridData(GridData.FILL_BOTH);
			gridData.horizontalSpan= 2;
			group.setLayoutData(gridData);
			return group;
		}

		private void createLocationInput(Composite parent) {
			Label l= new Label(parent, SWT.NONE);
			l.setText(RefactoringMessages.IntroduceParameterObjectWizard_destination_label);

			Composite composite= new Composite(parent, SWT.None);
			GridLayout gridLayout= new GridLayout(2, false);
			gridLayout.marginHeight= 0;
			gridLayout.marginWidth= 0;
			composite.setLayout(gridLayout);
			GridData gridData= new GridData(GridData.FILL_HORIZONTAL);
			composite.setLayoutData(gridData);

			final Button topLvlRadio= new Button(composite, SWT.RADIO);
			topLvlRadio.setText(RefactoringMessages.IntroduceParameterObjectWizard_createastoplevel_radio);
			topLvlRadio.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					boolean fAsTopLevel= topLvlRadio.getSelection();
					fProcessor.setCreateAsTopLevel(fAsTopLevel);
					updateSignaturePreview();
					validateRefactoring();
				}
			});

			Button nestedRadio= new Button(composite, SWT.RADIO);
			nestedRadio.setText(Messages.format(RefactoringMessages.IntroduceParameterObjectWizard_createasnestedclass_radio, BasicElementLabels.getJavaElementName(fProcessor.getContainingClass().getName())));
			boolean createAsTopLevel= getBooleanSetting(CREATE_TOP_LEVEL_SETTING, fProcessor.isCreateAsTopLevel());
			fProcessor.setCreateAsTopLevel(createAsTopLevel);
			topLvlRadio.setSelection(createAsTopLevel);
			nestedRadio.setSelection(!createAsTopLevel);

		}

		private void createTable(Composite parent) {
			Composite result= new Composite(parent, SWT.NONE);
			GridLayout layout= new GridLayout(2, false);
			layout.marginHeight= 0;
			layout.marginWidth= 0;
			result.setLayout(layout);
			GridData gridData= new GridData(GridData.FILL_BOTH);
			gridData.horizontalSpan= 2;
			result.setLayoutData(gridData);

			Label l= new Label(result, SWT.NONE);
			l.setText(RefactoringMessages.IntroduceParameterObjectWizard_fields_selection_label);
			gridData= new GridData(GridData.FILL_HORIZONTAL);
			gridData.horizontalSpan= 2;
			gridData.verticalIndent= 5;
			l.setLayoutData(gridData);

			Composite layoutComposite= new Composite(result, SWT.NONE);
			final CheckboxTableViewer tv= CheckboxTableViewer.newCheckList(layoutComposite, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI);
			tv.setContentProvider(new ParameterObjectCreatorContentProvider());
			createColumns(tv);

			Table table= tv.getTable();
			table.setLinesVisible(true);
			table.setHeaderVisible(true);
			gridData= new GridData(GridData.FILL_BOTH);
			table.setLayoutData(gridData);
			tv.setInput(fProcessor);
			List<ParameterInfo> parameterInfos= fProcessor.getParameterInfos();
			for (ParameterInfo pi : parameterInfos) {
				tv.setChecked(pi, pi.isCreateField());
			}
			tv.refresh(true);
			gridData= new GridData(GridData.FILL_BOTH);
			gridData.heightHint= SWTUtil.getTableHeightHint(table, parameterInfos.size());
			gridData.widthHint= convertWidthInCharsToPixels(30);
			layoutComposite.setLayoutData(gridData);
			Composite controls= new Composite(result, SWT.NONE);
			gridData= new GridData(GridData.FILL, GridData.FILL, false, false);
			controls.setLayoutData(gridData);
			GridLayout gridLayout= new GridLayout();
			gridLayout.marginHeight= 0;
			gridLayout.marginWidth= 0;
			controls.setLayout(gridLayout);

			final Button upButton= new Button(controls, SWT.NONE);
			upButton.setText(RefactoringMessages.IntroduceParameterObjectWizard_moveentryup_button);
			gridData= new GridData(GridData.FILL_HORIZONTAL);
			upButton.setLayoutData(gridData);
			SWTUtil.setButtonDimensionHint(upButton);
			upButton.setEnabled(false);

			final Button downButton= new Button(controls, SWT.NONE);
			downButton.setText(RefactoringMessages.IntroduceParameterObjectWizard_moventrydown_button);
			gridData= new GridData(GridData.FILL_HORIZONTAL);
			downButton.setLayoutData(gridData);
			SWTUtil.setButtonDimensionHint(downButton);
			downButton.setEnabled(false);

			addSpacer(controls);

			final Button editButton= new Button(controls, SWT.NONE);
			editButton.setText(RefactoringMessages.IntroduceParameterObjectWizard_edit_button);
			editButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			editButton.setEnabled(!tv.getSelection().isEmpty());
			SWTUtil.setButtonDimensionHint(editButton);
			editButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					ISelection selection= tv.getSelection();
					if (selection instanceof IStructuredSelection) {
						IStructuredSelection ss= (IStructuredSelection) selection;
						ParameterInfo selected= (ParameterInfo) ss.getFirstElement();
						String message= RefactoringMessages.IntroduceParameterObjectWizard_fieldname_message;
						String title= RefactoringMessages.IntroduceParameterObjectWizard_fieldname_title;
						InputDialog inputDialog= new InputDialog(getShell(), title, message, selected.getNewName(), newText -> {
							IStatus status= JavaConventionsUtil.validateIdentifier(newText, fProcessor.getCompilationUnit());
							if (!status.isOK())
								return status.getMessage();
							return null;
						});
						if (inputDialog.open() == Window.OK) {
							selected.setNewName(inputDialog.getValue());
							tv.refresh(selected);
							updateSignaturePreview();
						}

					}
				}
			});

			downButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					int[] indices= tv.getTable().getSelectionIndices();
					Arrays.sort(indices);
					for (int i= indices.length-1; i >=0; i--) {
						int idx= indices[i];
						ParameterInfo pi= (ParameterInfo) tv.getElementAt(idx);
						fProcessor.moveFieldDown(pi);
					}
					tv.refresh();
					updateButtons(tv, upButton, downButton, editButton);
				}

			});
			upButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					int[] indices= tv.getTable().getSelectionIndices();
					Arrays.sort(indices);
					for (int idx : indices) {
						ParameterInfo pi= (ParameterInfo) tv.getElementAt(idx);
						fProcessor.moveFieldUp(pi);
					}
					tv.refresh();
					updateButtons(tv, upButton, downButton, editButton);
				}

			});
			tv.addCheckStateListener(new ICheckStateListener() {
				Map<ParameterInfo, String> fLastNames=new HashMap<>();
				@Override
				public void checkStateChanged(CheckStateChangedEvent event) {
					ParameterInfo element= (ParameterInfo) event.getElement();
					element.setCreateField(event.getChecked());
					if (element.isCreateField()){
						String lastName= fLastNames.get(element);
						if (lastName==null){
							lastName= fProcessor.getFieldName(element);
						}
						element.setNewName(lastName);
					} else {
						fLastNames.put(element, element.getNewName());
						element.setNewName(element.getOldName());
					}
					tv.update(element, null);
					updateButtons(tv, upButton, downButton, editButton);
					validateRefactoring();
				}

			});
			tv.addSelectionChangedListener(event -> updateButtons(tv, upButton, downButton, editButton));
		}

		private void addSpacer(Composite parent) {
			Label label= new Label(parent, SWT.NONE);
			GridData gd= new GridData(GridData.FILL_HORIZONTAL);
			gd.heightHint= 5;
			label.setLayoutData(gd);
		}

		private void createColumns(final CheckboxTableViewer tv) {
			TextCellEditor cellEditor= new TextCellEditor(tv.getTable());

			TableViewerColumn viewerColumn= new TableViewerColumn(tv, SWT.LEAD);
			viewerColumn.setLabelProvider(new ParameterInfoLabelProvider() {
				@Override
				protected String doGetValue(ParameterInfo pi) {
					return pi.getNewTypeName();
				}
			});

			TableColumn columnType= viewerColumn.getColumn();
			columnType.setText(RefactoringMessages.IntroduceParameterObjectWizard_type_column);
			viewerColumn= new TableViewerColumn(tv, SWT.LEAD);
			viewerColumn.setLabelProvider(new ParameterInfoLabelProvider() {
				@Override
				protected String doGetValue(ParameterInfo pi) {
					return pi.getNewName();
				}
			});
			viewerColumn.setEditingSupport(new ParameterInfoEditingSupport(cellEditor, tv) {
				@Override
				public String doGetValue(ParameterInfo pi) {
					return pi.getNewName();
				}
				@Override
				public void doSetValue(ParameterInfo pi, String string) {
					pi.setNewName(string);
				}
			});

			TableColumn columnName= viewerColumn.getColumn();
			columnName.setText(RefactoringMessages.IntroduceParameterObjectWizard_name_column);

			TableColumnLayout layout= new TableColumnLayout();
			layout.setColumnData(columnType, new ColumnWeightData(50, convertWidthInCharsToPixels(20), true));
			layout.setColumnData(columnName, new ColumnWeightData(50, convertWidthInCharsToPixels(20), true));
			tv.getTable().getParent().setLayout(layout);
		}

		private void createGetterInput(Composite result) {
			Composite buttons= new Composite(result, SWT.NONE);
			GridLayout gridLayout= new GridLayout(2, true);
			gridLayout.marginHeight= 0;
			gridLayout.marginWidth= 0;
			buttons.setLayout(gridLayout);
			GridData gridData= new GridData();
			gridData.horizontalSpan= 2;
			buttons.setLayoutData(gridData);

			final Button button= new Button(buttons, SWT.CHECK);
			button.setText(RefactoringMessages.IntroduceParameterObjectWizard_creategetter_checkbox);
			button.addSelectionListener(new SelectionAdapter() {

				@Override
				public void widgetSelected(SelectionEvent e) {
					fProcessor.setCreateGetter(button.getSelection());
					validateRefactoring();
				}

			});
			button.setSelection(getBooleanSetting(CREATE_GETTERS_SETTING, fProcessor.isCreateGetter()));
			fProcessor.setCreateGetter(button.getSelection());
			gridData= new GridData();
			button.setLayoutData(gridData);
		}

		private void createSetterInput(Composite result) {
			final Button button= new Button(result, SWT.CHECK);
			button.setText(RefactoringMessages.IntroduceParameterObjectWizard_createsetter_checkbox);
			button.addSelectionListener(new SelectionAdapter() {

				@Override
				public void widgetSelected(SelectionEvent e) {
					fProcessor.setCreateSetter(button.getSelection());
					validateRefactoring();
				}

			});
			button.setSelection(getBooleanSetting(CREATE_SETTERS_SETTING, fProcessor.isCreateSetter()));
			fProcessor.setCreateSetter(button.getSelection());
			GridData gridData= new GridData();
			button.setLayoutData(gridData);
		}

		private void createClassNameInput(Composite result) {
			Label label= new Label(result, SWT.LEAD);
			label.setText(RefactoringMessages.IntroduceParameterObjectWizard_classnamefield_label);
			final Text text= new Text(result, SWT.SINGLE | SWT.BORDER);
			text.setText(fProcessor.getClassName());
			text.selectAll();
			text.setFocus();
			text.addModifyListener(e -> {
				fProcessor.setClassName(text.getText());
				updateSignaturePreview();
				validateRefactoring();
			});
			text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		}

		private void updateButtons(final TableViewer tv, Button upButton, Button downButton, Button editButton) {
			IStructuredSelection selection= (IStructuredSelection) tv.getSelection();
			ParameterInfo firstElement= (ParameterInfo) selection.getFirstElement();
			if (selection.isEmpty()) {
				upButton.setEnabled(false);
				downButton.setEnabled(false);
				editButton.setEnabled(false);
			} else {
				int[] selectionIndex= tv.getTable().getSelectionIndices();
				upButton.setEnabled(selectionIndex[0] != 0);
				downButton.setEnabled(selectionIndex[selectionIndex.length-1] != tv.getTable().getItemCount() - 1);
				editButton.setEnabled(firstElement.isCreateField() && selectionIndex.length==1);
			}
			fProcessor.updateParameterPosition();
			updateSignaturePreview();
		}

		private void updateSignaturePreview() {
			try {
				int top= fSignaturePreview.getTextWidget().getTopPixel();
				fSignaturePreview.getDocument().set(fProcessor.getNewMethodSignature());
				fSignaturePreview.getTextWidget().setTopPixel(top);
			} catch (JavaModelException e) {
				ExceptionHandler.handle(e, RefactoringMessages.IntroduceParameterObjectWizard_error_title, RefactoringMessages.IntroduceParameterObjectWizard_error_description);
			}
		}

		@Override
		public void dispose() {
			DelegateUIHelper.saveDeprecateDelegateSetting(fDeprecateDelegateCheckBox);
			DelegateUIHelper.saveLeaveDelegateSetting(fLeaveDelegateCheckBox);
			IDialogSettings settings= getRefactoringSettings();
			settings.put(IntroduceParameterObjectInputPage.CREATE_GETTERS_SETTING, fProcessor.isCreateGetter());
			settings.put(IntroduceParameterObjectInputPage.CREATE_SETTERS_SETTING, fProcessor.isCreateSetter());
			settings.put(IntroduceParameterObjectInputPage.CREATE_TOP_LEVEL_SETTING, fProcessor.isCreateAsTopLevel());
			super.dispose();
		}

		protected boolean getBooleanSetting(String key, boolean defaultValue) {
			String update= getRefactoringSettings().get(key);
			if (update != null)
				return Boolean.parseBoolean(update);
			else
				return defaultValue;
		}
	}

}
