/*******************************************************************************
 * Copyright (c) 2007, 2014 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
 *     Lars Vogel <Lars.Vogel@gmail.com> - Bug 427883
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.refactoring;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
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.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.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CellLabelProvider;
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.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.window.Window;

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

import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.refactoring.descriptors.ExtractClassDescriptor;
import org.eclipse.jdt.core.refactoring.descriptors.ExtractClassDescriptor.Field;

import org.eclipse.jdt.internal.corext.refactoring.structure.ExtractClassRefactoring.ExtractClassDescriptorVerification;
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.util.SWTUtil;
import org.eclipse.jdt.internal.ui.util.TableLayoutComposite;

public class ExtractClassWizard extends RefactoringWizard {

	private ExtractClassDescriptor fDescriptor;

	public ExtractClassWizard(ExtractClassDescriptor descriptor, Refactoring refactoring) {
		super(refactoring, DIALOG_BASED_USER_INTERFACE);
		fDescriptor= descriptor;
		setDefaultPageTitle(RefactoringMessages.ExtractClassWizard_page_title);
	}

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

	private class ExtractClassUserInputWizardPage extends UserInputWizardPage {

		private static final String CREATE_GETTER_SETTER= "CREATE_GETTER_SETTER"; //$NON-NLS-1$
		private static final String CREATE_TOP_LEVEL_SETTING= "CREATE_TOPLEVEL"; //$NON-NLS-1$
		private ControlDecoration fClassNameDecoration;
		private ControlDecoration fParameterNameDecoration;

		public ExtractClassUserInputWizardPage() {
			super("ExtractClass"); //$NON-NLS-1$
			setTitle(RefactoringMessages.ExtractClassWizard_page_title);
		}

		@Override
		public void createControl(Composite parent) {
			initializeDialogUnits(parent);
			Composite result= new Composite(parent, SWT.NONE);
			result.setLayout(new GridLayout(2, false));
			createClassNameInput(result);
			createLocationInput(result);
			createTable(result);
			createGetterSetterInput(result);
			createParameterNameInput(result);
			setControl(result);
			validateRefactoring();
		}

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

			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);
			gridData.horizontalIndent= FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
			composite.setLayoutData(gridData);

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

			Button nestedRadio= new Button(composite, SWT.RADIO);
			nestedRadio.setText(Messages.format(RefactoringMessages.ExtractClassWizard_radio_nested, JavaElementLabels.getElementLabel(fDescriptor.getType(), JavaElementLabels.ALL_DEFAULT)));

			boolean createAsTopLevel= getBooleanSetting(CREATE_TOP_LEVEL_SETTING, fDescriptor.isCreateTopLevel());
			fDescriptor.setCreateTopLevel(createAsTopLevel);
			topLvlRadio.setSelection(createAsTopLevel);
			nestedRadio.setSelection(!createAsTopLevel);

		}

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

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

			});
			button.setSelection(getBooleanSetting(CREATE_GETTER_SETTER, fDescriptor.isCreateGetterSetter()));
			fDescriptor.setCreateGetterSetter(button.getSelection());
			GridData gridData= new GridData();
			gridData.horizontalSpan= 2;
			button.setLayoutData(gridData);
		}

		private void createClassNameInput(Composite result) {
			Label label= new Label(result, SWT.LEAD);
			label.setText(RefactoringMessages.ExtractClassWizard_label_class_name);
			final Text text= new Text(result, SWT.SINGLE | SWT.BORDER);
			fClassNameDecoration= new ControlDecoration(text, SWT.TOP | SWT.LEAD);
			text.setText(fDescriptor.getClassName());
			text.selectAll();
			text.setFocus();
			text.addModifyListener(e -> {
				fDescriptor.setClassName(text.getText());
				validateRefactoring();
			});
			GridData gridData= new GridData(GridData.FILL_HORIZONTAL);
			gridData.horizontalIndent= FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
			text.setLayoutData(gridData);
		}


		protected void updateDecoration(ControlDecoration decoration, RefactoringStatus status) {
			RefactoringStatusEntry highestSeverity= status.getEntryWithHighestSeverity();
			if (highestSeverity != null) {
				Image newImage= null;
				FieldDecorationRegistry registry= FieldDecorationRegistry.getDefault();
				switch (highestSeverity.getSeverity()) {
					case RefactoringStatus.INFO:
						newImage= registry.getFieldDecoration(FieldDecorationRegistry.DEC_INFORMATION).getImage();
						break;
					case RefactoringStatus.WARNING:
						newImage= registry.getFieldDecoration(FieldDecorationRegistry.DEC_WARNING).getImage();
						break;
					case RefactoringStatus.FATAL:
					case RefactoringStatus.ERROR:
						newImage= registry.getFieldDecoration(FieldDecorationRegistry.DEC_ERROR).getImage();
				}
				decoration.setDescriptionText(highestSeverity.getMessage());
				decoration.setImage(newImage);
				decoration.show();
			} else {
				decoration.setDescriptionText(null);
				decoration.hide();
			}
		}

		private void createParameterNameInput(Composite group) {
			Label l= new Label(group, SWT.NONE);
			l.setText(RefactoringMessages.ExtractClassWizard_field_name);

			final Text text= new Text(group, SWT.BORDER);
			fParameterNameDecoration= new ControlDecoration(text, SWT.TOP | SWT.LEAD);
			text.setText(fDescriptor.getFieldName());
			text.addModifyListener(e -> {
				fDescriptor.setFieldName(text.getText());
				validateRefactoring();
			});
			GridData gridData= new GridData(GridData.FILL_HORIZONTAL);
			gridData.horizontalIndent= FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
			text.setLayoutData(gridData);
		}

		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.ExtractClassWizard_label_select_fields);
			gridData= new GridData(GridData.FILL_HORIZONTAL);
			gridData.horizontalSpan= 2;
			gridData.verticalIndent= 5;
			//gridData.horizontalIndent= FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
			l.setLayoutData(gridData);
			//fFieldDecoration= new ControlDecoration(l, SWT.TOP | SWT.LEAD);

			TableLayoutComposite layoutComposite= new TableLayoutComposite(result, SWT.NONE);
			layoutComposite.addColumnData(new ColumnWeightData(40, convertWidthInCharsToPixels(20), true));
			layoutComposite.addColumnData(new ColumnWeightData(60, convertWidthInCharsToPixels(20), true));
			final CheckboxTableViewer tv= CheckboxTableViewer.newCheckList(layoutComposite, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI);
			tv.setContentProvider(ArrayContentProvider.getInstance());
			createColumns(tv);

			Table table= tv.getTable();
			table.setLinesVisible(true);
			table.setHeaderVisible(true);
			gridData= new GridData(GridData.FILL_BOTH);
			table.setLayoutData(gridData);
			Field[] fields= fDescriptor.getFields();
			tv.setInput(fields);
			for (Field field : fields) {
				tv.setChecked(field, field.isCreateField());
			}

			gridData= new GridData(GridData.FILL_BOTH);
			gridData.heightHint= SWTUtil.getTableHeightHint(table, Math.max(fields.length,5));
			gridData.widthHint= convertWidthInCharsToPixels(50);
			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 editButton= new Button(controls, SWT.NONE);
			editButton.setText(RefactoringMessages.ExtractClassWizard_button_edit);
			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;
						Field selected= (Field) ss.getFirstElement();
						String message= RefactoringMessages.ExtractClassWizard_dialog_message;
						String title= RefactoringMessages.ExtractClassWizard_dialog_title;
						InputDialog inputDialog= new InputDialog(getShell(), title, message, selected.getNewFieldName(), newText -> {
							IStatus status= JavaConventionsUtil.validateIdentifier(newText, fDescriptor.getType());
							if (!status.isOK())
								return status.getMessage();
							return null;
						});
						if (inputDialog.open() == Window.OK) {
							selected.setNewFieldName(inputDialog.getValue());
							tv.refresh(selected);
						}

					}
				}
			});
			tv.addCheckStateListener(event -> {
				Field element= (Field) event.getElement();
				element.setCreateField(event.getChecked());
				validateRefactoring();
				tv.refresh(element, true);
			});
			tv.addSelectionChangedListener(event -> {
				IStructuredSelection selection= (IStructuredSelection) tv.getSelection();
				Field field= (Field) selection.getFirstElement();
				if (selection.isEmpty()) {
					editButton.setEnabled(false);
				} else {
					editButton.setEnabled(tv.getChecked(field));
				}
			});
		}

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

			protected abstract String doGetValue(Field pi);
		}

		private abstract class FieldInfoEditingSupport extends EditingSupport {
			private CellEditor fTextEditor;

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

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

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

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

			public abstract String doGetValue(Field pi);

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

			@Override
			protected boolean canEdit(Object element) {
				if (element instanceof Field) {
					return fTextEditor != null;
				}
				return false;
			}
		}

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

			TableViewerColumn viewerColumn= new TableViewerColumn(tv, SWT.LEAD);
			viewerColumn.setLabelProvider(new FieldInfoLabelProvider() {
				@Override
				protected String doGetValue(Field pi) {
					IField field= fDescriptor.getType().getField(pi.getFieldName());
					try {
						return Signature.toString(field.getTypeSignature());
					} catch (JavaModelException e) {
						return RefactoringMessages.ExtractClassWizard_not_available;
					}
				}
			});

			TableColumn column= viewerColumn.getColumn();
			column.setText(RefactoringMessages.ExtractClassWizard_column_type);
			viewerColumn= new TableViewerColumn(tv, SWT.LEAD);
			viewerColumn.setLabelProvider(new FieldInfoLabelProvider() {
				@Override
				protected String doGetValue(Field pi) {
					if (pi.isCreateField())
						return pi.getNewFieldName();
					else
						return pi.getFieldName();
				}
			});
			viewerColumn.setEditingSupport(new FieldInfoEditingSupport(cellEditor, tv) {
				@Override
				public String doGetValue(Field pi) {
					return pi.getNewFieldName();
				}

				@Override
				public void doSetValue(Field pi, String string) {
					pi.setNewFieldName(string);
				}

				@Override
				protected boolean canEdit(Object element) {
					if (element instanceof Field) {
						Field field= (Field) element;
						return field.isCreateField();
					}
					return super.canEdit(element);
				}
			});
			column= viewerColumn.getColumn();
			column.setText(RefactoringMessages.ExtractClassWizard_column_name);
		}

		protected RefactoringStatus validateParameterName() {
			RefactoringStatus status= new RefactoringStatus();
			ExtractClassDescriptorVerification verification= getVerification();
			status.merge(verification.validateParameterName());
			updateDecoration(fParameterNameDecoration, status);
			return status;
		}

		protected RefactoringStatus validateTopLevel() {
			RefactoringStatus status= new RefactoringStatus();
			ExtractClassDescriptorVerification verification= getVerification();
			status.merge(verification.validateTopLevel());
			updateDecoration(fClassNameDecoration, status);
			return status;
		}

		protected RefactoringStatus validateClassName() {
			RefactoringStatus status= new RefactoringStatus();
			ExtractClassDescriptorVerification verification= getVerification();
			status.merge(verification.validateClassName());
			updateDecoration(fClassNameDecoration, status);
			return status;
		}

		protected RefactoringStatus validateFields() {
			RefactoringStatus status= new RefactoringStatus();
			ExtractClassDescriptorVerification verification= getVerification();
			status.merge(verification.validateFields());
			return status;
		}

		protected RefactoringStatus validateRefactoring() {
			RefactoringStatus status= new RefactoringStatus();
			setErrorMessage(null);
			setMessage(null);
			setPageComplete(true);
			status.merge(validateTopLevel());
			status.merge(validateClassName());
			status.merge(validateParameterName());
			status.merge(validateFields());
			RefactoringStatusEntry highestSeverity= status.getEntryWithHighestSeverity();
			if (highestSeverity != null) {
				switch (highestSeverity.getSeverity()) {
					case RefactoringStatus.ERROR:
					case RefactoringStatus.FATAL:
						setErrorMessage(highestSeverity.getMessage());
						setPageComplete(false);
						break;
					case RefactoringStatus.WARNING:
						setMessage(highestSeverity.getMessage(), IMessageProvider.WARNING);
						break;
					case RefactoringStatus.INFO:
						setMessage(highestSeverity.getMessage(), IMessageProvider.INFORMATION);
						break;
				}
			}
			return status;
		}

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

		@Override
		public void dispose() {
			IDialogSettings settings= getRefactoringSettings();
			settings.put(CREATE_GETTER_SETTER, fDescriptor.isCreateGetterSetter());
			settings.put(CREATE_TOP_LEVEL_SETTING, fDescriptor.isCreateTopLevel());
			super.dispose();
		}

	}

	public ExtractClassDescriptorVerification getVerification() {
		ExtractClassDescriptorVerification adapter= getRefactoring().getAdapter(ExtractClassDescriptorVerification.class);
		return adapter;
	}

}
