/*=============================================================================#
 # Copyright (c) 2007, 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.ecommons.debug.ui.util;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.dialogs.DialogTray;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;

import org.eclipse.statet.ecommons.debug.core.util.LaunchUtils;
import org.eclipse.statet.ecommons.ui.SharedUIResources;
import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.internal.ecommons.debug.ui.Messages;


/**
 * Shows the help for a command line tool in a dialog tray.
 */
public class HelpRequestor implements IRunnableWithProgress {
	
	
	private static class InfoTray extends DialogTray{
		
		private final TrayDialog fDialog;
		
		private Text fTextControl;
		private Label fCmdInfo;
		
		private InfoTray(final TrayDialog dialog) {
			this.fDialog = dialog;
		}
		
		@Override
		protected Control createContents(final Composite parent) {
			final FormToolkit toolkit = new FormToolkit(parent.getDisplay());
			
			final Composite container = new Composite(parent, SWT.NONE);
			container.addListener(SWT.Dispose, new Listener() {
				@Override
				public void handleEvent(final Event event) {
					toolkit.dispose();
				}
			});
			container.setLayout(new FillLayout(SWT.VERTICAL));
			
			final Form form = toolkit.createForm(container);
			toolkit.decorateFormHeading(form);
			form.setText("'--help'"); //$NON-NLS-1$
			form.getToolBarManager().add(new ContributionItem() {
				@Override
				public void fill(final ToolBar parent, final int index) {
					final ToolItem item = new ToolItem(parent, SWT.PUSH);
					item.setImage(SharedUIResources.getImages().get(SharedUIResources.LOCTOOL_CLOSETRAY_IMAGE_ID));
					item.setHotImage(SharedUIResources.getImages().get(SharedUIResources.LOCTOOL_CLOSETRAY_H_IMAGE_ID));
					item.setToolTipText(Messages.HelpRequestor_Close_tooltip);
					item.addSelectionListener(new SelectionAdapter() {
						@Override
						public void widgetSelected(final SelectionEvent e) {
							InfoTray.this.fDialog.closeTray();
							InfoTray.this.fDialog.getShell().setFocus();
						}
					});
				}
			});
			form.getToolBarManager().update(true);
			final Composite content = form.getBody();
			content.setLayout(new GridLayout());
			
			this.fCmdInfo = toolkit.createLabel(content, ">"); //$NON-NLS-1$
			this.fCmdInfo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
			
			this.fTextControl = toolkit.createText(content, "", SWT.MULTI | SWT.READ_ONLY | SWT.H_SCROLL | SWT.V_SCROLL); //$NON-NLS-1$
			this.fTextControl.setFont(JFaceResources.getFont(JFaceResources.TEXT_FONT));
			final GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
			gd.widthHint = new PixelConverter(this.fTextControl).convertWidthInCharsToPixels(50);
			this.fTextControl.setLayoutData(gd);
			
			return container;
		}
		
		public void update(final String cmdInfo, final String text) {
			this.fCmdInfo.setText(cmdInfo);
			this.fTextControl.setText(text);
		}
		
	}
	
	public static void closeHelpTray(final TrayDialog dialog) {
		if (dialog.getTray() instanceof HelpRequestor.InfoTray) {
			dialog.closeTray();
		}
	}
	
	
	private final TrayDialog fDialog;
	
	private final ProcessBuilder fBuilder;
	
	boolean fIsRunning;
	
	
	public HelpRequestor(final ProcessBuilder processBuilder, final TrayDialog dialog) {
		this.fBuilder = processBuilder;
		this.fDialog = dialog;
	}
	
	
	public ProcessBuilder getProcessBuilder() {
		return this.fBuilder;
	}
	
	@Override
	public void run(final IProgressMonitor monitor) throws InvocationTargetException {
		final String cmdInfo = LaunchUtils.generateCommandLine(this.fBuilder.command());
		monitor.beginTask(Messages.HelpRequestor_Task_name+cmdInfo, 10);
		if (monitor.isCanceled()) {
			return;
		}
		try {
			this.fBuilder.redirectErrorStream(true);
			monitor.worked(1);
			
			final ProcessOutputCollector reader = new ProcessOutputCollector(this.fBuilder, "'--help'", monitor);
			final String helpText = reader.collect();
			
			UIAccess.getDisplay().asyncExec(new Runnable() {
				@Override
				public void run() {
					InfoTray tray = null;
					if (HelpRequestor.this.fDialog.getTray() instanceof InfoTray) {
						tray = (InfoTray) HelpRequestor.this.fDialog.getTray();
					}
					else {
						if (HelpRequestor.this.fDialog.getTray() != null) {
							HelpRequestor.this.fDialog.closeTray();
						}
						tray = new InfoTray(HelpRequestor.this.fDialog);
						HelpRequestor.this.fDialog.openTray(tray);
					}
					tray.update(cmdInfo, helpText);
				}
			});
		}
		catch (final CoreException e) {
			throw new InvocationTargetException(e);
		}
		finally {
			monitor.done();
		}
	}
	
}
