/*******************************************************************************
 * Copyright (c) 2005, 2007 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jface.examples.databinding.contentprovider.test;

import java.util.Iterator;
import java.util.Random;

import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.set.MappedSet;
import org.eclipse.core.databinding.observable.set.WritableSet;
import org.eclipse.core.databinding.observable.value.ComputedValue;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.viewers.ObservableSetContentProvider;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.internal.databinding.provisional.swt.ControlUpdater;
import org.eclipse.jface.internal.databinding.provisional.viewers.ViewerLabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

/**
 * Tests UpdatableSetContentProvider, ComputableValue, ControlUpdator,
 * UpdatableFunction, and ConvertingSet.
 * 
 * <p>
 * This test displays a dialog with user-editable list of Doubles. It allows the
 * user to select a math function to apply to the set, and displays the result
 * in a new list. A line of text along the bottom of the dialog displays the sum
 * of the elements from the transformed set. Although this dialog is rather
 * silly, it is a good example of a dialog where a lot of things can change from
 * many directions.
 * </p>
 * 
 * <p>
 * An UpdatableSetContentProvider is used to supply the contents each
 * ListViewer. ControlUpdators
 * 
 * </p>
 * 
 * @since 1.0
 */
public class StructuredContentProviderTest {

	private static Realm realm;

	/**
	 * Top-level shell for the dialog
	 */
	private Shell shell;

	/**
	 * Random number stream. Used for the "add" button.
	 */
	protected Random random = new Random();

	// Data model ////////////////////////////////////////////////////////

	/**
	 * inputSet stores a set of Doubles. The user is allowed to add and remove
	 * Doubles from this set.
	 */
	private WritableSet inputSet;

	/**
	 * currentFunction is an Integer, set to one of the SomeMathFunction.OP_*
	 * constants. It identifies which function will be applied to inputSet.
	 */
	private WritableValue currentFunction;

	/**
	 * mathFunction is the transformation. It can multiply by 2, round down to
	 * the nearest integer, or do nothing (identity)
	 */
	private SomeMathFunction mathFunction;

	/**
	 * Set of Doubles. Holds the result of applying mathFunction to the
	 * inputSet.
	 */
	private MappedSet outputSet;

	/**
	 * A Double. Stores the sum of the Doubles in outputSet
	 */
	private IObservableValue sumOfOutputSet;

	/**
	 * Creates the test dialog as a top-level shell.
	 */
	public StructuredContentProviderTest() {

		// Initialize the data model
		createDataModel();

		shell = new Shell(Display.getCurrent(), SWT.SHELL_TRIM);
		{ // Initialize shell
			final Label someDoubles = new Label(shell, SWT.NONE);
			someDoubles.setText("A list of random Doubles"); //$NON-NLS-1$
			someDoubles.setLayoutData(new GridData(
					GridData.HORIZONTAL_ALIGN_FILL
							| GridData.VERTICAL_ALIGN_FILL));

			Control addRemoveComposite = createInputControl(shell, inputSet);

			GridData addRemoveData = new GridData(GridData.FILL_BOTH);
			addRemoveData.minimumHeight = 1;
			addRemoveData.minimumWidth = 1;

			addRemoveComposite.setLayoutData(addRemoveData);

			Group operation = new Group(shell, SWT.NONE);
			{ // Initialize operation group
				operation.setText("Select transformation"); //$NON-NLS-1$

				createRadioButton(operation, currentFunction, "f(x) = x", //$NON-NLS-1$
						new Integer(SomeMathFunction.OP_IDENTITY));
				createRadioButton(operation, currentFunction, "f(x) = 2 * x", //$NON-NLS-1$
						new Integer(SomeMathFunction.OP_MULTIPLY));
				createRadioButton(operation, currentFunction,
						"f(x) = floor(x)", new Integer( //$NON-NLS-1$
								SomeMathFunction.OP_ROUND));

				GridLayout layout = new GridLayout();
				layout.numColumns = 1;
				operation.setLayout(layout);
			}
			operation.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
					| GridData.VERTICAL_ALIGN_FILL));

			Control outputControl = createOutputComposite(shell);
			GridData outputData = new GridData(GridData.FILL_BOTH);
			outputData.minimumHeight = 1;
			outputData.minimumWidth = 1;
			outputData.widthHint = 300;
			outputData.heightHint = 150;

			outputControl.setLayoutData(outputData);

