/*******************************************************************************
 * Copyright (c) 2007 Brad Reynolds 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:
 *     Brad Reynolds - initial API and implementation
 ******************************************************************************/

package org.eclipse.jface.tests.databinding.swt;

import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.jface.databinding.conformance.util.RealmTester;
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.internal.databinding.swt.ButtonObservableValue;
import org.eclipse.jface.internal.databinding.swt.CComboObservableList;
import org.eclipse.jface.internal.databinding.swt.CComboObservableValue;
import org.eclipse.jface.internal.databinding.swt.CLabelObservableValue;
import org.eclipse.jface.internal.databinding.swt.ComboObservableList;
import org.eclipse.jface.internal.databinding.swt.ComboObservableValue;
import org.eclipse.jface.internal.databinding.swt.LabelObservableValue;
import org.eclipse.jface.internal.databinding.swt.ListObservableList;
import org.eclipse.jface.internal.databinding.swt.ListObservableValue;
import org.eclipse.jface.internal.databinding.swt.SWTProperties;
import org.eclipse.jface.internal.databinding.swt.ScaleObservableValue;
import org.eclipse.jface.internal.databinding.swt.SpinnerObservableValue;
import org.eclipse.jface.internal.databinding.swt.TableSingleSelectionObservableValue;
import org.eclipse.jface.internal.databinding.swt.TextEditableObservableValue;
import org.eclipse.jface.internal.databinding.swt.TextObservableValue;
import org.eclipse.jface.tests.databinding.AbstractSWTTestCase;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Scale;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;

/**
 * @since 1.1
 */
public class SWTObservablesTest extends AbstractSWTTestCase {
	private Shell shell;

	protected void setUp() throws Exception {
		super.setUp();
		
		shell = getShell();
		RealmTester.setDefault(SWTObservables.getRealm(shell.getDisplay()));
	}

	protected void tearDown() throws Exception {
		super.tearDown();
		
		RealmTester.setDefault(null);
	}

	public void testObserveForeground() throws Exception {
		ISWTObservableValue value = SWTObservables.observeForeground(shell);
		assertNotNull(value);
		assertEquals(Color.class, value.getValueType());
	}

	public void testObserveBackground() throws Exception {
		ISWTObservableValue value = SWTObservables.observeBackground(shell);
		assertNotNull(value);
		assertEquals(Color.class, value.getValueType());
	}

	public void testObserveFont() throws Exception {
		ISWTObservableValue value = SWTObservables.observeFont(shell);
		assertNotNull(value);
		assertEquals(Font.class, value.getValueType());
	}

