/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *     Jerome Cambon <jerome.cambon@oracle.com> - [code style] don't generate redundant modifiers "public static final abstract" for interface members - https://bugs.eclipse.org/71627
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.refactoring;

import java.util.Arrays;
import java.util.List;

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.Label;
import org.eclipse.swt.widgets.Text;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.wizard.IWizardPage;

import org.eclipse.ui.PlatformUI;

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

import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.internal.corext.refactoring.structure.ExtractInterfaceProcessor;

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

import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
import org.eclipse.jdt.internal.ui.util.SWTUtil;
import org.eclipse.jdt.internal.ui.viewsupport.AppearanceAwareLabelProvider;
import org.eclipse.jdt.internal.ui.viewsupport.DecoratingJavaLabelProvider;

public class ExtractInterfaceWizard extends RefactoringWizard {

	private final ExtractInterfaceProcessor fProcessor;

	public ExtractInterfaceWizard(ExtractInterfaceProcessor processor, Refactoring refactoring) {
		super(refactoring, DIALOG_BASED_USER_INTERFACE);
		fProcessor= processor;
		setDefaultPageTitle(RefactoringMessages.ExtractInterfaceWizard_Extract_Interface);
	}

	/* non java-doc
	 * @see RefactoringWizard#addUserInputPages
	 */
	@Override
	protected void addUserInputPages(){
		addPage(new ExtractInterfaceInputPage(fProcessor));
	}

	private static class ExtractInterfaceInputPage extends TextInputWizardPage {

		private Button fReplaceAllCheckbox;
		private Button fGenerateAnnotationsCheckbox;
		private Button fGenerateCommentsCheckbox;
		private Button fInstanceofCheckbox;
		private CheckboxTableViewer fTableViewer;
		private static final String DESCRIPTION = RefactoringMessages.ExtractInterfaceInputPage_description;
		private static final String SETTING_ANNOTATIONS= 		"Annotations";//$NON-NLS-1$
		private static final String SETTING_REPLACE= "Replace"; //$NON-NLS-1$
		private static final String SETTING_COMMENTS= "Comments"; //$NON-NLS-1$
		private static final String SETTING_INSTANCEOF= "InstanceOf"; //$NON-NLS-1$
		private Button fSelectAllButton;
		private Button fDeselectAllButton;

		private final ExtractInterfaceProcessor fProcessor;

		public ExtractInterfaceInputPage(ExtractInterfaceProcessor processor) {
			super(DESCRIPTION, true);
			fProcessor= processor;
		}

		@Override
		public void createControl(Composite parent) {
			initializeDialogUnits(parent);
			Composite result= new Composite(parent, SWT.NONE);
			setControl(result);
			GridLayout layout= new GridLayout();
			layout.numColumns= 2;
			result.setLayout(layout);

			Label label= new Label(result, SWT.NONE);
			label.setText(RefactoringMessages.ExtractInterfaceInputPage_Interface_name);

			Text text= createTextInputField(result);
			text.selectAll();
			text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

			addReplaceAllCheckbox(result);
			addInstanceofCheckbox(result, layout.marginWidth);
			fReplaceAllCheckbox.addSelectionListener(new SelectionAdapter() {

				@Override
				public void widgetSelected(SelectionEvent e) {
					fInstanceofCheckbox.setEnabled(fReplaceAllCheckbox.getSelection());
				}
			});
			addGenerateAnnotationsCheckbox(result);

			Label separator= new Label(result, SWT.NONE);
			GridData gd= new GridData();
			gd.horizontalSpan= 2;
			separator.setLayoutData(gd);

			Label tableLabel= new Label(result, SWT.NONE);
			tableLabel.setText(RefactoringMessages.ExtractInterfaceInputPage_Members);
			tableLabel.setEnabled(anyMembersToExtract());
			gd= new GridData();
			gd.horizontalSpan= 2;
			tableLabel.setLayoutData(gd);

			addMemberListComposite(result);
			addGenerateCommentsCheckbox(result);
			Dialog.applyDialogFont(result);
			initializeCheckboxes();
			updateUIElementEnablement();
			PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaHelpContextIds.EXTRACT_INTERFACE_WIZARD_PAGE);
		}

		private void addGenerateAnnotationsCheckbox(Composite result) {
			String title= RefactoringMessages.ExtractInterfaceWizard_generate_annotations;
			fGenerateAnnotationsCheckbox= createCheckbox(result,  title, false);
			fProcessor.setAnnotations(fGenerateAnnotationsCheckbox.getSelection());
			fGenerateAnnotationsCheckbox.addSelectionListener(new SelectionAdapter(){
				@Override
				public void widgetSelected(SelectionEvent e) {
					fProcessor.setAnnotations(fGenerateAnnotationsCheckbox.getSelection());
				}
			});
		}

		private void addGenerateCommentsCheckbox(Composite result) {
			String title= RefactoringMessages.ExtractInterfaceWizard_generate_comments;
			fGenerateCommentsCheckbox= createCheckbox(result,  title, false);
			fProcessor.setComments(fGenerateCommentsCheckbox.getSelection());
			fGenerateCommentsCheckbox.addSelectionListener(new SelectionAdapter(){
				@Override
				public void widgetSelected(SelectionEvent e) {
					fProcessor.setComments(fGenerateCommentsCheckbox.getSelection());
				}
			});
		}

