/*******************************************************************************
 * Copyright (c) 2005, 2009 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
 *     Brad Reynolds - bugs 116920, 160000
 *     Matthew Hall - bugs 260329, 260337
 *******************************************************************************/
package org.eclipse.jface.tests.databinding.scenarios;

import static org.junit.Assert.assertEquals;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.viewers.ViewerSupport;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.examples.databinding.model.Account;
import org.eclipse.jface.examples.databinding.model.Adventure;
import org.eclipse.jface.examples.databinding.model.Catalog;
import org.eclipse.jface.examples.databinding.model.Lodging;
import org.eclipse.jface.examples.databinding.model.SampleData;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Combo;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ComboScenarios extends ScenariosTestCase {

	protected ComboViewer cviewer = null;

	protected Combo combo = null;

	protected Catalog catalog = null;

	ILabelProvider lodgingLabelProvider = new LabelProvider() {
		@Override
		public String getText(Object element) {
			return ((Lodging) element).getName();
		}
	};

	ILabelProvider accountLabelProvider = new LabelProvider() {
		@Override
		public String getText(Object element) {
			return ((Account) element).getCountry();
		}
	};

	@Before
	public void setUp() throws Exception {
		super.setUp();
		getComposite().setLayout(new FillLayout());

		combo = new Combo(getComposite(), SWT.READ_ONLY | SWT.DROP_DOWN);
		cviewer = new ComboViewer(combo);

		catalog = SampleData.CATALOG_2005; // Lodging source
	}

	@After
	public void tearDown() throws Exception {
		combo.dispose();
		combo = null;
		cviewer = null;
		super.tearDown();
	}

	protected Object getViewerSelection() {
		return cviewer.getStructuredSelection().getFirstElement();
	}

	/**
	 * @return the ComboViewer's domain object list
	 */
	protected List getViewerContent(ComboViewer cviewer) {
		Object[] elements = ((IStructuredContentProvider) cviewer
				.getContentProvider()).getElements(null);
		if (elements != null)
			return Arrays.asList(elements);
		return null;
	}

	/**
	 *
	 * @return the combo's items (String[]), which is the same thing as the
	 *         Viewer's labels
	 *
	 */
	protected List getComboContent() {
		String[] elements = combo.getItems();
		if (elements != null)
			return Arrays.asList(elements);
		return null;
	}

	protected List getColumn(Object[] list, String feature) {
		List result = new ArrayList();
		if (list == null || list.length == 0)
			return result;
		String getterName = "get"
				+ feature.substring(0, 1).toUpperCase(Locale.ENGLISH)
				+ feature.substring(1);
		try {
			Method getter = list[0].getClass().getMethod(getterName,
					new Class[0]);
			try {
				for (int i = 0; i < list.length; i++) {
					result.add(getter.invoke(list[i], new Object[0]));
				}
			} catch (IllegalArgumentException e) {
			} catch (IllegalAccessException e) {
			} catch (InvocationTargetException e) {
			}
		} catch (SecurityException e) {
		} catch (NoSuchMethodException e) {
		}
		return result;
	}

	/**
	 * This test case deal with the 3rd scenario, using vanilla bindings: Ensure
	 * a valid content and selection are bounded correctly Bind a collection of
	 * Lodgings to a ComboViewer Bind the ComboViewer's selection to the
	 * defaultLodging of an Adventure
	 *
	 * This test does not deal with null values, empty content, changed content,
	 * property change of content elements, etc.
	 *
	 */
	@Test
	public void test_ROCombo_Scenario03_vanilla() {
		IObservableList lodgings = BeansObservables.observeList(Realm
				.getDefault(), catalog, "lodgings");
		ViewerSupport.bind(cviewer, lodgings, BeanProperties.value(
				Lodging.class, "name"));

		Adventure skiAdventure = SampleData.WINTER_HOLIDAY; // selection will

		// Ensure that cv's content now has the catalog's lodgings
		assertArrayEquals(catalog.getLodgings(), getViewerContent(cviewer)
				.toArray());

		// Ensure that the cv's labels are the same as the lodging descriptions
		assertEquals(getColumn(catalog.getLodgings(), "name"),
				getComboContent());

		getDbc().bindValue(ViewersObservables.observeSingleSelection(cviewer),
				BeansObservables.observeValue(skiAdventure, "defaultLodging"));

		// Check to see that the initial selection is the currentDefault Lodging
		assertEquals(getViewerSelection(), skiAdventure.getDefaultLodging());

		// Change the selection of the ComboViewer to all possible lodgings, and
		// verify that skiAdventure's default lodging was changed accordingly
		for (int i = 0; i < catalog.getLodgings().length; i++) {
			Object selection = catalog.getLodgings()[i];
			cviewer.setSelection(new StructuredSelection(selection));
			assertEquals(selection, skiAdventure.getDefaultLodging());
			assertEquals(getViewerSelection(), skiAdventure.getDefaultLodging());
		}

	}

	/**
	 * This test case deal with the 3rd scenario, and focuses on the collection
	 * binding to the combo. It will bind a collection, add/remove/change
	 * elements in the collection, and change element's properties to ensure
	 * that the combo's labels were updated appropriatly.
	 *
	 * it also induce null values in properties, and elments.
	 *
	 * This test does not deal with the combo's selection.
	 */
	@Test
	public void test_ROCombo_Scenario03_collectionBindings() {
		// column binding
		// Bind the ComboViewer's content to the available lodging
		IObservableList lodgings = BeansObservables.observeList(Realm
				.getDefault(), catalog, "lodgings");
		ViewerSupport.bind(cviewer, lodgings, BeanProperties.value(
				Lodging.class, "name"));

		// Ensure that cv's content now has the catalog's lodgings
		assertArrayEquals(catalog.getLodgings(), getViewerContent(cviewer)
				.toArray());

		// Ensure that the cv's labels are the same as the lodging descriptions
		assertEquals(getColumn(catalog.getLodgings(), "name"),
				getComboContent());

		// Add a lodging in the middle (not supported by the model right now)
		// Lodging lodging = SampleData.FACTORY.createLodging();
		// lodging.setName("Middle Lodging");
		// catalog.addLodging(lodging);
		// assertEquals(getViewerContent(cviewer).get(2), lodging);

		// Add a lodging at the end
		Lodging lodging = SampleData.FACTORY.createLodging();
		lodging.setName("End Lodging");
		catalog.addLodging(lodging);
		int index = getComboContent().size() - 1;
		assertEquals(getViewerContent(cviewer).get(index), lodging);

		// Delete the first Lodging
		catalog.removeLodging(catalog.getLodgings()[0]);
		// Ensure that the cv's labels are the same as the lodging descriptions
		assertEquals(getColumn(catalog.getLodgings(), "name"),
				getComboContent());

		// Delete middle Lodging
		catalog.removeLodging(catalog.getLodgings()[2]);
		// Ensure that the cv's labels are the same as the lodging descriptions
		assertEquals(getColumn(catalog.getLodgings(), "name"),
				getComboContent());

		// Change the names of all Lodging
		for (int i = 0; i < catalog.getLodgings().length; i++) {
			Lodging l = catalog.getLodgings()[i];
			l.setName("Changed: " + l.getName());
		}
		spinEventLoop(0); // force Async. efforts
		assertEquals(getColumn(catalog.getLodgings(), "name"),
				getComboContent());

		// Set to null value
		Lodging l = catalog.getLodgings()[0];
		assertEquals(combo.getItem(0), l.getName());
		l.setName(null);
		assertEquals("", combo.getItem(0));

		// set to empty list
		while (catalog.getLodgings().length > 0) {
			catalog.removeLodging(catalog.getLodgings()[0]);
			assertEquals(getColumn(catalog.getLodgings(), "name"),
					getComboContent());
		}
	}

	/**
	 * This scenario tests a simple SWT combo with a set item list where the
	 * selection is bouded to a String property
	 */
	// @Test
	// public void test_ROCombo_Scenario01() {
	//
	// // Read-Only Combo will not change its text property on a call to
	// // setText()
	//
	// String[] items = new String[] { "FairyLand", "TuneLand", "NoWereLand",
	// "TinkerLand", "DreamLand" };
	// combo.setItems(items);
	// Account account = catalog.getAccounts()[0];
	//
	// // simple Combo's selection bound to the Account's country property
	// getDbc().bind(new Property(combo, SWTProperties.SELECTION),
	// new Property(account, "country"), null);
	//
	// // Drive the combo selection
	// int index = 3;
	// combo.setText(items[index]); // this should drive the selection
	// assertEquals(account.getCountry(), items[index]);
	//
	// // Set the country, and ensure selection is set property
	// index = 1;
	// account.setCountry(items[index]);
	// assertEquals(index, combo.getSelectionIndex());
	// assertEquals(combo.getText(), items[index]);
	//
	// index = combo.getSelectionIndex();
	// String txt = combo.getText();
	// // Set the country to something that is not in the Combo's list
	// account.setCountry("FooBar");
	// // Combo's selection will not Change
	// assertEquals(combo.getSelectionIndex(), index);
	// assertEquals(combo.getText(), txt);
	//
	// }
	/**
	 * This scenario tests a simple SWT combo that is bound to a list of Country
	 * objects. The Country object's name property is listed in the Combo.
	 *
	 * The Combo's selection is bounded to the Country property of an Account.
	 */
	// @Test
	// public void test_ROCombo_Scenario02_SWTCombo() {
	//
	// // Create a list of Strings for the countries
	// IObservableList list = new WritableList();
	// for (int i = 0; i < catalog.getAccounts().length; i++)
	// list.add(catalog.getAccounts()[i].getCountry());
	//
	// // Bind the combo's content to that of the String based list
	// getDbc().bind(combo, list, null);
	// assertEquals(Arrays.asList(combo.getItems()), list);
	//
	// Account account = catalog.getAccounts()[0];
	//
	// // simple Combo's selection bound to the Account's country property
	// getDbc().bind(new Property(combo, SWTProperties.SELECTION),
	// new Property(account, "country"), null);
	//
	// // Drive the combo selection
	// String selection = (String) list.get(2);
	// combo.setText(selection); // this should drive the selection
	// assertEquals(account.getCountry(), selection);
	//
	// }
	/**
	 * This scenario tests a simple SWT combo that is bound to a list of Country
	 * objects. The Country object's name property is listed in the Combo.
	 *
	 * The Combo's selection is bounded to the Country property of an Account.
	 */
	// @Test
	// public void test_ROCombo_Scenario02_ComboViewer() {
	//
	// // Account label provider will fill the combo with the country
	// cviewer.setLabelProvider(accountLabelProvider);
	// // Bind the ComboViewer's content to the available accounts
	// getDbc().bind(
	// cviewer,
	// new ListModelDescription(new Property(catalog, "accounts"),
	// "country"), null);
	//
	// // Ensure that cv's content now has the catalog's accounts
	// assertArrayEquals(catalog.getAccounts(), getViewerContent(cviewer)
	// .toArray());
	// // Ensure that the cv's labels are the same as the account countries
	// assertEquals(getColumn(catalog.getAccounts(), "country"),
	// getComboContent());
	//
	// Account account = SampleData.FACTORY.createAccount();
	//
	// // Use the Viewers visual Combo (Strings) to set the account's country
	// getDbc().bind(new Property(combo, SWTProperties.SELECTION),
	// new Property(account, "country"), null);
	//
	// // Change the selection of the ComboViewer to all possible accounts, and
	// // verify that the account's Country is being changed correctly.
	// for (int i = 0; i < catalog.getAccounts().length; i++) {
	// Account selection = catalog.getAccounts()[i];
	// cviewer.setSelection(new StructuredSelection(selection));
	// assertEquals(selection.getCountry(), account.getCountry());
	// }
	//
	// }
	/**
	 * This test ensure that multiple combos can be bound to the same deomain
	 * model
	 */
	@Test
	public void test_ROCombo_multipleBindings() {
		Adventure skiAdventure = SampleData.WINTER_HOLIDAY; // for selection

		// Bind the ComboViewer's content to the available lodging
		IObservableList lodgings = BeansObservables.observeList(Realm
				.getDefault(), catalog, "lodgings");
		ViewerSupport.bind(cviewer, lodgings, BeanProperties.value(
				Lodging.class, "name"));

		// Ensure that cv's content now has the catalog's lodgings
		assertArrayEquals(catalog.getLodgings(), getViewerContent(cviewer)
				.toArray());

		// Ensure that the cv's labels are the same as the lodging descriptions
		assertEquals(getColumn(catalog.getLodgings(), "name"),
				getComboContent());

		ComboViewer otherViewer = new ComboViewer(getComposite(), SWT.NONE);
		ViewerSupport.bind(otherViewer, lodgings, BeanProperties.value(
				Lodging.class, "name"));

		// Ensure that cv's content now has the catalog's lodgings
		assertArrayEquals(catalog.getLodgings(), getViewerContent(otherViewer)
				.toArray());

		// Bind both selections to the same thing
		IObservableValue selection = ViewersObservables
				.observeSingleSelection(cviewer);
		getDbc().bindValue(selection,
				BeansObservables.observeValue(skiAdventure, "defaultLodging"));

		IObservableValue otherSelection = ViewersObservables
				.observeSingleSelection(otherViewer);
		getDbc().bindValue(otherSelection,
				BeansObservables.observeValue(skiAdventure, "defaultLodging"));

		Lodging lodging = catalog.getLodgings()[0];

		// Ensure that setting the selection is driven forward to the other
		// combo
		cviewer.setSelection(new StructuredSelection(lodging));
		assertEquals(cviewer.getStructuredSelection().getFirstElement(),
				otherViewer.getStructuredSelection().getFirstElement());

		// Change the list of one combo, and ensure it updates the other combo
		catalog.removeLodging(lodging);
		assertEquals(getViewerContent(cviewer), getViewerContent(otherViewer));

	}

	/**
	 * This scenario tests a simple SWT CCombo that is bound to a list of
	 * Country objects. The Country object's name property is listed in the
	 * Combo.
	 *
	 * The Combo's selection is bounded to the Country property of an Account.
	 */
	@Test
	public void test_ROCombo_SWTCCombo() {

		// Create a list of Strings for the countries
		IObservableList list = new WritableList();
		for (int i = 0; i < catalog.getAccounts().length; i++)
			list.add(catalog.getAccounts()[i].getCountry());

		CCombo ccombo = new CCombo(getComposite(), SWT.READ_ONLY
				| SWT.DROP_DOWN);

		// Bind the combo's content to that of the String based list
		getDbc().bindList(SWTObservables.observeItems(ccombo), list);
		assertEquals(Arrays.asList(ccombo.getItems()), list);

		Account account = catalog.getAccounts()[0];

		// simple Combo's selection bound to the Account's country property
		IObservableValue comboSelection = SWTObservables
				.observeSelection(ccombo);
		getDbc().bindValue(comboSelection,
				BeansObservables.observeValue(account, "country"));

		// Drive the combo selection
		String selection = (String) list.get(2);
		ccombo.setText(selection); // this should drive the selection
		assertEquals(account.getCountry(), selection);

	}

	/**
	 * This scenario tests a simple SWT CCombo that is bound to a list of
	 * Country objects. The Country object's name property is listed in the
	 * Combo.
	 *
	 * The Combo's selection is bounded to the Country property of an Account.
	 */
	@Test
	public void test_WCombo_SWTCCombo() {

		// Create a list of Strings for the countries
		IObservableList list = new WritableList();
		for (int i = 0; i < catalog.getAccounts().length; i++)
			list.add(catalog.getAccounts()[i].getCountry());

		CCombo ccombo = new CCombo(getComposite(), SWT.READ_ONLY
				| SWT.DROP_DOWN);

		// Bind the combo's content to that of the String based list
		getDbc().bindList(SWTObservables.observeItems(ccombo), list);
		assertEquals(Arrays.asList(ccombo.getItems()), list);

		Account account = catalog.getAccounts()[0];

		// simple Combo's selection bound to the Account's country property
		IObservableValue comboSelection = SWTObservables
				.observeSelection(ccombo);
		getDbc().bindValue(comboSelection,
				BeansObservables.observeValue(account, "country"));

		// Drive the combo selection
		String selection = (String) list.get(2);
		ccombo.setText(selection); // this should drive the selection
		assertEquals(account.getCountry(), selection);

		selection = (String) list.get(1);
		account.setCountry(selection);
		assertEquals(selection, ccombo.getItem(ccombo.getSelectionIndex()));
		assertEquals(selection, ccombo.getText());

		selection = "country not in list";
		account.setCountry(selection);
		assertEquals(-1, ccombo.getSelectionIndex());
		assertEquals(selection, ccombo.getText());
	}

	/**
	 * This scenario tests a simple SWT CCombo that is bound to a list of
	 * Country objects. The Country object's name property is listed in the
	 * Combo.
	 *
	 * The Combo's selection is bounded to the Country property of an Account.
	 */
	@Test
	public void test_ROCombo_SWTList() {

		// Create a list of Strings for the countries
		IObservableList list = new WritableList();
		for (int i = 0; i < catalog.getAccounts().length; i++)
			list.add(catalog.getAccounts()[i].getCountry());

		org.eclipse.swt.widgets.List swtlist = new org.eclipse.swt.widgets.List(
				getComposite(), SWT.READ_ONLY | SWT.SINGLE);

		// Bind the combo's content to that of the String based list
		getDbc().bindList(SWTObservables.observeItems(swtlist), list);
		assertEquals(Arrays.asList(swtlist.getItems()), list);

		Account account = catalog.getAccounts()[0];

		// simple Combo's selection bound to the Account's country property
		IObservableValue listSelection = SWTObservables
				.observeSelection(swtlist);
		getDbc().bindValue(listSelection,
				BeansObservables.observeValue(account, "country"));

		String selection = (String) list.get(2);
		swtlist.select(2); // this should drive the selection
		swtlist.notifyListeners(SWT.Selection, null); // Force notification
		assertEquals(account.getCountry(), selection);

	}

}
