/*=============================================================================#
 # Copyright (c) 2008, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.internal.r.ui.refactoring;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.typed.PojoProperties;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
import org.eclipse.jface.databinding.wizard.WizardPageSupport;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ArrayContentProvider;
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.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import org.eclipse.statet.ecommons.ui.components.ButtonGroup;
import org.eclipse.statet.ecommons.ui.components.DataAdapter;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils.CheckboxTableComposite;

import org.eclipse.statet.ltk.ui.refactoring.RefactoringBasedStatus;
import org.eclipse.statet.r.core.refactoring.FunctionToS4MethodRefactoring;
import org.eclipse.statet.r.core.refactoring.FunctionToS4MethodRefactoring.Variable;


public class FunctionToS4MethodWizard extends RefactoringWizard {
	
	
	private static class InputPage extends UserInputWizardPage {
		
		
		public static final String PAGE_NAME= "FunctionToS4Method.InputPage"; //$NON-NLS-1$
		
		private static class TypeEditing extends EditingSupport {
			
			private final TextCellEditor cellEditor;
			
			public TypeEditing(final ColumnViewer viewer) {
				super(viewer);
				this.cellEditor= new TextCellEditor((Composite) viewer.getControl());
				this.cellEditor.getControl().setFont(JFaceResources.getTextFont());
			}
			
			@Override
			protected boolean canEdit(final Object element) {
				return (element instanceof Variable);
			}
			
			@Override
			protected CellEditor getCellEditor(final Object element) {
				if (element instanceof Variable) {
					return this.cellEditor;
				}
				return null;
			}
			
			@Override
			protected Object getValue(final Object element) {
				if (element instanceof Variable) {
					final Variable variable= (Variable) element;
					final String type= variable.getArgumentType();
					return (type != null) ? type : "";
				}
				return null;
			}
			
			@Override
			protected void setValue(final Object element, final Object value) {
				if (element instanceof Variable) {
					final Variable variable= (Variable) element;
					variable.setArgumentType((String) value);
					getViewer().update(element, null);
				}
			}
			
		}
		
		private Text functionNameControl;
		private CheckboxTableViewer argumentsViewer;
		private ButtonGroup<Variable> argumentsButtons;
		
		private Button generateGenericControl;
		
		
		public InputPage() {
			super(PAGE_NAME);
		}
		
		@Override
		protected FunctionToS4MethodRefactoring getRefactoring() {
			return (FunctionToS4MethodRefactoring) super.getRefactoring();
		}
		
		@Override
		public void createControl(final Composite parent) {
			final Composite composite= new Composite(parent, SWT.NONE);
			composite.setLayout(LayoutUtils.newDialogGrid(2));
			setControl(composite);
			
			{	final String title= Messages.FunctionToS4Method_Wizard_header;
				final Label label= new Label(composite, SWT.NONE);
				label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));
				label.setText(title);
				label.setFont(JFaceResources.getBannerFont());
			}
			
			LayoutUtils.addSmallFiller(composite, false);
			
			{	final Label label= new Label(composite, SWT.NONE);
				label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
				label.setText(Messages.FunctionToS4Method_Wizard_VariableName_label);
				
				this.functionNameControl= new Text(composite, SWT.BORDER);
				this.functionNameControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
				this.functionNameControl.setFont(JFaceResources.getTextFont());
			}
			
			LayoutUtils.addSmallFiller(composite, false);
			
			final Control table= createArgumentsTable(composite);
			table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
			
			LayoutUtils.addSmallFiller(composite, false);
			
			{	this.generateGenericControl= new Button(composite, SWT.CHECK);
				this.generateGenericControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
				this.generateGenericControl.setText(Messages.FunctionToS4Method_Wizard_GenerateGeneric_label);
			}
			
			LayoutUtils.addSmallFiller(composite, false);
			Dialog.applyDialogFont(composite);
//			PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),);
			
			initBindings();
			for (final Variable variable : getRefactoring().getVariables()) {
				if (!variable.getName().equals("...")) { //$NON-NLS-1$
					this.argumentsViewer.setChecked(variable, variable.getUseAsGenericArgumentDefault());
				}
				else {
					this.argumentsViewer.setGrayed(variable, true);
					this.argumentsViewer.setChecked(variable, true);
				}
			}
			this.argumentsButtons.updateState();
		}
		
		private Control createArgumentsTable(final Composite parent) {
			final Composite composite= new Composite(parent, SWT.NONE);
			composite.setLayout(LayoutUtils.newCompositeGrid(2));
			
			{	final Composite above= new Composite(composite, SWT.NONE);
				above.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false, 2, 1));
				above.setLayout(LayoutUtils.newCompositeGrid(2));
				
				final Label label= new Label(above, SWT.NONE);
				label.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false));
				label.setText("Method &parameters:");
				label.addTraverseListener(new TraverseListener() {
					@Override
					public void keyTraversed(final TraverseEvent e) {
						if (e.detail == SWT.TRAVERSE_MNEMONIC) {
							e.doit= false;
							InputPage.this.argumentsViewer.getControl().setFocus();
						}
					}
				});
			}
			
			final CheckboxTableComposite table= new CheckboxTableComposite(composite, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
			final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
			gd.heightHint= LayoutUtils.hintHeight(table.table, 12);
			table.setLayoutData(gd);
			table.setLayoutData(gd);
			table.table.setHeaderVisible(true);
			table.table.setLinesVisible(true);
			this.argumentsViewer= table.viewer;
			
			{	final TableViewerColumn column= table.addColumn("Name", SWT.LEFT, new ColumnWeightData(1));
				column.setLabelProvider(new CellLabelProvider() {
					@Override
					public void update(final ViewerCell cell) {
						final Object element= cell.getElement();
						if (element instanceof Variable) {
							cell.setFont(JFaceResources.getDialogFont());
							final Variable variable= (Variable) element;
							cell.setText(variable.getName());
							return;
						}
						cell.setText(""); //$NON-NLS-1$
					}
				});
			}
			
			{	final TableViewerColumn column= table.addColumn("Type", SWT.LEFT, new ColumnWeightData(1));
				column.setLabelProvider(new CellLabelProvider() {
					@Override
					public void update(final ViewerCell cell) {
						final Object element= cell.getElement();
						if (element instanceof Variable) {
							cell.setFont(JFaceResources.getTextFont());
							final Variable variable= (Variable) element;
							final String type= variable.getArgumentType();
							cell.setText((type != null) ? type : ""); //$NON-NLS-1$
							return;
						}
						cell.setText(""); //$NON-NLS-1$
					}
				});
				final TypeEditing editing= new TypeEditing(table.viewer);
				
				column.setEditingSupport(editing);
			}
			
			ViewerUtils.installDefaultEditBehaviour(this.argumentsViewer);
			this.argumentsViewer.setContentProvider(new ArrayContentProvider());
			
			this.argumentsButtons= new ButtonGroup<>(composite);
			this.argumentsButtons.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, true));
			this.argumentsButtons.addUpButton(null);
			this.argumentsButtons.addDownButton(null);
			
			return composite;
		}
		
		protected void initBindings() {
			final Realm realm= Realm.getDefault();
			final DataBindingContext dbc= new DataBindingContext(realm);
			
			addBindings(dbc, realm);
			WizardPageSupport.create(this, dbc);
		}
		
		protected void addBindings(final DataBindingContext dbc, final Realm realm) {
			dbc.bindValue(
					WidgetProperties.text(SWT.Modify)
							.observe(this.functionNameControl),
					PojoProperties.value(FunctionToS4MethodRefactoring.class, "functionName", String.class) //$NON-NLS-1$
							.observe(realm, getRefactoring()),
					new UpdateValueStrategy<String, String>()
							.setAfterGetValidator((final String value) ->
									new RefactoringBasedStatus(
											getRefactoring().checkFunctionName(value) )),
					null );
			final IObservableList<Variable> argumentsList= new WritableList<>(realm, getRefactoring().getVariables(), Variable.class);
			this.argumentsViewer.addCheckStateListener(
					(final CheckStateChangedEvent event) -> {
						final Object element= event.getElement();
						if (element instanceof Variable) {
							final Variable variable= (Variable) element;
							if (!variable.getName().equals("...")) { //$NON-NLS-1$
								final boolean check= event.getChecked();
								int idx= argumentsList.indexOf(element);
								if (check) {
									Variable previousVariable= null;
									while (idx > 0) {
										final Object previousElement= argumentsList.get(idx-1);
										if (previousElement instanceof Variable
												&& !((Variable) previousElement).getName().equals("...")) { //$NON-NLS-1$
											previousVariable= (Variable) previousElement;
											break;
										}
										idx--;
									}
									if (previousVariable == null || previousVariable.getUseAsGenericArgument() == event.getChecked()) {
										variable.setUseAsGenericArgument(event.getChecked());
										InputPage.this.argumentsViewer.setChecked(variable, event.getChecked());
										return;
									}
								}
								else {
									Variable nextVariable= null;
									while (idx < argumentsList.size()-1) {
										final Object nextElement= argumentsList.get(idx+1);
										if (nextElement instanceof Variable
												&& !((Variable) nextElement).getName().equals("...")) { //$NON-NLS-1$
											nextVariable= (Variable) nextElement;
											break;
										}
										idx++;
									}
									if (nextVariable == null || nextVariable.getUseAsGenericArgument() == event.getChecked()) {
										variable.setUseAsGenericArgument(event.getChecked());
										InputPage.this.argumentsViewer.setChecked(variable, event.getChecked());
										return;
									}
								}
								InputPage.this.argumentsViewer.setChecked(variable, !event.getChecked());
							}
							else {
								InputPage.this.argumentsViewer.setChecked(variable, true);
							}
						}
					} );
			this.argumentsViewer.setInput(argumentsList);
			this.argumentsButtons.connectTo(this.argumentsViewer, new DataAdapter.ListAdapter<FunctionToS4MethodRefactoring.Variable>(
					argumentsList, null ) {
				@Override
				protected void moveByIdx(final int oldIdx, final int newIdx) {
					final Object upperElement= InputPage.this.argumentsViewer.getElementAt(Math.min(oldIdx, newIdx));
					final Object lowerElement= InputPage.this.argumentsViewer.getElementAt(Math.max(oldIdx, newIdx));
					super.moveByIdx(oldIdx, newIdx);
					if ((upperElement instanceof Variable)
							&& !((Variable) upperElement).getName().equals("...") //$NON-NLS-1$
							&& (lowerElement instanceof Variable)
							&& !((Variable) lowerElement).getName().equals("...")) { //$NON-NLS-1$
						final boolean checked= InputPage.this.argumentsViewer.getChecked(upperElement);
						((Variable) lowerElement).setUseAsGenericArgument(checked);
						InputPage.this.argumentsViewer.setChecked(lowerElement, checked);
					}
				}
			});
			
			dbc.bindValue(
					WidgetProperties.buttonSelection()
							.observe(this.generateGenericControl),
					PojoProperties.value(FunctionToS4MethodRefactoring.class, "generateGeneric", Boolean.TYPE) //$NON-NLS-1$
							.observe(realm, getRefactoring()) );
		}
		
		@Override
		public void setVisible(final boolean visible) {
			super.setVisible(visible);
			this.functionNameControl.setFocus();
		}
		
	}
	
	
	public FunctionToS4MethodWizard(final FunctionToS4MethodRefactoring ref) {
		super(ref, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE | NO_BACK_BUTTON_ON_STATUS_DIALOG);
		setDefaultPageTitle(Messages.FunctionToS4Method_Wizard_title);
	}
	
	
	@Override
	protected void addUserInputPages() {
		addPage(new InputPage());
	}
	
}