		private void addInstanceofCheckbox(Composite result, int margin) {
			String title= RefactoringMessages.ExtractInterfaceWizard_use_supertype;
			fInstanceofCheckbox= new Button(result, SWT.CHECK);
			fInstanceofCheckbox.setSelection(false);
			GridData gd= new GridData();
			gd.horizontalIndent= (margin + fInstanceofCheckbox.computeSize(SWT.DEFAULT, SWT.DEFAULT).x);
			gd.horizontalSpan= 2;
			fInstanceofCheckbox.setLayoutData(gd);
			fInstanceofCheckbox.setText(title);
			fProcessor.setInstanceOf(fInstanceofCheckbox.getSelection());
			fInstanceofCheckbox.addSelectionListener(new SelectionAdapter(){
				@Override
				public void widgetSelected(SelectionEvent e) {
					fProcessor.setInstanceOf(fInstanceofCheckbox.getSelection());
				}
			});
		}

		private void addMemberListComposite(Composite result) {
			Composite composite= new Composite(result, SWT.NONE);
			GridLayout layout= new GridLayout();
			layout.numColumns= 2;
			layout.marginWidth= 0;
			layout.marginHeight= 0;
			composite.setLayout(layout);
			GridData gd= new GridData(GridData.FILL_BOTH);
			gd.heightHint= convertHeightInCharsToPixels(12);
			gd.horizontalSpan= 2;
			composite.setLayoutData(gd);

			fTableViewer= CheckboxTableViewer.newCheckList(composite, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
			fTableViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH));
			fTableViewer.setLabelProvider(createLabelProvider());
			fTableViewer.setContentProvider(ArrayContentProvider.getInstance());
			try {
				fTableViewer.setInput(getExtractableMembers());
			} catch (JavaModelException e) {
				ExceptionHandler.handle(e, RefactoringMessages.ExtractInterfaceInputPage_Extract_Interface, RefactoringMessages.ExtractInterfaceInputPage_Internal_Error);
				fTableViewer.setInput(new IMember[0]);
			}
			fTableViewer.addCheckStateListener(new ICheckStateListener(){
				@Override
				public void checkStateChanged(CheckStateChangedEvent event) {
					ExtractInterfaceInputPage.this.updateUIElementEnablement();
				}
			});
			fTableViewer.setComparator(new JavaElementComparator());
			fTableViewer.getControl().setEnabled(anyMembersToExtract());

