package com.planetmayo.debrief.satc.model.generator;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Iterator;
import java.util.TreeSet;

import com.planetmayo.debrief.satc.model.contributions.BaseContribution;
import com.planetmayo.debrief.satc.model.states.ProblemSpace;

public class TrackGenerator
{
	/**
	 * the problem space we consider
	 */
	private final ProblemSpace _space = new ProblemSpace();

	/**
	 * the set of contributions we listen to. They are ordered, so that we have
	 * data-producing contributions before those that purely perform analysis.
	 * Because of BaseContribution.compareTo, the contribs will be in this order:
	 * 1. Measurement
	 * 2. Forecast
	 * 3. Analysis
	 * 
	 * This is because we need some data before we start analysing it.
	 * 
	 */
	private TreeSet<BaseContribution> _contribs = new TreeSet<BaseContribution>();

	/**
	 * property listener = so we know about contibutions changing
	 * 
	 */
	private final PropertyChangeListener _contribListener = new PropertyChangeListener()
	{
		@Override
		public void propertyChange(PropertyChangeEvent arg0)
		{
			// let our custom method handle it
			propChange();
		}
	};

	/**
	 * something has changed - rerun the scenario constraint management
	 * 
	 */
	protected void propChange()
	{
		// ok, re-run our constraint generation
		Iterator<BaseContribution> iter = _contribs.iterator();
		while (iter.hasNext())
		{
			BaseContribution bC = (BaseContribution) iter.next();
			bC.actUpon(_space);
		}
	}

	/**
	 * store this new contribution
	 * 
	 * @param contribution
	 */
	public void addContribution(BaseContribution contribution)
	{
		// remember it
		_contribs.add(contribution);

		// start listening to it
		contribution.addPropertyChangeListener(BaseContribution.ACTIVE,
				_contribListener);
		contribution.addPropertyChangeListener(BaseContribution.HARD_CONSTRAINTS,
				_contribListener);
		contribution.addPropertyChangeListener(BaseContribution.START_DATE,
				_contribListener);
		contribution.addPropertyChangeListener(BaseContribution.FINISH_DATE,
				_contribListener);
	}

	/**
	 * remove this contribution
	 * 
	 * @param contribution
	 */
	public void removeContribution(BaseContribution contribution)
	{
		// remember it
		_contribs.remove(contribution);

		// start listening to it
		contribution.removePropertyChangeListener(BaseContribution.ACTIVE,
				_contribListener);
		contribution.removePropertyChangeListener(
				BaseContribution.HARD_CONSTRAINTS, _contribListener);
		contribution.removePropertyChangeListener(BaseContribution.START_DATE,
				_contribListener);
		contribution.removePropertyChangeListener(BaseContribution.FINISH_DATE,
				_contribListener);
	}

}

@@ -318,16 +318,126 @@
 Space;%0A%0A
+/** the top level manager object that handles the generation of bounded constraints%0A * %0A * @author ian%0A *%0A */%0A
 public c
@@ -815,20 +815,16 @@
 surement
-%0A%09 *
  2. Fore
@@ -827,20 +827,16 @@
 Forecast
-%0A%09 *
  3. Anal
@@ -932,16 +932,22 @@
 private 
+final 
 TreeSet%3C
@@ -1006,24 +1006,276 @@
 bution%3E();%0A%0A
+%09/** the set of contribution properties that we're interested in%0A%09 * %0A%09 */%0A%09private final String%5B%5D _interestingProperties =%0A%09%7B BaseContribution.ACTIVE, BaseContribution.HARD_CONSTRAINTS,%0A%09%09%09BaseContribution.START_DATE, BaseContribution.FINISH_DATE %7D;%0A%0A
 %09/**%0A%09 * pro
@@ -2113,287 +2113,117 @@
 t%0A%09%09
-contribution.addPropertyChangeListener(BaseContribution.ACTIVE,%0A%09%09%09%09_contribListener);%0A%09%09contribution.addPropertyChangeListener(BaseContribution.HARD_CONSTRAINTS,%0A%09%09%09%09_contribListener);%0A%09%09contribution.addPropertyChangeListener(BaseContribution.START_DATE,%0A%09%09%09%09_contribListener);%0A
+for (int i = 0; i %3C _interestingProperties.length; i++)%0A%09%09%7B%0A%09%09%09String thisProp = _interestingProperties%5Bi%5D;%0A%09
 %09%09co
@@ -2263,38 +2263,19 @@
 ner(
-BaseContribution.FINISH_DATE
+thisProp
 ,%0A
+%09
 %09%09%09%09
@@ -2289,24 +2289,28 @@
 bListener);%0A
+%09%09%7D%0A
 %09%7D%0A%0A%09/**%0A%09 *
@@ -2486,35 +2486,34 @@
 ution);%0A%0A%09%09// st
-art
+op
  listening to it
@@ -2519,297 +2519,117 @@
 t%0A%09%09
-contribution.removePropertyChangeListener(BaseContribution.ACTIVE,%0A%09%09%09%09_contribListener);%0A%09%09contribution.removePropertyChangeListener(%0A%09%09%09%09BaseContribution.HARD_CONSTRAINTS, _contribListener);%0A%09%09contribution.removePropertyChangeListener(BaseContribution.START_DATE,%0A%09%09%09%09_contribListener);%0A
+for (int i = 0; i %3C _interestingProperties.length; i++)%0A%09%09%7B%0A%09%09%09String thisProp = _interestingProperties%5Bi%5D;%0A%09
 %09%09co
@@ -2672,38 +2672,19 @@
 ner(
-BaseContribution.FINISH_DATE
+thisProp
 ,%0A
+%09
 %09%09%09%09
@@ -2702,14 +2702,18 @@
 tener);%0A
+%09%09%7D%0A
 %09%7D%0A%0A%7D%0A

refactor how we decide which contribution properties to listen to