/*******************************************************************************
 * Copyright (c) 2008 Remy Chi Jian Suen and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Remy Chi Jian Suen <remy.suen@gmail.com> - initial API and implementation
 ******************************************************************************/
package org.eclipse.ecf.remoteservices.ui;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.ecf.internal.remoteservices.ui.Messages;
import org.eclipse.ecf.remoteservices.ui.RemoteMethod.Parameter;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.jface.window.SameShellProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Image;
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.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

/**
 * The MethodInvocationDialog allows a user to select a method given a
 * <code>java.lang.Class</code> to invoke and communicate with a remote service.
 * 
 * @since 2.0
 */
public final class MethodInvocationDialog extends Dialog {

	/**
	 * An integer constant that corresponds to the "Async Listener" selection.
	 * 
	 * @see #getInvocationType()
	 */
	public static final int ASYNC_LISTENER = 0;

	/**
	 * An integer constant that corresponds to the "Async Future Result"
	 * selection.
	 * 
	 * @see #getInvocationType()
	 */
	public static final int ASYNC_FUTURE_RESULT = ASYNC_LISTENER + 1;

	/**
	 * An integer constant that corresponds to the "Async Fire-and-Go"
	 * selection.
	 * 
	 * @see #getInvocationType()
	 */
	public static final int ASYNC_FIRE_AND_GO = ASYNC_FUTURE_RESULT + 1;

	/**
	 * An integer constant that corresponds to the "OSGi Service Proxy"
	 * selection.
	 * 
	 * @see #getInvocationType()
	 */
	public static final int OSGI_SERVICE_PROXY = ASYNC_FIRE_AND_GO + 1;
	/**
	 * An integer constant that corresponds to the "Remote Service Proxy"
	 * selection.
	 * 
	 * @see #getInvocationType()
	 */
	public static final int REMOTE_SERVICE_PROXY = OSGI_SERVICE_PROXY + 1;
	/**
	 * An integer constant that corresponds to the "Synchronous" selection.
	 * 
	 * @see #getInvocationType()
	 */
	public static final int SYNCHRONOUS = REMOTE_SERVICE_PROXY + 1;

	private static final String[] COLUMN_PROPERTIES = { "Parameter", "Argument" }; //$NON-NLS-1$ //$NON-NLS-2$

	/**
	 * Provide a default timeout value of 30,000 milliseconds.
	 */
	private static final String DEFAULT_TIMEOUT_VALUE = "30000"; //$NON-NLS-1$

	private TableViewer methodsViewer;
	private TableViewer parametersViewer;
	private Text timeoutText;
	private Combo invocationCombo;

	private final RemoteMethod[] methods;

	private Method method;
	private Object[] methodArguments;
	private int timeout;
	private int invocationType;

	/**
	 * Creates a new MethodInvocationDialog on top of the specified shell
	 * provider.
	 * 
	 * @param parentShell
	 *            the provider to return the parent shell of this dialog
	 * @param cls
	 *            the class to select the methods from
	 */
	public MethodInvocationDialog(IShellProvider parentShell, Class cls) {
		super(parentShell);
		Assert.isNotNull(cls);

		Method[] methods = cls.getMethods();
		final List validMethods = new ArrayList();
		for (int i = 0; i < methods.length; i++) {
			final Class[] parameters = methods[i].getParameterTypes();
			final String[] types = new String[parameters.length];

			if (types.length == 0) {
				validMethods.add(methods[i]);
				continue;
			}

			boolean match = true;
			for (int j = 0; j < types.length; j++) {
				final String name = parameters[j].getName();
				if (!name.equals("char") && !name.equals("boolean") //$NON-NLS-1$ //$NON-NLS-2$
						&& !name.equals("int") && !name.equals("double") //$NON-NLS-1$ //$NON-NLS-2$
						&& !name.equals("float") && !name.equals("long") //$NON-NLS-1$ //$NON-NLS-2$
						&& !name.equals("short") && !name.equals("byte") //$NON-NLS-1$ //$NON-NLS-2$
						&& !name.equals("java.lang.String")) { //$NON-NLS-1$
					match = false;
					break;
				}
			}
			if (match) {
				validMethods.add(methods[i]);
			}
		}

		methods = (Method[]) validMethods.toArray(new Method[validMethods
				.size()]);
		this.methods = new RemoteMethod[methods.length];
		for (int i = 0; i < methods.length; i++) {
			this.methods[i] = new RemoteMethod(methods[i]);
		}
	}

