/*=============================================================================#
 # Copyright (c) 2008, 2019 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.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.ltk.ui.refactoring.RefactoringWizard;
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
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.statet.ecommons.ui.util.LayoutUtils;

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


public class ExtractTempWizard extends RefactoringWizard {
	
	
	private static class InputPage extends UserInputWizardPage {
		
		
		public static final String PAGE_NAME= "ExtractTemp.InputPage"; //$NON-NLS-1$
		
		
		private Text variableNameControl;
		private Button replaceAllControl;
		
		
		public InputPage() {
			super(PAGE_NAME);
		}
		
		@Override
		protected ExtractTempRefactoring getRefactoring() {
			return (ExtractTempRefactoring) 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 int count= getRefactoring().getAllOccurrencesCount();
			
			{	final Label label= new Label(composite, SWT.NONE);
				label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));
				label.setText(Messages.ExtractTemp_Wizard_header);
				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.ExtractTemp_Wizard_VariableName_label);
				
				this.variableNameControl= new Text(composite, SWT.BORDER);
				this.variableNameControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
				this.variableNameControl.setFont(JFaceResources.getTextFont());
			}
			
			LayoutUtils.addSmallFiller(composite, false);
			
			{	
				if (count > 0) {
					final Label label= new Label(composite, SWT.WRAP);
					label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
					if (count == 1) {
						label.setText("No other occurrences of the selected expression found.");
					}
					else {
						label.setText(NLS.bind("{0} other occurrences of the selected expression found.", count-1));
					}
				}
				
				this.replaceAllControl= new Button(composite, SWT.CHECK);
				this.replaceAllControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
				this.replaceAllControl.setText(Messages.ExtractTemp_Wizard_ReplaceAll_label);
				if (count <= 1) {
					this.replaceAllControl.setEnabled(false);
				}
			}
			
			LayoutUtils.addSmallFiller(composite, false);
			Dialog.applyDialogFont(composite);
			
			initBindings();
//			PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),);
		}
		
		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.variableNameControl),
					PojoProperties.value(ExtractTempRefactoring.class, "tempName", String.class) //$NON-NLS-1$
							.observe(realm, getRefactoring()),
					new UpdateValueStrategy<String, String>()
							.setAfterGetValidator((final String value) ->
									new RefactoringBasedStatus(
											getRefactoring().checkTempName(value) )),
					null );
			dbc.bindValue(
					WidgetProperties.buttonSelection()
							.observe(this.replaceAllControl),
					PojoProperties.value(ExtractTempRefactoring.class, "replaceAllOccurrences", Boolean.TYPE) //$NON-NLS-1$
							.observe(realm, getRefactoring()) );
		}
		
		@Override
		public void setVisible(final boolean visible) {
			super.setVisible(visible);
			this.variableNameControl.setFocus();
		}
		
	}
	
	
	public ExtractTempWizard(final ExtractTempRefactoring ref) {
		super(ref, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE | NO_BACK_BUTTON_ON_STATUS_DIALOG);
		setDefaultPageTitle(Messages.ExtractTemp_Wizard_title);
	}
	
	
	@Override
	protected void addUserInputPages() {
		addPage(new InputPage());
	}
	
}