	public void testObserveSelectionOfSpinner() throws Exception {
		Spinner spinner = new Spinner(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeSelection(spinner);
		assertNotNull(value);
		assertTrue(value instanceof SpinnerObservableValue);

		SpinnerObservableValue spinnerObservable = (SpinnerObservableValue) value;
		assertEquals(SWTProperties.SELECTION, spinnerObservable.getAttribute());
	}

	public void testObserveSelectionOfButton() throws Exception {
		Button button = new Button(shell, SWT.PUSH);
		ISWTObservableValue value = SWTObservables.observeSelection(button);
		assertNotNull(value);
		assertTrue(value instanceof ButtonObservableValue);
	}

	public void testObserveSelectionOfCombo() throws Exception {
		Combo combo = new Combo(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeSelection(combo);
		assertNotNull(value);
		assertTrue(value instanceof ComboObservableValue);

		ComboObservableValue comboObservable = (ComboObservableValue) value;
		assertEquals(SWTProperties.SELECTION, comboObservable.getAttribute());
	}

	public void testObserveSelectionOfCCombo() throws Exception {
		CCombo combo = new CCombo(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeSelection(combo);
		assertNotNull(value);
		assertTrue(value instanceof CComboObservableValue);

		CComboObservableValue ccomboObservable = (CComboObservableValue) value;
		assertEquals(SWTProperties.SELECTION, ccomboObservable.getAttribute());
	}

	public void testObserveSelectionOfList() throws Exception {
		List list = new List(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeSelection(list);
		assertNotNull(value);
		assertTrue(value instanceof ListObservableValue);
	}
	
	public void testObserveSelectionOfScale() throws Exception {
		Scale scale = new Scale(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeSelection(scale);
		assertNotNull(value);
		assertTrue(value instanceof ScaleObservableValue);
		
		ScaleObservableValue scaleObservable = (ScaleObservableValue) value;
		assertEquals(SWTProperties.SELECTION, scaleObservable.getAttribute());
	}

	public void testObserveSelectionOfUnsupportedControl() throws Exception {
		try {
			Text text = new Text(shell, SWT.NONE);
			SWTObservables.observeSelection(text);
			fail("Exception should have been thrown");
		} catch (IllegalArgumentException e) {
		}
	}

	public void testObserveTextOfText() throws Exception {
		Text text = new Text(shell, SWT.NONE);
		assertFalse(text.isListening(SWT.FocusOut));

		ISWTObservableValue value = SWTObservables.observeText(text,
				SWT.FocusOut);
		assertNotNull(value);
		assertTrue(value instanceof TextObservableValue);
		assertTrue(text.isListening(SWT.FocusOut));
	}

	public void testObserveTextWithEventOfUnsupportedControl() throws Exception {
		Label label = new Label(shell, SWT.NONE);
		try {
			SWTObservables.observeText(label, SWT.FocusOut);
			fail("Exception should have been thrown");
		} catch (Exception e) {
		}
	}

	public void testObserveTextOfLabel() throws Exception {
		Label label = new Label(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeText(label);
		assertNotNull(label);
		assertTrue(value instanceof LabelObservableValue);
	}

	public void testObserveTextOfCLabel() throws Exception {
		CLabel label = new CLabel(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeText(label);
		assertNotNull(label);
		assertTrue(value instanceof CLabelObservableValue);
	}

	public void testObserveTextOfCombo() throws Exception {
		Combo combo = new Combo(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeText(combo);
		assertNotNull(value);
		assertTrue(value instanceof ComboObservableValue);

		ComboObservableValue comboObservable = (ComboObservableValue) value;
		assertEquals(SWTProperties.TEXT, comboObservable.getAttribute());
	}

	public void testObserveTextOfCCombo() throws Exception {
		CCombo combo = new CCombo(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeText(combo);
		assertNotNull(value);
		assertTrue(value instanceof CComboObservableValue);

		CComboObservableValue ccomboObservable = (CComboObservableValue) value;
		assertEquals(SWTProperties.TEXT, ccomboObservable.getAttribute());
	}

	public void testObserveTextOfUnsupportedControl() throws Exception {
		Table table = new Table(shell, SWT.NONE);
		try {
			SWTObservables.observeText(table);
			fail("Exception should have been thrown");
		} catch (IllegalArgumentException e) {
		}
	}

	public void testObserveItemsOfCombo() throws Exception {
		Combo combo = new Combo(shell, SWT.NONE);
		IObservableList list = SWTObservables.observeItems(combo);
		assertNotNull(list);
		assertTrue(list instanceof ComboObservableList);
	}

	public void testObserveItemsOfCCombo() throws Exception {
		CCombo ccombo = new CCombo(shell, SWT.NONE);
		IObservableList list = SWTObservables.observeItems(ccombo);
		assertNotNull(list);
		assertTrue(list instanceof CComboObservableList);
	}

	public void testObserveItemsOfList() throws Exception {
		List list = new List(shell, SWT.NONE);
		IObservableList observableList = SWTObservables.observeItems(list);
		assertNotNull(observableList);
		assertTrue(observableList instanceof ListObservableList);
	}

	public void testObserveItemsOfUnsupportedControl() throws Exception {
		Table table = new Table(shell, SWT.NONE);
		try {
			SWTObservables.observeItems(table);
			fail("Exception should have been thrown");
		} catch (IllegalArgumentException e) {
		}
	}

	public void testObserveSingleSelectionIndexOfTable() throws Exception {
		Table table = new Table(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables
				.observeSingleSelectionIndex(table);
		assertNotNull(value);
		assertTrue(value instanceof TableSingleSelectionObservableValue);
	}

	public void testObserveSingleSelectionIndexOfUnsupportedControl()
			throws Exception {
		Tree tree = new Tree(shell, SWT.NONE);
		try {
			SWTObservables.observeSingleSelectionIndex(tree);
			fail("Exception should have been thrown");
		} catch (IllegalArgumentException e) {

		}
	}
	
	public void testObserveMinOfSpinner() throws Exception {
		Spinner spinner = new Spinner(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeMin(spinner);
		assertNotNull(value);
		assertTrue(value instanceof SpinnerObservableValue);
		
		SpinnerObservableValue spinnerObservable = (SpinnerObservableValue) value;
		assertEquals(SWTProperties.MIN, spinnerObservable.getAttribute());
	}
	
	public void testObserveMinOfScale() throws Exception {
		Scale scale = new Scale(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeMin(scale);
		assertNotNull(value);
		assertTrue(value instanceof ScaleObservableValue);
		
		ScaleObservableValue scaleObservable = (ScaleObservableValue) value;
		assertEquals(SWTProperties.MIN, scaleObservable.getAttribute());
	}

	public void testObserveMinOfUnsupportedControl() throws Exception {
		Text text = new Text(shell, SWT.NONE);
		try {
			SWTObservables.observeMin(text);
			fail("Exception should have been thrown");
		} catch (IllegalArgumentException e) {	
		}
	}
	
	public void testObserveMaxOfSpinner() throws Exception {
		Spinner spinner = new Spinner(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeMax(spinner);
		assertNotNull(value);
		assertTrue(value instanceof SpinnerObservableValue);
		
		SpinnerObservableValue spinnerObservable = (SpinnerObservableValue) value;
		assertEquals(SWTProperties.MAX, spinnerObservable.getAttribute());
	}
	
	public void testObserveMaxOfScale() throws Exception {
		Scale scale = new Scale(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeMax(scale);
		assertNotNull(value);
		assertTrue(value instanceof ScaleObservableValue);
		
		ScaleObservableValue scaleObservable = (ScaleObservableValue) value;
		assertEquals(SWTProperties.MAX, scaleObservable.getAttribute());
	}
	
	public void testObserveMaxOfUnsupportedControl() throws Exception {
		Text text = new Text(shell, SWT.NONE);
		try {
			SWTObservables.observeMax(text);
			fail("Exception should have been thrown");
		} catch (IllegalArgumentException e) {
		}
	}
	
	public void testObserveEditableOfText() throws Exception {
		Text text = new Text(shell, SWT.NONE);
		ISWTObservableValue value = SWTObservables.observeEditable(text);
		assertNotNull(value);
		assertTrue(value instanceof TextEditableObservableValue);
	}
	
	public void testObserveEditableOfUnsupportedControl() throws Exception {
		Label label = new Label(shell, SWT.NONE);
		try {
			SWTObservables.observeEditable(label);
			fail("Exception should have been thrown");
		} catch (IllegalArgumentException e) {
		}
	}
}