	/**
	 * Creates a new MethodInvocationDialog over the provided shell.
	 * 
	 * @param parentShell
	 *            the parent shell
	 * @param cls
	 *            the class to select the methods from
	 */
	public MethodInvocationDialog(Shell parentShell, Class cls) {
		this(new SameShellProvider(parentShell), cls);
	}

	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText(Messages.MethodInvocationDialog_ShellTitle);
	}

	protected Control createDialogArea(Composite parent) {
		parent = (Composite) super.createDialogArea(parent);

		final Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		composite.setLayout(new GridLayout(2, true));

		Label label = new Label(composite, SWT.LEAD);
		label.setText(Messages.MethodInvocationDialog_AvailableMethodsLabel);

		label = new Label(composite, SWT.LEAD);
		label.setText(Messages.MethodInvocationDialog_ArgumentsLabel);

		methodsViewer = new TableViewer(composite, SWT.V_SCROLL | SWT.H_SCROLL
				| SWT.BORDER);
		methodsViewer.getControl().setLayoutData(
				new GridData(SWT.FILL, SWT.FILL, true, true));
		methodsViewer.setContentProvider(new ArrayContentProvider());
		methodsViewer
				.addSelectionChangedListener(new ISelectionChangedListener() {
					public void selectionChanged(SelectionChangedEvent e) {
						final IStructuredSelection iss = (IStructuredSelection) e
								.getSelection();
						final Object element = iss.getFirstElement();
						if (element != null) {
							getButton(IDialogConstants.OK_ID).setEnabled(
									!timeoutText.getText().equals("")); //$NON-NLS-1$
							final RemoteMethod method = (RemoteMethod) element;
							parametersViewer.setInput(method.getParameters());
						}
					}
				});
		methodsViewer.setLabelProvider(new LabelProvider() {
			public String getText(Object element) {
				final RemoteMethod method = (RemoteMethod) element;
				return method.getReturnType() + ' ' + method.getSignature();
			}
		});

		parametersViewer = new TableViewer(composite, SWT.V_SCROLL
				| SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.BORDER);
		parametersViewer.getControl().setLayoutData(
				new GridData(SWT.FILL, SWT.FILL, true, true));
		parametersViewer.setContentProvider(new ArrayContentProvider());
		parametersViewer.setLabelProvider(new ITableLabelProvider() {
			public Image getColumnImage(Object element, int columnIndex) {
				return null;
			}

			public String getColumnText(Object element, int columnIndex) {
				final Parameter p = (Parameter) element;
				if (columnIndex == 0) {
					final String name = p.getParameter().getName();
					if (name.charAt(0) == 'j') {
						// this is java.lang.String
						return "String"; //$NON-NLS-1$
					} else {
						return name;
					}
				} else {
					return p.getArgument();
				}
			}

			public void addListener(ILabelProviderListener listener) {
			}

			public void dispose() {
			}

			public boolean isLabelProperty(Object element, String property) {
				return true;
			}

			public void removeListener(ILabelProviderListener listener) {
			}
		});
		parametersViewer.setCellEditors(new CellEditor[] { null,
				new TextCellEditor(parametersViewer.getTable()) });
		parametersViewer.setCellModifier(new ICellModifier() {
			public boolean canModify(Object element, String property) {
				return property.equals(COLUMN_PROPERTIES[1]);
			}

			public Object getValue(Object element, String property) {
				return ((Parameter) element).getArgument();
			}

			public void modify(Object element, String property, Object value) {
				if (property.equals(COLUMN_PROPERTIES[1])) {
					if (element instanceof TableItem) {
						final TableItem item = ((TableItem) element);
						final Parameter p = (Parameter) item.getData();
						final String argument = (String) value;
						p.setArgument(argument);
						item.setText(1, argument);
					}
				}
			}
		});
		parametersViewer.setColumnProperties(COLUMN_PROPERTIES);

		final Table table = parametersViewer.getTable();
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		TableColumn column = new TableColumn(table, SWT.LEAD);
		column.setWidth(150);
		column.setText(Messages.MethodInvocationDialog_ParameterColumn);
		column = new TableColumn(table, SWT.LEAD);
		column.setWidth(150);
		column.setText(Messages.MethodInvocationDialog_ValueColumn);

		methodsViewer.setInput(methods);

		final Composite bottomComposite = new Composite(composite, SWT.NONE);
		bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 2, 1));
		final GridLayout layout = new GridLayout(2, false);
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		bottomComposite.setLayout(layout);

		label = new Label(bottomComposite, SWT.LEAD);
		label.setText(Messages.MethodInvocationDialog_TimeoutLabel);
		label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, true));

		timeoutText = new Text(bottomComposite, SWT.BORDER);
		timeoutText.setText(DEFAULT_TIMEOUT_VALUE);
		timeoutText.addVerifyListener(new VerifyListener() {
			public void verifyText(VerifyEvent e) {
				switch (e.text.length()) {
				case 0:
					e.doit = true;
					break;
				case 1:
					e.doit = Character.isDigit(e.text.charAt(0));
					break;
				default:
					e.doit = false;
					break;
				}
			}
		});
		timeoutText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				getButton(IDialogConstants.OK_ID).setEnabled(
						!timeoutText.getText().equals("") //$NON-NLS-1$
								&& !methodsViewer.getSelection().isEmpty());
			}
		});
		timeoutText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
				false));

		label = new Label(bottomComposite, SWT.LEAD);
		label.setText(Messages.MethodInvocationDialog_InvocationTypeLabel);
		label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, true));

		invocationCombo = new Combo(bottomComposite, SWT.READ_ONLY);
		invocationCombo
				.setItems(new String[] {
						Messages.MethodInvocationDialog_InvocationTypeAsyncListener,
						Messages.MethodInvocationDialog_InvocationTypeAsyncFutureResult,
						Messages.MethodInvocationDialog_InvocationTypeAsyncFireAndGo,
						Messages.MethodInvocationDialog_InvocationTypeOSGiServiceProxy,
						Messages.MethodInvocationDialog_InvocationTypeRemoteServiceProxy,
						Messages.MethodInvocationDialog_InvocationTypeSynchronous });
		invocationCombo.select(0);
		bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false));

		return parent;
	}

	public void create() {
		super.create();
		final Button okButton = getButton(IDialogConstants.OK_ID);
		okButton.setEnabled(false);
		okButton.setText(Messages.MethodInvocationDialog_BUTTON_INVOKE_TEXT);
	}

	protected void okPressed() {
		final IStructuredSelection selection = (IStructuredSelection) methodsViewer
				.getSelection();
		final RemoteMethod remoteMethod = (RemoteMethod) selection
				.getFirstElement();
		method = remoteMethod.getMethod();
		final Parameter[] p = remoteMethod.getParameters();
		methodArguments = new Object[p.length];
		for (int i = 0; i < p.length; i++) {
			final String name = p[i].getParameter().getName();
			final String arg = p[i].getArgument();
			if (name.equals("char")) { //$NON-NLS-1$
				methodArguments[i] = new Character(arg.charAt(0));
			} else if (name.equals("boolean")) { //$NON-NLS-1$
				methodArguments[i] = Boolean.valueOf(arg);
			} else if (name.equals("int")) { //$NON-NLS-1$
				methodArguments[i] = Integer.valueOf(arg);
			} else if (name.equals("double")) { //$NON-NLS-1$
				methodArguments[i] = Double.valueOf(arg);
			} else if (name.equals("float")) { //$NON-NLS-1$
				methodArguments[i] = Float.valueOf(arg);
			} else if (name.equals("long")) { //$NON-NLS-1$
				methodArguments[i] = Long.valueOf(arg);
			} else if (name.equals("short")) { //$NON-NLS-1$
				methodArguments[i] = Short.valueOf(arg);
			} else if (name.equals("byte")) { //$NON-NLS-1$
				methodArguments[i] = Byte.valueOf(arg);
			} else {
				methodArguments[i] = arg;
			}
		}
		timeout = Integer.parseInt(timeoutText.getText());
		invocationType = invocationCombo.getSelectionIndex();
		super.okPressed();
	}

	/**
	 * Returns the method that has been selected by the user.
	 * 
	 * @return the selected method
	 */
	public Method getMethod() {
		return method;
	}

	/**
	 * Returns the arguments that has been specified by the user to pass to the
	 * method.
	 * 
	 * @return the list of arguments to pass into the method
	 */
	public Object[] getMethodArguments() {
		return methodArguments;
	}

	/**
	 * Retrieves the timeout value that has been specified by the user. This
	 * value is in milliseconds.
	 * 
	 * @return the timeout valued specified by the user in milliseconds
	 */
	public int getTimeout() {
		return timeout;
	}

	/**
	 * Returns the type of invocation that should be used to call the selected
	 * method to communicate with a remote service.
	 * 
	 * @return the invocation type selected by the user
	 * @see #ASYNC_LISTENER
	 * @see #ASYNC_FUTURE_RESULT
	 * @see #ASYNC_FIRE_AND_GO
	 * @see #OSGI_SERVICE_PROXY
	 * @see #REMOTE_SERVICE_PROXY
	 * @see #SYNCHRONOUS
	 */
	public int getInvocationType() {
		return invocationType;
	}
}
