package info.limpet.data.commands;

import info.limpet.ICollection;
import info.limpet.ICommand;
import info.limpet.IStore;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public abstract class AbstractCommand<T extends ICollection> implements ICommand<T>
{
	final private String _title;
	final private String _description;
	final private boolean _canUndo;
	final private boolean _canRedo;
	final private IStore _store;
	
	final protected List<T> _inputs;		
	final protected List<T> _outputs;

	public AbstractCommand(String title, String description, IStore store, boolean canUndo, boolean canRedo, List<T> inputs)
	{
		_title = title;
		_description = description;
		_store = store;
		_canUndo = canUndo;		
		_canRedo = canRedo;
		
		_inputs = inputs;
		_outputs = new ArrayList<T>();
	}
	
	
	
	@Override
	public void dataChanged()
	{
		// do the recalc
		recalculate();
		
		// now tell the outputs they have changed
		Iterator<T> iter = _outputs.iterator();
		while (iter.hasNext())
		{
			T t = (T) iter.next();
			t.fireChanged();
		}
	}

	abstract protected void recalculate();


	@Override
	public void collectionDeleted()
	{
	}



	public IStore getStore()
	{
		return _store;
	}
	
	@Override
	public String getTitle()
	{
		return _title;
	}

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

	@Override
	public void execute()
	{
		// ok, register as a listener with the input files
		Iterator<T> iter = _inputs.iterator();
		while (iter.hasNext())
		{
			T t = (T) iter.next();
			t.addChangeListener(this);			
		}
	}

	@Override
	public void undo()
	{
		throw new UnsupportedOperationException("Should not be called, undo not provided");
	}

	@Override
	public void redo()
	{
		throw new UnsupportedOperationException("Should not be called, redo not provided");
	}

	@Override
	public boolean canUndo()
	{
		return _canUndo;
	}

	@Override
	public boolean canRedo()
	{
		return _canRedo;
	}

	public List<T> getInputs()
	{
		return _inputs;
	}
	
	@Override
	public List<T> getOutputs()
	{
		return _outputs;
	}
	
	public void addOutput(T output)
	{
		_outputs.add(output);
	}



}

@@ -173,16 +173,44 @@
 erator;%0A
+import java.util.ArrayList;%0A
 import j
@@ -296,17 +296,19 @@
 plements
- 
+%0A%09%09
 ICommand
@@ -475,17 +475,16 @@
 _store;%0A
-%09
 %0A%09final 
@@ -509,18 +509,16 @@
 _inputs;
-%09%09
 %0A%09final 
@@ -617,17 +617,20 @@
 e store,
- 
+%0A%09%09%09
 boolean 
@@ -761,18 +761,16 @@
 canUndo;
-%09%09
 %0A%09%09_canR
@@ -784,18 +784,16 @@
 anRedo;%0A
-%09%09
 %0A%09%09_inpu
@@ -797,22 +797,40 @@
 nputs = 
+new ArrayList%3CT%3E(
 inputs
+)
 ;%0A%09%09_out
@@ -859,21 +859,16 @@
 %3E();%0A%09%7D%0A
-%09%0A%09%0A%09
 %0A%09@Overr
@@ -937,18 +937,16 @@
 late();%0A
-%09%09
 %0A%09%09// no
@@ -1148,17 +1148,16 @@
 ate();%0A%0A
-%0A
 %09@Overri
@@ -1199,18 +1199,16 @@
 %0A%09%7B%0A%09%7D%0A%0A
-%0A%0A
 %09public 
@@ -1244,25 +1244,24 @@
  _store;%0A%09%7D%0A
-%09
 %0A%09@Override%0A
@@ -1598,19 +1598,16 @@
 r(this);
-%09%09%09
 %0A%09%09%7D%0A%09%7D%0A
@@ -1675,32 +1675,37 @@
 rationException(
+%0A%09%09%09%09
 %22Should not be c
@@ -1812,16 +1812,21 @@
 ception(
+%0A%09%09%09%09
 %22Should 
@@ -2043,17 +2043,16 @@
 uts;%0A%09%7D%0A
-%09
 %0A%09@Overr
@@ -2109,17 +2109,16 @@
 uts;%0A%09%7D%0A
-%09
 %0A%09public
@@ -2174,12 +2174,10 @@
 t);%0A%09%7D%0A%0A
-%0A%0A
 %7D%0A

use a copy constructor, since the collection we use may later change