			final Label sumLabel = new Label(shell, SWT.NONE);
			new ControlUpdater(sumLabel) {
				protected void updateControl() {
					double sum = ((Double) sumOfOutputSet.getValue())
							.doubleValue();
					int size = outputSet.size();

					sumLabel.setText("The sum of the above " + size //$NON-NLS-1$
							+ " doubles is " + sum); //$NON-NLS-1$
				}
			};
			sumLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
					| GridData.VERTICAL_ALIGN_FILL));

			GridLayout layout = new GridLayout();
			layout.numColumns = 1;
			shell.setLayout(layout);
		}

	}

	/**
	 * Create the updatables for this dialog
	 */
	private void createDataModel() {
		// Initialize data model. We will create a user-editable set of Doubles.
		// The user can run
		// a transformation on this set and view the result in a list viewer.

		// inputSet will be a writable set of doubles. The user will add and
		// remove entries from this set
		// through the UI.
		inputSet = new WritableSet(realm);

		// currentFunction holds the ID currently selected function to apply to
		// elements in the inputSet.
		// We will allow the user to change the current function through a set
		// of radio buttons
		currentFunction = new WritableValue(realm, new Integer(
				SomeMathFunction.OP_MULTIPLY), null);

		// mathFunction implements the selected function
		mathFunction = new SomeMathFunction(inputSet);
		currentFunction.addValueChangeListener(new IValueChangeListener() {
			public void handleValueChange(ValueChangeEvent event) {
				mathFunction
						.setOperation(((Integer) currentFunction.getValue())
								.intValue());
			}
		});
		mathFunction.setOperation(((Integer) currentFunction.getValue())
				.intValue());

		// outputSet holds the result. It displays the result of applying the
		// currently-selected
		// function on all the elements in the input set.
		outputSet = new MappedSet(inputSet, mathFunction);

		// sumOfOutputSet stores the current sum of the the Doubles in the
		// output set
		sumOfOutputSet = new ComputedValue(realm) {
			protected Object calculate() {
				double sum = 0.0;
				for (Iterator iter = outputSet.iterator(); iter.hasNext();) {
					Double next = (Double) iter.next();

					sum += next.doubleValue();
				}
				return new Double(sum);
			}
		};
	}

	/**
	 * Creates a radio button in the given parent composite. When selected, the
	 * button will change the given SettableValue to the given value.
	 * 
	 * @param parent
	 *            parent composite
	 * @param model
	 *            SettableValue that will hold the value of the
	 *            currently-selected radio button
	 * @param string
	 *            text to appear in the radio button
	 * @param value
	 *            value of this radio button (SettableValue will hold this value
	 *            when the radio button is selected)
	 */
	private void createRadioButton(Composite parent, final WritableValue model,
			String string, final Object value) {
		final Button button = new Button(parent, SWT.RADIO);
		button.setText(string);
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				model.setValue(value);
				super.widgetSelected(e);
			}
		});
		new ControlUpdater(button) {
			protected void updateControl() {
				button.setSelection(model.getValue().equals(value));
			}
		};
		button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
				| GridData.VERTICAL_ALIGN_FILL));
	}

	private Control createOutputComposite(Composite parent) {
		ListViewer listOfInts = new ListViewer(parent, SWT.BORDER
				| SWT.V_SCROLL | SWT.H_SCROLL);

		listOfInts.setContentProvider(new ObservableSetContentProvider());
		listOfInts.setLabelProvider(new ViewerLabelProvider());
		listOfInts.setInput(outputSet);
		return listOfInts.getControl();
	}

	/**
	 * Creates and returns a control that will allow the user to add and remove
	 * Doubles from the given input set.
	 * 
	 * @param parent
	 *            parent control
	 * @param inputSet
	 *            input set
	 * @return a newly created SWT control that displays Doubles from the input
	 *         set and allows the user to add and remove entries
	 */
	private Control createInputControl(Composite parent,
			final WritableSet inputSet) {
		Composite addRemoveComposite = new Composite(parent, SWT.NONE);
		{ // Initialize addRemoveComposite
			ListViewer listOfInts = new ListViewer(addRemoveComposite,
					SWT.BORDER);

			listOfInts.setContentProvider(new ObservableSetContentProvider());
			listOfInts.setLabelProvider(new ViewerLabelProvider());
			listOfInts.setInput(inputSet);

			final IObservableValue selectedInt = ViewersObservables.observeSingleSelection(listOfInts);

			GridData listData = new GridData(GridData.FILL_BOTH);
			listData.minimumHeight = 1;
			listData.minimumWidth = 1;
			listData.widthHint = 150;
			listData.heightHint = 150;
			listOfInts.getControl().setLayoutData(listData);

			Composite buttonBar = new Composite(addRemoveComposite, SWT.NONE);
			{ // Initialize button bar

				Button add = new Button(buttonBar, SWT.PUSH);
				add.setText("Add"); //$NON-NLS-1$
				add.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						inputSet.add(new Double(random.nextDouble() * 100.0));
						super.widgetSelected(e);
					}
				});
				add.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
						| GridData.VERTICAL_ALIGN_FILL));

				final Button remove = new Button(buttonBar, SWT.PUSH);
				remove.setText("Remove"); //$NON-NLS-1$
				// Enable the Remove button if and only if there is currently an
				// element selected.
				new ControlUpdater(remove) {
					protected void updateControl() {
						// This block demonstrates auto-listening.
						// When updateControl is running, the framework
						// remembers each
						// updatable that gets touched. Since we're calling
						// selectedInt.getValue()
						// here, this updator will be flagged as dependant on
						// selectedInt. This
						// means that whenever selectedInt changes, this block
						// of code will re-run
						// itself.

						// The result is that the remove button will recompute
						// its enablement
						// whenever the selection in the listbox changes, and it
						// was not necessary
						// to attach any listeners.
						remove.setEnabled(selectedInt.getValue() != null);
					}
				};

				remove.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						inputSet.remove(selectedInt.getValue());
						super.widgetSelected(e);
					}
				});
				remove.setLayoutData(new GridData(
						GridData.HORIZONTAL_ALIGN_FILL
								| GridData.VERTICAL_ALIGN_FILL));

				GridLayout buttonLayout = new GridLayout();
				buttonLayout.numColumns = 1;
				buttonBar.setLayout(buttonLayout);

			} // End button bar
			buttonBar.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
					| GridData.VERTICAL_ALIGN_BEGINNING));

			GridLayout addRemoveLayout = new GridLayout();
			addRemoveLayout.numColumns = 2;
			addRemoveComposite.setLayout(addRemoveLayout);
		}
		return addRemoveComposite;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Display display = Display.getDefault();
		realm = SWTObservables.getRealm(display);
		StructuredContentProviderTest test = new StructuredContentProviderTest();
		Shell s = test.getShell();
		s.pack();
		s.setVisible(true);

		while (!s.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}

	private Shell getShell() {
		return shell;
	}

}
