package info.limpet.data.impl;

import info.limpet.IChangeListener;
import info.limpet.ICommand;
import info.limpet.IObjectCollection;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ObjectCollection<T extends Object> implements IObjectCollection<T>
{

	ArrayList<T> _values = new ArrayList<T>();
	private String _name;
	private String _description = "";
	private final ICommand<?> _precedent;
	private final List<ICommand<?>> _dependents;
	private final ListenerHelper _changeSupport;

	public ObjectCollection(String name)
	{
		this(name, null);
	}

	public ObjectCollection(String name, ICommand<?> precedent)
	{
		_name = name;
		_precedent = precedent;
		_dependents = new ArrayList<ICommand<?>>();
		_changeSupport = new ListenerHelper();
	}

	@Override
	public String getDescription()
	{
		return _description;
	}

	@Override
	public void setDescription(String description)
	{
		this._description = description;
	}

	@Override
	public List<T> getValues()
	{
		return _values;
	}

	@Override
	public void add(T value)
	{
		_values.add(value);
	}

	@Override
	public int size()
	{
		return _values.size();
	}

	@Override
	public String getName()
	{
		return _name;
	}

	@Override
	public boolean isQuantity()
	{
		return false;
	}

	@Override
	public boolean isTemporal()
	{
		return false;
	}

	@Override
	public ICommand<?> getPrecedent()
	{
		return _precedent;
	}

	@Override
	public List<ICommand<?>> getDependents()
	{
		return _dependents;
	}

	@Override
	public void addDependent(ICommand<?> command)
	{
		_dependents.add(command);
	}

	@Override
	public void setName(String name)
	{
		_name = name;
	}

	@Override
	public void addChangeListener(IChangeListener listener)
	{
		_changeSupport.add(listener);
	}

	@Override
	public void removeChangeListener(IChangeListener listener)
	{
		_changeSupport.remove(listener);
	}

	@Override
	public void fireChanged()
	{
		// tell any standard listeners
		_changeSupport.fireChange(this);

		// now tell the dependents
		Iterator<ICommand<?>> iter = _dependents.iterator();
		while (iter.hasNext())
		{
			ICommand<?> iC = (ICommand<?>) iter.next();
			iC.dataChanged(this);
		}
	}

	@Override
	public Class<?> storedClass()
	{
		@SuppressWarnings("unchecked")
		final Class<? extends ObjectCollection<?>> thisClass = (Class<? extends ObjectCollection<?>>) getClass();
		final Type superType = thisClass.getGenericSuperclass();
		if (superType instanceof ParameterizedType)
		{
			final ParameterizedType parameterizedType = (ParameterizedType) superType;
			return (Class<?>) parameterizedType.getActualTypeArguments()[0];
		}
		else
		{
			return null;
		}
	}

}

@@ -553,30 +553,151 @@
 ndents;%0A
-%09private final
+%0A%09// note: we make the change support listeners transient, since%0A%09// they refer to UI elements that we don't persist%0A%09private transient
  Listene
@@ -942,39 +942,42 @@
 ();%0A
+%0A
 %09%09
-_changeSupport = new 
+// setup helpers%0A%09%09init
 Listener
 Help
@@ -972,22 +972,17 @@
 Listener
-Helper
+s
 ();%0A%09%7D%0A%0A
@@ -1841,32 +1841,156 @@
 ame = name;%0A%09%7D%0A%0A
+%09protected void initListeners()%0A%09%7B%0A%09%09if (_changeSupport == null)%0A%09%09%09;%0A%09%09%7B%0A%09%09%09_changeSupport = new ListenerHelper();%0A%09%09%7D%0A%09%7D%0A%0A
 %09@Override%0A%09publ
@@ -2036,32 +2036,52 @@
 er listener)%0A%09%7B%0A
+%09%09initListeners();%0A%0A
 %09%09_changeSupport
@@ -2174,16 +2174,36 @@
 ner)%0A%09%7B%0A
+%09%09initListeners();%0A%0A
 %09%09_chang
@@ -2274,16 +2274,51 @@
 ed()%0A%09%7B%0A
+%09%09if (_changeSupport != null)%0A%09%09%7B%0A%09
 %09%09// tel
@@ -2344,16 +2344,17 @@
 eners%0A%09%09
+%09
 _changeS
@@ -2377,16 +2377,20 @@
 e(this);
+%0A%09%09%7D
 %0A%0A%09%09// n

make UI listeners transient