/*******************************************************************************
 * Copyright (c) 2000, 2019 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.sef;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Text;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.window.Window;

import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil;

import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.internal.corext.refactoring.sef.SelfEncapsulateFieldRefactoring;
import org.eclipse.jdt.internal.corext.util.JdtFlags;

import org.eclipse.jdt.ui.JavaElementLabels;
import org.eclipse.jdt.ui.PreferenceConstants;

import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.dialogs.TextFieldNavigationHandler;
import org.eclipse.jdt.internal.ui.preferences.CodeStylePreferencePage;
import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
import org.eclipse.jdt.internal.ui.refactoring.RefactoringMessages;
import org.eclipse.jdt.internal.ui.util.SWTUtil;

public class SelfEncapsulateFieldInputPage extends UserInputWizardPage {

	private SelfEncapsulateFieldRefactoring fRefactoring;
	private IDialogSettings fSettings;
	private List<Control> fEnablements;

	private Text fGetterName;
	private Text fSetterName;

	private Label fGetterInfo;
	private Label fSetterInfo;

	private String fOldSetterValue= ""; //$NON-NLS-1$
	private String fOldGetterValue= ""; //$NON-NLS-1$

	private Button fGenerateGetter;
	private Button fGenerateSetter;

	private static final String GENERATE_JAVADOC= "GenerateJavadoc";  //$NON-NLS-1$

	public SelfEncapsulateFieldInputPage() {
		super("InputPage"); //$NON-NLS-1$
		setDescription(RefactoringMessages.SelfEncapsulateFieldInputPage_description);
		setImageDescriptor(JavaPluginImages.DESC_WIZBAN_REFACTOR_CU);
	}

	@Override
	public void createControl(Composite parent) {
		fRefactoring= (SelfEncapsulateFieldRefactoring)getRefactoring();

		fEnablements= new ArrayList<>();
		loadSettings();

		Composite result= new Composite(parent, SWT.NONE);
		setControl(result);
		initializeDialogUnits(result);

		result.setLayout(new GridLayout(3, false));

		Composite nameComposite= new Composite(result, SWT.NONE);
		nameComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));

		GridLayout gridLayout= new GridLayout(3, false);
		gridLayout.marginHeight= 0;
		gridLayout.marginWidth= 0;

		nameComposite.setLayout(gridLayout);
		fGenerateGetter= new Button(nameComposite, SWT.CHECK);
		fGenerateGetter.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_getter_name);
		fGenerateGetter.setSelection(true);
		fGenerateGetter.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (fGenerateGetter.getSelection()) {
					fGetterName.setEnabled(true);
					fGetterName.setText(fOldGetterValue);
				} else {
					fOldGetterValue= fGetterName.getText();
					fGetterName.setText(""); //$NON-NLS-1$
					fGetterName.setEnabled(false);
				}
				doGetterModified();
			}
		});
		fGenerateGetter.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));

		fGetterName= new Text(nameComposite, SWT.BORDER);
		fGetterName.setText(fRefactoring.getGetterName());
		GridData gd= new GridData(GridData.FILL_HORIZONTAL);
		gd.widthHint= convertWidthInCharsToPixels(25);
		fGetterName.setLayoutData(gd);
		fGetterName.addModifyListener(new ModifyListener() {
			@Override
			public void modifyText(ModifyEvent e) {
				doGetterModified();
			}
		});
		TextFieldNavigationHandler.install(fGetterName);


		fGetterInfo= new Label(nameComposite, SWT.LEAD);
		fGetterInfo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		updateUseGetter();

		fGenerateSetter= new Button(nameComposite, SWT.CHECK);
		fGenerateSetter.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_setter_name);
		fGenerateSetter.setEnabled(needsSetter());
		fGenerateSetter.setSelection(needsSetter());
		fGenerateSetter.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (fGenerateSetter.getSelection()) {
					fSetterName.setEnabled(true);
					fSetterName.setText(fOldSetterValue);
				} else {
					fOldSetterValue= fSetterName.getText();
					fSetterName.setText(""); //$NON-NLS-1$
					fSetterName.setEnabled(false);
				}
				doSetterModified();
			}
		});
		fGenerateSetter.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));

		fSetterName= new Text(nameComposite, SWT.BORDER);
		if(needsSetter()) {
			fSetterName.setText(fRefactoring.getSetterName());
		} else {
			fSetterName.setText(""); //$NON-NLS-1$
			fSetterName.setEnabled(false);
		}
		gd= new GridData(GridData.FILL_HORIZONTAL);
		gd.widthHint= convertWidthInCharsToPixels(25);
		fSetterName.setLayoutData(gd);
		fSetterName.addModifyListener(new ModifyListener() {
			@Override
			public void modifyText(ModifyEvent e) {
				doSetterModified();
			}
		});
		TextFieldNavigationHandler.install(fSetterName);

		fSetterInfo= new Label(nameComposite, SWT.LEAD);
		fSetterInfo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		updateUseSetter();

		Link link= new Link(nameComposite, SWT.NONE);
		link.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_configure_link);
		link.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doOpenPreference();
			}
		});
		link.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));

		Label separator= new Label(result, SWT.NONE);
		separator.setText(""); //$NON-NLS-1$
		separator.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));

		createFieldAccessBlock(result);

		Label label= new Label(result, SWT.LEFT);
		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		label.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_insert_after);
		fEnablements.add(label);

		final Combo combo= new Combo(result, SWT.READ_ONLY);
		SWTUtil.setDefaultVisibleItemCount(combo);
		fillWithPossibleInsertPositions(combo, fRefactoring.getField());
		combo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				fRefactoring.setInsertionIndex(combo.getSelectionIndex() - 1);
			}
		});
		combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));
		fEnablements.add(combo);

		createAccessModifier(result);

		Button checkBox= new Button(result, SWT.CHECK);
		checkBox.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_generateJavadocComment);
		checkBox.setSelection(fRefactoring.getGenerateJavadoc());
		checkBox.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				setGenerateJavadoc(((Button)e.widget).getSelection());
			}
		});
		checkBox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));

		fEnablements.add(checkBox);

		updateEnablements();

		processValidation();

		fGetterName.setFocus();

		Dialog.applyDialogFont(result);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaHelpContextIds.SEF_WIZARD_PAGE);
	}

	private void updateUseSetter() {
		if(!needsSetter()) {
			fGenerateSetter.setSelection(false);
			fGenerateSetter.setEnabled(false);
			fSetterInfo.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_final_field);
		} else if (fGenerateSetter.getSelection() == false)
			fSetterInfo.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_no_setter_created);
		else if (fSetterName.getText().isEmpty())
			fSetterInfo.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_no_setter_name);
		else if (fRefactoring.isUsingLocalSetter())
			fSetterInfo.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_useexistingsetter_label);
		else
			fSetterInfo.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_usenewgetter_label);
		updateEnablements();
	}

	private void updateEnablements() {
		boolean enable=!(fRefactoring.isUsingLocalSetter()&&fRefactoring.isUsingLocalGetter());
		for (Iterator<Control> iter= fEnablements.iterator(); iter.hasNext();) {
			Control control= iter.next();
			control.setEnabled(enable);
		}
	}

	private void updateUseGetter() {
		if (fGenerateGetter.getSelection() == false)
			fGetterInfo.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_no_getter_created);
		else if (fRefactoring.isUsingLocalGetter())
			fGetterInfo.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_useexistinggetter_label);
		else if (fGetterName.getText().isEmpty())
			fGetterInfo.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_no_getter_name);
		else
			fGetterInfo.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_usenewsetter_label);
		updateEnablements();
	}

	private void loadSettings() {
		fSettings= getDialogSettings().getSection(SelfEncapsulateFieldWizard.DIALOG_SETTING_SECTION);
		if (fSettings == null) {
			fSettings= getDialogSettings().addNewSection(SelfEncapsulateFieldWizard.DIALOG_SETTING_SECTION);
			fSettings.put(GENERATE_JAVADOC, JavaPreferencesSettings.getCodeGenerationSettings(fRefactoring.getField().getJavaProject()).createComments);
		}
		fRefactoring.setGenerateJavadoc(fSettings.getBoolean(GENERATE_JAVADOC));
	}

	private void createAccessModifier(Composite result) {
		int visibility= fRefactoring.getVisibility();
		if (Flags.isPublic(visibility))
			return;

		Label label= new Label(result, SWT.NONE);
		label.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_access_Modifiers);
		fEnablements.add(label);

		Composite group= new Composite(result, SWT.NONE);
		group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));

		GridLayout layout= new GridLayout(4, false);
		layout.marginWidth= 0;
		layout.marginHeight= 0;
		group.setLayout(layout);

		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		Object[] info= createData(visibility);
		String[] labels= (String[])info[0];
		Integer[] data= (Integer[])info[1];
		for (int i= 0; i < labels.length; i++) {
			Button radio= new Button(group, SWT.RADIO);
			radio.setText(labels[i]);
			radio.setData(data[i]);
			int iData= data[i].intValue();
			if (iData == visibility)
				radio.setSelection(true);
			radio.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent event) {
					fRefactoring.setVisibility(((Integer)event.widget.getData()).intValue());
				}
			});
			fEnablements.add(radio);
		}
	}

	private void createFieldAccessBlock(Composite result) {
		Label label= new Label(result, SWT.LEFT);
		label.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_field_access);
		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));

		Composite group= new Composite(result, SWT.NONE);
		GridLayout layout= new GridLayout(2, false);
		layout.marginWidth= 0;
		layout.marginHeight= 0;
		group.setLayout(layout);

		group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));

		Button radio= new Button(group, SWT.RADIO);
		radio.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_use_setter_getter);
		radio.setSelection(true);
		radio.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				fRefactoring.setEncapsulateDeclaringClass(true);
			}
		});
		radio.setLayoutData(new GridData());

		radio= new Button(group, SWT.RADIO);
		radio.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_keep_references);
		radio.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				fRefactoring.setEncapsulateDeclaringClass(false);
			}
		});
		radio.setLayoutData(new GridData());
	}

	private Object[] createData(int visibility) {
		String pub= RefactoringMessages.SelfEncapsulateFieldInputPage_public;
		String pro= RefactoringMessages.SelfEncapsulateFieldInputPage_protected;
		String def= RefactoringMessages.SelfEncapsulateFieldInputPage_default;
		String priv= RefactoringMessages.SelfEncapsulateFieldInputPage_private;

		String[] labels= null;
		Integer[] data= null;
		if (Flags.isPrivate(visibility)) {
			labels= new String[] { pub, pro, def, priv };
			data= new Integer[] {Integer.valueOf(Flags.AccPublic), Integer.valueOf(Flags.AccProtected), Integer.valueOf(0), Integer.valueOf(Flags.AccPrivate) };
		} else if (Flags.isProtected(visibility)) {
			labels= new String[] { pub, pro };
			data= new Integer[] {Integer.valueOf(Flags.AccPublic), Integer.valueOf(Flags.AccProtected)};
		} else {
			labels= new String[] { pub, def };
			data= new Integer[] {Integer.valueOf(Flags.AccPublic), Integer.valueOf(0)};
		}
		return new Object[] {labels, data};
	}

	private void fillWithPossibleInsertPositions(Combo combo, IField field) {
		int select= 0;
		combo.add(RefactoringMessages.SelfEncapsulateFieldInputPage_first_method);
		try {
			IMethod[] methods= field.getDeclaringType().getMethods();
			for (int i= 0; i < methods.length; i++) {
				combo.add(JavaElementLabels.getElementLabel(methods[i], JavaElementLabels.M_PARAMETER_TYPES));
			}
			if (methods.length > 0)
				select= methods.length;
		} catch (JavaModelException e) {
			// Fall through
		}
		combo.select(select);
		fRefactoring.setInsertionIndex(select - 1);
	}

	private void setGenerateJavadoc(boolean value) {
		fSettings.put(GENERATE_JAVADOC, value);
		fRefactoring.setGenerateJavadoc(value);
	}

	private void processValidation() {
		RefactoringStatus status= fRefactoring.checkMethodNames();
		String message= null;
		boolean valid= true;
		if (status.hasFatalError()) {
			message= status.getMessageMatchingSeverity(RefactoringStatus.FATAL);
			valid= false;
		}
		if (fGenerateGetter.getSelection() && fGetterName.getText().isEmpty()) {
			message= RefactoringMessages.SelfEncapsulateFieldInputPage_no_getter_name;
			valid= false;
		} else if (fGenerateSetter.getSelection() && fSetterName.getText().isEmpty()) {
			message= RefactoringMessages.SelfEncapsulateFieldInputPage_no_setter_name;
			valid= false;
		} else if (!fGenerateGetter.getSelection() && !fGenerateSetter.getSelection()) {
			message= RefactoringMessages.SelfEncapsulateFieldInputPage_please_choose_to_generate_a_getter_setter;
			valid= false;
		}
		setErrorMessage(message);
		setPageComplete(valid);
	}

	private boolean needsSetter() {
		try {
			return !JdtFlags.isFinal(fRefactoring.getField());
		} catch(JavaModelException e) {
			return true;
		}
	}

	private void doOpenPreference() {
		String id= CodeStylePreferencePage.PROP_ID;
		IJavaProject project= fRefactoring.getField().getJavaProject();

		String[] relevantOptions= getRelevantOptions(project);

		int open= PreferencesUtil.createPropertyDialogOn(getShell(), project, id, new String[] { id }, null).open();
		if (open == Window.OK && !Arrays.equals(relevantOptions, getRelevantOptions(project))) { // relevant options changes
			fRefactoring.reinitialize();
			fGetterName.setText(fRefactoring.getGetterName());
			fSetterName.setText(fRefactoring.getSetterName());
		}
	}

	private String[] getRelevantOptions(IJavaProject project) {
		return new String[] {
			project.getOption(JavaCore.CODEASSIST_FIELD_PREFIXES, true),
			project.getOption(JavaCore.CODEASSIST_FIELD_SUFFIXES, true),
			PreferenceConstants.getPreference(PreferenceConstants.CODEGEN_IS_FOR_GETTERS, project)
		};
	}

	private void doSetterModified() {
		fRefactoring.setSetterName(fSetterName.getText());
		updateUseSetter();
		processValidation();
	}

	private void doGetterModified() {
		fRefactoring.setGetterName(fGetterName.getText());
		updateUseGetter();
		processValidation();
	}
}