			createButtonComposite(composite);
		}

		private IMember[] getExtractableMembers() throws JavaModelException {
			return fProcessor.getExtractableMembers();
		}

		protected void updateUIElementEnablement() {
			final IMember[] checked= getCheckedMembers();
			IMember[] extractable;
			try {
				extractable= getExtractableMembers();
			} catch (JavaModelException exception) {
				extractable= new IMember[0];
				JavaPlugin.log(exception);
			}
			final boolean enabled= containsMethods(checked);
			fGenerateAnnotationsCheckbox.setEnabled(enabled);
			fGenerateCommentsCheckbox.setEnabled(enabled);
			fInstanceofCheckbox.setEnabled(fReplaceAllCheckbox.getSelection());
			fSelectAllButton.setEnabled(checked.length < extractable.length);
			fDeselectAllButton.setEnabled(checked.length > 0);
		}

		private static boolean containsMethods(IMember[] members) {
			for (IMember member : members) {
				if (member.getElementType() == IJavaElement.METHOD) {
					return true;
				}
			}
			return false;
		}

		private ILabelProvider createLabelProvider(){
			AppearanceAwareLabelProvider lprovider= new AppearanceAwareLabelProvider(
				AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS |  JavaElementLabels.F_APP_TYPE_SIGNATURE,
				AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS
			);

			return new DecoratingJavaLabelProvider(lprovider);
		}

		private void createButtonComposite(Composite composite) {
			GridData gd;
			Composite buttonComposite= new Composite(composite, SWT.NONE);
			GridLayout gl= new GridLayout();
			gl.marginHeight= 0;
			gl.marginWidth= 0;
			buttonComposite.setLayout(gl);
			gd= new GridData(GridData.FILL_VERTICAL);
			buttonComposite.setLayoutData(gd);

			fSelectAllButton= new Button(buttonComposite, SWT.PUSH);
			fSelectAllButton.setText(RefactoringMessages.ExtractInterfaceInputPage_Select_All);
			fSelectAllButton.setEnabled(anyMembersToExtract());
			fSelectAllButton.setLayoutData(new GridData());
			SWTUtil.setButtonDimensionHint(fSelectAllButton);
			fSelectAllButton.addSelectionListener(new SelectionAdapter(){
				@Override
				public void widgetSelected(SelectionEvent e) {
					fTableViewer.setAllChecked(true);
					ExtractInterfaceInputPage.this.updateUIElementEnablement();
				}
			});

			fDeselectAllButton= new Button(buttonComposite, SWT.PUSH);
			fDeselectAllButton.setText(RefactoringMessages.ExtractInterfaceInputPage_Deselect_All);
			fDeselectAllButton.setEnabled(anyMembersToExtract());
			fDeselectAllButton.setLayoutData(new GridData());
			SWTUtil.setButtonDimensionHint(fDeselectAllButton);
			fDeselectAllButton.addSelectionListener(new SelectionAdapter(){
				@Override
				public void widgetSelected(SelectionEvent e) {
					fTableViewer.setAllChecked(false);
					ExtractInterfaceInputPage.this.updateUIElementEnablement();
				}
			});
		}

		private boolean anyMembersToExtract() {
			try {
				return getExtractableMembers().length > 0;
			} catch (JavaModelException e) {
				return false;
			}
		}

		private void addReplaceAllCheckbox(Composite result) {
			String title= RefactoringMessages.ExtractInterfaceInputPage_change_references;
			boolean defaultValue= fProcessor.isReplace();
			fReplaceAllCheckbox= createCheckbox(result,  title, defaultValue);
			fProcessor.setReplace(fReplaceAllCheckbox.getSelection());
			fReplaceAllCheckbox.addSelectionListener(new SelectionAdapter(){
				@Override
				public void widgetSelected(SelectionEvent e) {
					fProcessor.setReplace(fReplaceAllCheckbox.getSelection());
				}
			});
		}

		private static Button createCheckbox(Composite parent, String title, boolean value){
			Button checkBox= new Button(parent, SWT.CHECK);
			checkBox.setText(title);
			checkBox.setSelection(value);
			GridData layoutData= new GridData();
			layoutData.horizontalSpan= 2;

			checkBox.setLayoutData(layoutData);
			return checkBox;
		}

		/*
		 * @see org.eclipse.jdt.internal.ui.refactoring.TextInputWizardPage#validateTextField(String)
		 */
		@Override
		protected RefactoringStatus validateTextField(String text) {
			final ExtractInterfaceProcessor processor= fProcessor;
			processor.setTypeName(text);
			return processor.checkTypeName(text);
		}

		/*
		 * @see org.eclipse.jface.wizard.IWizardPage#getNextPage()
		 */
		@Override
		public IWizardPage getNextPage() {
			try {
				initializeRefactoring();
				storeDialogSettings();
				return super.getNextPage();
			} catch (JavaModelException e) {
				JavaPlugin.log(e);
				return null;
			}
		}

		/*
		 * @see org.eclipse.jdt.internal.ui.refactoring.RefactoringWizardPage#performFinish()
		 */
		@Override
		public boolean performFinish(){
			try {
				initializeRefactoring();
				storeDialogSettings();
				return super.performFinish();
			} catch (JavaModelException e) {
				JavaPlugin.log(e);
				return false;
			}
		}

		private void initializeRefactoring() throws JavaModelException {
			fProcessor.setTypeName(getText());
			fProcessor.setReplace(fReplaceAllCheckbox.getSelection());
			fProcessor.setExtractedMembers(getCheckedMembers());
			fProcessor.setAnnotations(fGenerateAnnotationsCheckbox.getSelection());
			fProcessor.setComments(fGenerateCommentsCheckbox.getSelection());
			fProcessor.setInstanceOf(fInstanceofCheckbox.getSelection());
		}

		private IMember[] getCheckedMembers() {
			List<?> checked= Arrays.asList(fTableViewer.getCheckedElements());
			return checked.toArray(new IMember[checked.size()]);
		}

		@Override
		public void dispose() {
			fInstanceofCheckbox= null;
			fGenerateCommentsCheckbox= null;
			fReplaceAllCheckbox= null;
			fTableViewer= null;
			super.dispose();
		}

		private void initializeCheckboxes() {
			initializeCheckBox(fGenerateAnnotationsCheckbox, SETTING_ANNOTATIONS, true);
			initializeCheckBox(fReplaceAllCheckbox, SETTING_REPLACE, true);
			initializeCheckBox(fGenerateCommentsCheckbox, SETTING_COMMENTS, true);
			initializeCheckBox(fInstanceofCheckbox, SETTING_INSTANCEOF, false);
		}

		private void initializeCheckBox(Button checkbox, String property, boolean def) {
			String s= JavaPlugin.getDefault().getDialogSettings().get(property);
			if (s != null)
				checkbox.setSelection(Boolean.parseBoolean(s));
			else
				checkbox.setSelection(def);
		}

		private void storeDialogSettings() {
			final IDialogSettings settings= JavaPlugin.getDefault().getDialogSettings();
			settings.put(SETTING_ANNOTATIONS, fGenerateAnnotationsCheckbox.getSelection());
			settings.put(SETTING_REPLACE, fReplaceAllCheckbox.getSelection());
			settings.put(SETTING_COMMENTS, fGenerateCommentsCheckbox.getSelection());
			settings.put(SETTING_INSTANCEOF, fInstanceofCheckbox.getSelection());
		}
	}
}
