package org.eclipse.osbp.ecview.core.databinding.tests;

import static org.junit.Assert.assertEquals;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.beans.IBeanListProperty;
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.osbp.ecview.core.databinding.tests.bean.model.ChildDto;
import org.eclipse.osbp.ecview.core.databinding.tests.bean.model.ParentDto;
import org.junit.Test;

@SuppressWarnings({ "unchecked", "unused" })
public class TestBindBeanListToTarget {

	@Test
	public void test__2() {
		new MyRealm();

		ParentDto p = new ParentDto();
		ChildDto c1 = new ChildDto();
		ChildDto c2 = new ChildDto();

		p.addToChildren(c1);
		p.addToChildren(c2);

		IBeanListProperty prop = BeanProperties.list(ParentDto.class,
				"children", ChildDto.class);
		IObservableList pObservable = prop.observe(p);

		WritableList target = new WritableList();
		new DataBindingContext().bindList(target, pObservable);

		assertEquals(p.getChildren().size(), target.size());

		target.add(new ChildDto());
		assertEquals(p.getChildren().size(), target.size());

		p.addToChildren(new ChildDto());
		assertEquals(p.getChildren().size(), target.size());

		p.removeFromChildren(p.getChildren().get(0));
		assertEquals(p.getChildren().size(), target.size());

		target.remove(p.getChildren().get(0));
		assertEquals(p.getChildren().size(), target.size());
	}

	private static class MyRealm extends Realm {

		public MyRealm() {
			setDefault(this);
		}

		@Override
		public boolean isCurrent() {
			return true;
		}

	}

	private static class Bean {

		private List<String> writableList = new WritableList(new ArrayList<>(),
				String.class);

		public List<String> getWritableList() {
			return writableList;
		}

		public void setWritableList(List<String> writableList) {
			this.writableList = writableList;
		}

	}

	private static class BeanPlus {

		private PropertyChangeSupport pcs = new PropertyChangeSupport(this);

		private List<String> writableList = new WritableList(new ArrayList<>(),
				String.class);

		public List<String> getWritableList() {
			return writableList;
		}

		public void setWritableList(List<String> writableList) {
			List<String> old = this.writableList;
			this.writableList = writableList;
			pcs.firePropertyChange("writableList", old, this.writableList);
		}

		public void addPropertyChangeListener(PropertyChangeListener listener) {
			pcs.addPropertyChangeListener(listener);
		}

		public void removePropertyChangeListener(PropertyChangeListener listener) {
			pcs.removePropertyChangeListener(listener);
		}

		public void addPropertyChangeListener(String propertyName,
				PropertyChangeListener listener) {
			pcs.addPropertyChangeListener(propertyName, listener);
		}

		public void removePropertyChangeListener(String propertyName,
				PropertyChangeListener listener) {
			pcs.removePropertyChangeListener(propertyName, listener);
		}

	}

}
