package utp;

public class ActiveGenerator<T> implements IActiveGenerator<T> {
	private Cell<T> cell;
	private T value = null;
	private ActiveGenerator<T> next = null;

	private ActiveGenerator(Cell<T> cell) {
		this.cell = cell;
	}

	public ActiveGenerator(IPassiveGenerator<T> passive) {
		this.cell = new Cell<T>();
		ICode<T> code = new ActiveCode<T>(cell);
		new ActiveThread<T>(passive, code, cell).start();
	}

	private void force() throws StopException {
		if (cell != null) {
			value = cell.get();
			next = new ActiveGenerator<T>(cell);
			cell = null;
		}
	}

	public IActiveGenerator<T> next() {
		try {
			force();
		} catch (StopException e) {
			return this;
		}
		return next;
	}

	public T value() throws StopException {
		force();
		return value;
	}

	public void stop() // for testing purpose only
	{
		if(next != null) next.stop();
		else stopThis();
	}
	
	protected void stopThis()
	{
		if (cell != null) {
			cell.stop();
		}
	}
	
	protected void finalize() {
		stopThis();
	}
}
