/*=============================================================================#
 # 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.variables.IStringVariable;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jface.databinding.swt.typed.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.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.ecommons.databinding.core.validation.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;


@NonNullByDefault
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<@Nullable 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<String, Integer>()
						.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<String, String>()
						.setAfterGetValidator(new UpdateableErrorValidator<>(
								new VariableTextValidator(
										this.rSnippetVariableResolver,
										Messages.Operation_StartApp_RCode_error_SpecInvalid_message ))),
				null );
		dbc.bindValue(
				WidgetProperties.buttonSelection()
						.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) {
//		this.appPathValue.setValue(readAttribute(configuration, AppControlConfigs.EXPL_SOURCE_PATH_ATTR_NAME,
//				"" )); //$NON-NLS-1$
		
		{	final String text= readAttribute(configuration,
					AppControlConfigs.APP_HOST_ATTR_NAME,
					"" ); //$NON-NLS-1$
			this.appHostValue.setValue(text);
		}
		{	final int port= readAttribute(configuration,
					AppControlConfigs.APP_PORT_ATTR_NAME,
					0 );
			this.appPortValue.setValue((port != 0) ? Integer.valueOf(port) : null);
		}
		
		{	final int mode= readAttribute(configuration,
					AppControlConfigs.START_STOP_BLOCKING_TASKS_MODE_ATTR_NAME,
					0 );
			this.startStopRunningValue.setValue(mode > 0);
		}
		{	final String code= readAttribute(configuration,
					AppControlConfigs.START_R_SNIPPET_CODE_ATTR_NAME,
					"" ); //$NON-NLS-1$
			this.startRSnippetValue.setValue(code);
		}
		{	final String code= readAttribute(configuration,
					AppControlConfigs.STOP_R_SNIPPET_CODE_ATTR_NAME,
					"" ); //$NON-NLS-1$
			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);
		}
	}
	
}
