/*******************************************************************************
 * Copyright (c) 2004, 2013 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Brock Janiczak (brockj@tpg.com.au) - Bug 145736
 *******************************************************************************/

package org.eclipse.ant.internal.ui.antsupport.inputhandler;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.input.DefaultInputHandler;
import org.apache.tools.ant.input.InputRequest;
import org.apache.tools.ant.input.MultipleChoiceInputRequest;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class SWTInputHandler extends DefaultInputHandler {

	private Text fText;
	private Combo fCombo;
	private Text fErrorMessageText;
	private Button fOkButton;
	private Shell fDialog;
	private FontMetrics fFontMetrics;
	protected InputRequest fRequest;
	private boolean fFirstValidation = true;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.input.InputHandler#handleInput(org.apache.tools.ant.input.InputRequest)
	 */
	@Override
	public void handleInput(InputRequest request) throws BuildException {
		if (System.getProperty("eclipse.ant.noInput") != null) { //$NON-NLS-1$
			throw new BuildException(RemoteAntMessages.getString("SWTInputHandler.0")); //$NON-NLS-1$
		}
		fFirstValidation = true;
		fRequest = request;
		BuildException[] problem = new BuildException[1];
		Runnable runnable = getHandleInputRunnable(problem);
		Display.getDefault().syncExec(runnable);
		if (problem[0] != null) {
			throw problem[0];
		}
	}

	protected Runnable getHandleInputRunnable(final BuildException[] problem) {
		return () -> {
			String prompt;
			if (fRequest instanceof MultipleChoiceInputRequest) {
				prompt = fRequest.getPrompt();
			} else {
				prompt = getPrompt(fRequest);
			}
			String title = RemoteAntMessages.getString("SWTInputHandler.1"); //$NON-NLS-1$
			boolean[] result = new boolean[1];
			open(title, prompt, result);

			if (!result[0]) {
				problem[0] = new BuildException(RemoteAntMessages.getString("SWTInputHandler.2")); //$NON-NLS-1$
			}
		};
	}

	protected void open(String title, String prompt, boolean[] result) {
		createDialog(title, prompt, result);
		validateInput();
		fDialog.open();

		while (!fDialog.isDisposed()) {
			if (!fDialog.getDisplay().readAndDispatch())
				fDialog.getDisplay().sleep();
		}
		Display.getDefault().dispose();
	}

	private void createDialog(String title, String prompt, boolean[] result) {
		Display display = Display.getDefault();
		fDialog = new Shell(display, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE);
		initializeDialogUnits(fDialog);
		fDialog.setLayout(new GridLayout());

		GridData gd = new GridData(SWT.FILL);
		gd.horizontalSpan = 2;
		fDialog.setLayoutData(gd);
		fDialog.setText(title);
		Label label = new Label(fDialog, SWT.WRAP);
		label.setText(prompt);
		GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL
				| GridData.VERTICAL_ALIGN_CENTER);

		data.widthHint = convertHorizontalDLUsToPixels(300); // from IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH
		label.setLayoutData(data);
		label.setFont(fDialog.getFont());

		if (fRequest instanceof MultipleChoiceInputRequest) {
			fCombo = new Combo(fDialog, SWT.BORDER | SWT.READ_ONLY);
			fCombo.add(""); //$NON-NLS-1$
			for (String text : ((MultipleChoiceInputRequest) fRequest).getChoices()) {
				fCombo.add(text);
				fCombo.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
				fCombo.addSelectionListener(new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						validateInput();
					}
				});
			}
		} else {
			fText = new Text(fDialog, SWT.SINGLE | SWT.BORDER);
			fText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
			fText.addModifyListener(new ModifyListener() {
				@Override
				public void modifyText(ModifyEvent e) {
					validateInput();
				}
			});
		}

		String value = null;
		try {
			fRequest.getClass().getMethod("getDefaultValue", new Class<?>[0]); //$NON-NLS-1$
			value = fRequest.getDefaultValue();
		}
		catch (SecurityException e) {
			// do nothing
		}
		catch (NoSuchMethodException e) {
			// pre Ant 1.7.0
		}

		fErrorMessageText = new Text(fDialog, SWT.READ_ONLY);
		fErrorMessageText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
		fErrorMessageText.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));

		createButtonBar(fDialog, result);

		if (value != null) {
			if (fCombo != null) {
				fCombo.select(fCombo.indexOf(value));
			} else {
				fText.setText(value);
				fText.selectAll();
			}
		}
		fDialog.pack();
	}

	protected void setErrorMessage(String errorMessage) {
		fErrorMessageText.setText(errorMessage == null ? "" : errorMessage); //$NON-NLS-1$
		fOkButton.setEnabled(errorMessage == null);
		fErrorMessageText.getParent().update();
	}

	protected void validateInput() {
		String errorMessage = null;
		if (fRequest instanceof MultipleChoiceInputRequest) {
			fRequest.setInput(fCombo.getText());
		} else {
			fRequest.setInput(fText.getText());
		}
		if (!fRequest.isInputValid()) {
			if (fFirstValidation) {
				errorMessage = ""; //$NON-NLS-1$
				fFirstValidation = false;
			} else {
				errorMessage = RemoteAntMessages.getString("SWTInputHandler.3"); //$NON-NLS-1$
			}
		}

		setErrorMessage(errorMessage);
	}

	protected Control createButtonBar(Composite parent, boolean[] result) {
		Composite composite = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.makeColumnsEqualWidth = true;
		composite.setLayout(layout);
		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER);
		composite.setLayoutData(data);
		composite.setFont(parent.getFont());

		createButtonsForButtonBar(composite, result);
		return composite;
	}

	protected void createButtonsForButtonBar(Composite parent, final boolean[] result) {
		fOkButton = new Button(parent, SWT.PUSH);
		fOkButton.setText(RemoteAntMessages.getString("SWTInputHandler.4")); //$NON-NLS-1$
		setButtonLayoutData(fOkButton);

		Button cancel = new Button(parent, SWT.PUSH);
		cancel.setText(RemoteAntMessages.getString("SWTInputHandler.5")); //$NON-NLS-1$
		Listener listener = new Listener() {
			@Override
			public void handleEvent(Event event) {
				result[0] = event.widget == fOkButton;
				fDialog.close();
			}
		};
		setButtonLayoutData(cancel);
		fOkButton.addListener(SWT.Selection, listener);
		fDialog.setDefaultButton(fOkButton);
		cancel.addListener(SWT.Selection, listener);
		// do this here because setting the text will set enablement on the ok button
		if (fRequest instanceof MultipleChoiceInputRequest) {
			fCombo.setFocus();
		} else {
			fText.setFocus();
		}
	}

	private void setButtonLayoutData(Button button) {
		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		int widthHint = convertHorizontalDLUsToPixels(61); // from IDialogConstants.BUTTON_WIDTH
		Point minSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
		data.widthHint = Math.max(widthHint, minSize.x);
		button.setLayoutData(data);
	}

	private int convertHorizontalDLUsToPixels(int dlus) {
		// round to the nearest pixel
		return (fFontMetrics.getAverageCharWidth() * dlus + 4 / 2) / 4;
	}

	protected void initializeDialogUnits(Control control) {
		// Compute and store a font metric
		GC gc = new GC(control);
		gc.setFont(control.getFont());
		fFontMetrics = gc.getFontMetrics();
		gc.dispose();
	}
}