/*=============================================================================#
 # Copyright (c) 2008, 2021 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.nico.ui.util;

import static org.eclipse.statet.jcommons.status.Status.CANCEL_STATUS;
import static org.eclipse.statet.jcommons.status.Status.OK_STATUS;

import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.Status;
import org.eclipse.statet.jcommons.ts.core.ToolCommandData;

import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.dialogs.TitleAreaStatusUpdater;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ecommons.ui.workbench.ResourceInputComposite;

import org.eclipse.statet.internal.nico.ui.Messages;
import org.eclipse.statet.internal.nico.ui.NicoUIPlugin;
import org.eclipse.statet.nico.core.runtime.ConsoleService;
import org.eclipse.statet.nico.core.runtime.IProgressInfo;
import org.eclipse.statet.nico.core.runtime.ToolProcess;
import org.eclipse.statet.nico.core.util.AbstractConsoleCommandHandler;


/**
 * TODO: Better support for remote engines (resource mapping); disable OK button on errors?
 */
@NonNullByDefault
public class ChooseFileHandler extends AbstractConsoleCommandHandler {
	
	
	public static final String CHOOSE_FILE_COMMAND_ID= "common/chooseFile"; //$NON-NLS-1$
	
	
	private static class ChooseFileDialog extends ToolDialog {
		
		private final int mode;
		
		private final String message;
		
		private ResourceInputComposite locationGroup;
		private final WritableValue<String> newLocationValue;
		private final String historyId;
		
		
		public ChooseFileDialog(final Shell shell, final ToolProcess tool, final String message,
				final boolean newFile) {
			super(tool, shell, null, Messages.Util_ChooseFile_Dialog_title);
			
			this.mode= newFile ?
					(ResourceInputComposite.MODE_FILE | ResourceInputComposite.MODE_SAVE) :
					(ResourceInputComposite.MODE_FILE | ResourceInputComposite.MODE_OPEN);
			this.message= message;
			this.historyId= "statet:" + getTool().getMainType() + ":location.commonfile"; //$NON-NLS-1$ //$NON-NLS-2$
			
			final IFileStore current= getTool().getWorkspaceData().getWorkspaceDir();
			String dir= ""; //$NON-NLS-1$
			if (current != null) {
				final IPath path= URIUtil.toPath(current.toURI());
				if (path != null) {
					dir= path.toOSString();
				}
			}
			this.newLocationValue= new WritableValue<>(dir, String.class);
		}
		
		
		@Override
		protected IDialogSettings getDialogSettings() {
			return DialogUtils.getDialogSettings(NicoUIPlugin.getInstance(), "tools/ChooseFileDialog"); //$NON-NLS-1$
		}
		
		@Override
		protected Control createDialogContent(final Composite parent) {
			setTitle(this.message);
			
			final Composite composite= new Composite(parent, SWT.NONE);
			composite.setLayout(LayoutUtils.newCompositeGrid(1));
			
			final Composite inputComposite= new Composite(composite, SWT.NONE);
			inputComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
			inputComposite.setLayout(LayoutUtils.newCompositeGrid(2));
			
			this.locationGroup= new ResourceInputComposite(inputComposite,
					ResourceInputComposite.STYLE_COMBO,
					this.mode,
					Messages.Util_ChooseFile_File_label );
			this.locationGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
			final String[] history= getDialogSettings().getArray(this.historyId);
			this.locationGroup.setHistory(history);
			
			final DataBindingSupport databinding= new DataBindingSupport(composite);
			addBindings(databinding);
			
			this.newLocationValue.setValue((history != null && history.length > 0) ? history[0] : ""); //$NON-NLS-1$
			
			databinding.installStatusListener(new TitleAreaStatusUpdater(this, this.message));
			
			return composite;
		}
		
		protected void addBindings(final DataBindingSupport db) {
			db.getContext().bindValue(
					this.locationGroup.getObservable(),
					this.newLocationValue,
					new UpdateValueStrategy<String, String>()
							.setAfterGetValidator(this.locationGroup.getValidator()),
					null );
		}
		
		@Override
		protected void okPressed() {
			saveSettings();
			super.okPressed();
		}
		
		public void saveSettings() {
			final IDialogSettings settings= getDialogSettings();
			DialogUtils.saveHistorySettings(settings, this.historyId, this.newLocationValue.getValue());
		}
		
		public IFileStore getResource() {
			return this.locationGroup.getResourceAsFileStore();
		}
		
	}
	
	
	@Override
	public Status execute(final String id, final ConsoleService service, final ToolCommandData data,
			final ProgressMonitor m) {
		final String message;
		{	String s= data.getString("message"); //$NON-NLS-1$
			if (s == null) {
				final IProgressInfo progressInfo= service.getController().getProgressInfo();
				s= NLS.bind("Choose file (asked by {0}):", progressInfo.getLabel());
			}
			message= s;
		}
		final boolean newFile= data.getBooleanRequired("newResource"); //$NON-NLS-1$
		final var file= UIAccess.<@Nullable IFileStore>syncExecGet(() -> {
			final ChooseFileDialog dialog= new ChooseFileDialog(UIAccess.getActiveWorkbenchShell(true),
					service.getTool(), message, newFile );
			dialog.setBlockOnOpen(true);
			return (dialog.open() == Dialog.OK) ? dialog.getResource() : null;
		});
		if (file == null) {
			return CANCEL_STATUS;
		}
		{	final String fileName= file.toString();
			data.setReturnData("filename", fileName); //$NON-NLS-1$
			data.setReturnData("fileName", fileName); //$NON-NLS-1$
			data.setReturnData("filePath", fileName); //$NON-NLS-1$
		}
		return OK_STATUS;
	}
	
}
