function varargout=plotseq(F,X,varargin)
% plotseq - use arbitrary function to plot elements of sequence sequence 
%
% plotseq :: 
%    (A->handle)   ~'function to make a plot',
%    seq A         ~'data sequence to plot',
%    options {
%       ppre :: action unit ~'called before each plot';
%       ppost :: action unit ~'called after eacn plot';
%       mode :: {'gui','immed','null'} ~
%          'Controls how the iteration proceeds. 
%           gui: obtain next plot by clicking on title
%           immed: use function ITERATE to loop immediately
%           null: do nothing but return state fn and initial state'
%    }
% -> (plotseq_state -> plotseq_state) ~'state transformer',
%    plotseq_state ~'initial state.
%
% This works best (at all?) if the plotting function draws in one axes.
% The axes gains a clickable suffix to it's title. Button 1 click advances
% to the next object in the data sequence. Button 2 click rewinds to the
% beginning of the sequence. Alternatively the space bar advances and
% 'b' rewinds.


	opts=prefs('mode','gui','ppre',@nop,'ppost',@nop,varargin{:});

	fig=getparam(opts,'fig',gcf);
	figure(fig); ax=gca; hold off;
	fn=@nextplot;
	S0.i=1; S0.X=X;
	switch opts.mode
		case 'immed', iterate(fn,S0,opts);
		case 'gui', 
			disp('Click TITLE or [space] for next, button 2 click or [b] to rewind.');
			rotate3d off;
			zoom off; pan off;
			iterate_gui(fn,S0,opts);
	end

	if nargout==1, varargout{1}={fn,S0}; else varargout={fn,S0}; end
	

	% state machine to control output
	% 2nd return is handle of object to respond to mouse click for next/rewind
	function [S,ti]=nextplot(S)
		axes(ax);
		opts.ppre(); 
		F(head(S.X)); 
		ti=get(gca,'Title');
		set(ti,'String',sprintf('%s (%d)',get(ti,'String'),S.i));
		opts.ppost();

		S.i=S.i+1;
		S.X=next(S.X);
		if isempty(S.X), S=[]; end
	end
end % of main function

