/*=============================================================================#
 # Copyright (c) 2017, 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.apps.ui.launching;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.variables.IStringVariable;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.dialogs.Dialog;
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.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;

import org.eclipse.statet.ecommons.databinding.IntegerValidator;
import org.eclipse.statet.ecommons.databinding.core.validation.UpdateableErrorValidator;
import org.eclipse.statet.ecommons.debug.ui.config.LaunchConfigPresets;
import org.eclipse.statet.ecommons.debug.ui.config.LaunchConfigTabWithPresets;
import org.eclipse.statet.ecommons.templates.TemplateVariableProcessor;
import org.eclipse.statet.ecommons.ui.SharedMessages;
import org.eclipse.statet.ecommons.ui.SharedUIResources;
import org.eclipse.statet.ecommons.ui.components.CustomizableVariableSelectionDialog;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.VariableFilterUtils;
import org.eclipse.statet.ecommons.variables.core.VariableText2;
import org.eclipse.statet.ecommons.variables.core.VariableTextValidator;
import org.eclipse.statet.ecommons.variables.core.VariableUtils;

import org.eclipse.statet.internal.r.apps.ui.Messages;
import org.eclipse.statet.ltk.ui.sourceediting.SnippetEditor;
import org.eclipse.statet.ltk.ui.sourceediting.SnippetEditor1;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.launching.ui.RLaunchingUI;
import org.eclipse.statet.r.ui.sourceediting.RSourceViewerConfigurator;
import org.eclipse.statet.r.ui.sourceediting.RTemplateSourceViewerConfigurator;


public class AppControlConfigMainTab extends LaunchConfigTabWithPresets {
	
	
	static void initDefaults(final ILaunchConfigurationWorkingCopy config) {
		config.setAttribute(AppControlConfigs.START_STOP_BLOCKING_TASKS_MODE_ATTR_NAME, 1);
	}
	
	
	private final IObservableValue<String> appPathValue;
	
	private final IObservableValue<String> appHostValue;
	private final IObservableValue<Integer> appPortValue;
	
	private final IObservableValue<Boolean> startStopRunningValue;
	private final IObservableValue<String> startRSnippetValue;
	private final IObservableValue<String> stopRSnippetValue;
	
//	private ResourceInputComposite appPathControl;
	
	private Text sHostControl;
	private Text sPortControl;
	
	private Button startStopRunningControl;
	private VariableText2 rSnippetVariableResolver;
	private SnippetEditor startRSnippetEditor;
	private SnippetEditor stopRSnippetEditor;
	
	
	public AppControlConfigMainTab(final LaunchConfigPresets presets) {
		
		final Realm realm= getRealm();
		this.appHostValue= new WritableValue<>(realm, null, String.class);
		this.appPortValue= new WritableValue<>(realm, null, Integer.class);
		this.appPathValue= new WritableValue<>(realm, null, String.class);
		this.startRSnippetValue= new WritableValue<>(realm, null, String.class);
		this.startStopRunningValue= new WritableValue<>(realm, null, Boolean.class);
		this.stopRSnippetValue= new WritableValue<>(realm, null, String.class);
		
		setPresets(presets);
	}
	
	
	@Override
	public Image getImage() {
		return SharedUIResources.getImages().get(SharedUIResources.OBJ_MAIN_TAB_ID);
	}
	
	@Override
	public String getName() {
		return Messages.Operation_MainTab_name;
	}
	
	
	@Override
	public void createControl(final Composite parent) {
		final Composite mainComposite= new Composite(parent, SWT.NONE);
		setControl(mainComposite);
		mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		mainComposite.setLayout(LayoutUtils.newTabGrid(1));
		
		addPresetsButton(mainComposite);
		
		{	final Composite composite= createAddressSettings(mainComposite);
			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		}
		{	final Composite composite= createSnippetSettings(mainComposite);
			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		}
		Dialog.applyDialogFont(parent);
		
		initBindings();
	}
	
	private Composite createAddressSettings(final Composite parent) {
		final Group composite= new Group(parent, SWT.NONE);
		composite.setText(Messages.Operation_MainTab_AppAddress_group);
		composite.setLayout(LayoutUtils.newGroupGrid(4));
		
		{	// Address
			final Label label= new Label(composite, SWT.LEFT);
			label.setText(Messages.Operation_MainTab_AppHost_label + ':');
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			
			final Text text= new Text(composite, SWT.BORDER | SWT.SINGLE | SWT.LEFT);
			text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
			this.sHostControl= text;
			
			final Label info= new Label(composite, SWT.LEFT);
			info.setText(Messages.Operation_AppHost_info);
			info.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		}
		{	// Port
			final Label label= new Label(composite, SWT.LEFT);
			label.setText(Messages.Operation_MainTab_AppPort_label + ':');
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			
			final Text number= new Text(composite, SWT.BORDER | SWT.SINGLE | SWT.LEFT);
			final GridData gd= new GridData(SWT.LEFT, SWT.CENTER, false, false);
			gd.widthHint= LayoutUtils.hintWidth(number, 5);
			number.setLayoutData(gd);
			this.sPortControl= number;
			
			final Label info= new Label(composite, SWT.LEFT);
			info.setText(Messages.Operation_AppPort_info);
			info.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));
		}
		
		return composite;
	}
	
	private Map<String, IStringVariable> createSnippetVariables() {
		final Map<String, IStringVariable> variables= new HashMap<>();
		VariableUtils.add(variables, AppControlConfigs.APP_HOST_VAR);
		VariableUtils.add(variables, AppControlConfigs.APP_PORT_VAR);
		return variables;
	}
	
	private Composite createSnippetSettings(final Composite parent) {
		final Group composite= new Group(parent, SWT.NONE);
		composite.setText(Messages.Operation_MainTab_Start_group);
		composite.setLayout(LayoutUtils.newGroupGrid(1));
		
//		{	final Label label= new Label(composite, SWT.NONE);
//			label.setText(Messages.Operation_MainTab_AppFolder_label + ' ' +
//					Messages.Operation_AppFolder_info + ':' );
//			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
//			
//			final ResourceInputComposite input= new ResourceInputComposite(composite,
//					ResourceInputComposite.STYLE_TEXT,
//					ResourceInputComposite.MODE_DIRECTORY | ResourceInputComposite.MODE_OPEN
//							| ResourceInputComposite.MODE_WS_ONLY,
//					Messages.Operation_MainTab_AppFolder_label );
//			input.getValidator().setOnEmpty(IStatus.OK);
//			input.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
//			this.appPathControl= input;
//		}
		
		this.rSnippetVariableResolver= new VariableText2(createSnippetVariables());
		
		{	final Label label= new Label(composite, SWT.NONE);
			label.setText(Messages.Operation_StartApp_RCode_label + ':');
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
			
			final TemplateVariableProcessor templateVariableProcessor= new TemplateVariableProcessor();
			final RSourceViewerConfigurator configurator= new RTemplateSourceViewerConfigurator(
					RCore.getWorkbenchAccess(),
					templateVariableProcessor );
			final SnippetEditor1 editor= new SnippetEditor1(configurator, null,
					PlatformUI.getWorkbench(), RLaunchingUI.LAUNCH_CONFIG_QUALIFIER, true ) {
				@Override
				protected void fillToolMenu(final Menu menu) {
					{	final MenuItem item= new MenuItem(menu, SWT.PUSH);
						item.setText(SharedMessages.InsertVariable_label);
						item.addSelectionListener(new SelectionAdapter() {
							@Override
							public void widgetSelected(final SelectionEvent e) {
								final CustomizableVariableSelectionDialog dialog= new CustomizableVariableSelectionDialog(getTextControl().getShell());
								dialog.addVariableFilter(VariableFilterUtils.EXCLUDE_JAVA_FILTER);
								dialog.setAdditionals(AppControlConfigMainTab
										.this.rSnippetVariableResolver.getExtraVariables().values() );
								if (dialog.open() != Dialog.OK) {
									return;
								}
								final String variable= dialog.getVariableExpression();
								if (variable == null) {
									return;
								}
								getTextControl().insert(variable);
								getTextControl().setFocus();
							}
						});
					}
				}
			};
			editor.create(composite, SnippetEditor.DEFAULT_MULTI_LINE_STYLE);
			final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true);
			gd.heightHint= LayoutUtils.hintHeight(editor.getSourceViewer().getTextWidget(), 8);
			editor.getControl().setLayoutData(gd);
			this.startRSnippetEditor= editor;
		}
		{	final Button button= new Button(composite, SWT.CHECK);
			button.setText(Messages.Operation_StartApp_StopRunningApp_label);
			button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
			this.startStopRunningControl= button;
		}
		LayoutUtils.addSmallFiller(composite, false);
		{	final Label label= new Label(composite, SWT.NONE);
			label.setText(Messages.Operation_StopApp_RCode_label + ':');
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			
			final TemplateVariableProcessor templateVariableProcessor= new TemplateVariableProcessor();
			final RSourceViewerConfigurator configurator= new RTemplateSourceViewerConfigurator(
					RCore.getWorkbenchAccess(),
					templateVariableProcessor );
			final SnippetEditor1 editor= new SnippetEditor1(configurator, null,
					PlatformUI.getWorkbench(), RLaunchingUI.LAUNCH_CONFIG_QUALIFIER );
			editor.create(composite, SnippetEditor.DEFAULT_SINGLE_LINE_STYLE);
			final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, false);
			gd.heightHint= LayoutUtils.hintHeight(editor.getSourceViewer().getTextWidget(), 1);
			editor.getControl().setLayoutData(gd);
			this.stopRSnippetEditor= editor;
		}
		return composite;
	}
	
	
	@Override
	protected void addBindings(final DataBindingContext dbc) {
//		dbc.bindValue(
//				this.appPathControl.getObservable(),
//				this.appPathValue,
//				new UpdateValueStrategy().setAfterGetValidator(this.appPathControl.getValidator()),
//				null );
		
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify).observe(this.sHostControl),
				this.appHostValue );
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify).observe(this.sPortControl),
				this.appPortValue,
				new UpdateValueStrategy().setAfterGetValidator(new IntegerValidator(0, 65535, true,
						Messages.Operation_AppPort_error_SpecInvalid_message )),
				null );
		
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify).observe(this.startRSnippetEditor.getTextControl()),
				this.startRSnippetValue,
				new UpdateValueStrategy().setAfterGetValidator(
						new UpdateableErrorValidator(new VariableTextValidator(
								this.rSnippetVariableResolver,
								Messages.Operation_StartApp_RCode_error_SpecInvalid_message ))),
				null );
		dbc.bindValue(
				WidgetProperties.selection().observe(this.startStopRunningControl),
				this.startStopRunningValue );
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify).observe(this.stopRSnippetEditor.getTextControl()),
				this.stopRSnippetValue );
	}
	
	
	@Override
	public void setDefaults(final ILaunchConfigurationWorkingCopy configuration) {
		initDefaults(configuration);
	}
	
	@Override
	protected void doInitialize(final ILaunchConfiguration configuration) {
//		{	String path= ""; //$NON-NLS-1$
//			try {
//				path= configuration.getAttribute(AppControlConfig.EXPL_SOURCE_PATH_ATTR_NAME, path);
//			}
//			catch (final CoreException e) {
//				logReadingError(e);
//			}
//			this.appPathValue.setValue(path);
//		}
		
		{	String text= ""; //$NON-NLS-1$
			try {
				text= configuration.getAttribute(AppControlConfigs.APP_HOST_ATTR_NAME, text);
			}
			catch (final CoreException e) {
				logReadingError(e);
			}
			this.appHostValue.setValue(text);
		}
		{	int port= 0;
			try {
				port= configuration.getAttribute(AppControlConfigs.APP_PORT_ATTR_NAME, port);
			}
			catch (final CoreException e) {
				logReadingError(e);
			}
			this.appPortValue.setValue((port != 0) ? Integer.valueOf(port) : null);
		}
		
		{	int mode= 0;
			try {
				mode= configuration.getAttribute(AppControlConfigs.START_STOP_BLOCKING_TASKS_MODE_ATTR_NAME, mode);
			}
			catch (final CoreException e) {
				logReadingError(e);
			}
			this.startStopRunningValue.setValue(mode > 0);
		}
		{	String code= ""; //$NON-NLS-1$
			try {
				code= configuration.getAttribute(AppControlConfigs.START_R_SNIPPET_CODE_ATTR_NAME, code);
			}
			catch (final CoreException e) {
				logReadingError(e);
			}
			this.startRSnippetValue.setValue(code);
		}
		{	String code= ""; //$NON-NLS-1$
			try {
				code= configuration.getAttribute(AppControlConfigs.STOP_R_SNIPPET_CODE_ATTR_NAME, code);
			}
			catch (final CoreException e) {
				logReadingError(e);
			}
			this.stopRSnippetValue.setValue(code);
		}
	}
	
	@Override
	protected void doSave(final ILaunchConfigurationWorkingCopy configuration) {
//		{	final String path= this.appPathValue.getValue();
//			configuration.setAttribute(AppControlConfig.EXPL_SOURCE_PATH_ATTR_NAME, path);
//		}
		
		{	final String text= this.appHostValue.getValue();
			configuration.setAttribute(AppControlConfigs.APP_HOST_ATTR_NAME, text);
		}
		{	final Integer port= this.appPortValue.getValue();
			if (port != null) {
				configuration.setAttribute(AppControlConfigs.APP_PORT_ATTR_NAME, port.intValue());
			}
			else {
				configuration.removeAttribute(AppControlConfigs.APP_PORT_ATTR_NAME);
			}
		}
		
		{	final int mode= (this.startStopRunningValue.getValue()) ? 1 : 0;
			configuration.setAttribute(AppControlConfigs.START_STOP_BLOCKING_TASKS_MODE_ATTR_NAME, mode);
		}
		{	final String code= this.startRSnippetValue.getValue();
			configuration.setAttribute(AppControlConfigs.START_R_SNIPPET_CODE_ATTR_NAME, code);
		}
		{	final String code= this.stopRSnippetValue.getValue();
			configuration.setAttribute(AppControlConfigs.STOP_R_SNIPPET_CODE_ATTR_NAME, code);
		}
	}
	
}
