function [Y,X0]=gathern(dim,n,X,varargin)
% gathern - make big array of n arrays in a sequence
%
% gathern :: N:natural, seq [D] -> [E], seq [D].
% gathern :: 
%    D:natural   ~'the dimension along which to collect arrays',
%    N:natural   ~'number of elements to collect',
%    seq [D]    ~'the seq to gather',
%    options {
%       draw   :: boolean /0    ~'whether or not to call plotfn every iteration';
%       plotfn :: seq [D]->handle ~'plotting function';
%       save   :: natural /0    ~'if >0, then save state every this many interations';
%       recover:: boolean / 0   ~'if 1, then attempt to restart from saved state'; 
%       id     :: string  /'@gather' ~'file to save state'
%    }
% -> [E], seq [D].
%
% E is such that E(I) = D(I) if I~=N. The second return
% is the final object in the sequence

Y=[]; i=1;
if nargin<3 % simple version
	if ~isempty(X),
		Y=head(X); 
		i=1; while i<n
			X0=X; X=next(X0); i=i+1;
			if isempty(X), break; end
			Y=cat(dim,Y,head(X)); 
		end
	end
else
	opts=options('save',0,'recover',0,'draw',0,'plotfn',@nullplot,varargin{:});
	draw=opts.draw;
	savn=opts.save;
	
	if opts.recover && exist([opts.id,'.mat'],'file')
		load(opts.id);		
		X=next(X0);
		fprintf('recovering from i=%d\n',i);
	end
	
	if savn==0 && ~draw
		if ~isempty(X)
			Y=head(X); 
			i=1; while i<n
				X0=X; X=next(X0); i=i+1;
				if isempty(X), break; end
				Y=cat(dim,Y,head(X)); 
			end
		end
	else
		if savn>0
			fprintf('Will save every %d iterations to %s.mat\n',savn,opts.id);
		end

		if ~isempty(X)
			Y=head(X);
			i=1; while i<n
				X0=X; X=next(X0); i=i+1;
				if draw, opts.plotfn(X0); end
				if mod(i,savn)==0,
					fprintf('saving at %d.\n',i);
					save(opts.id,'X0','Y','opts','i','dim');
				end
				optpause(opts); 
				if isempty(X), break; end
				Y=cat(dim,Y,head(X));
			end
		end
		if savn>0, delete([opts.id '.mat']); end
	end
	if nargout>1, if isempty(X), X0=X; else X0=next(X); end; end
end

function nullplot(A,B), return
