classdef sigcat < sigbase
	properties (GetAccess=private, SetAccess=immutable)
		signals
	end
	methods
		function s=sigcat(varargin)
			fs=foldl(@unify_rates,nan,map(@rate,varargin));
			if isinf(fs), error('sampling rate mismatch'); end
			ch=foldl(@unify_channels,nan,map(@channels,varargin));
			if isinf(ch), error('channel count mismatch'); end
			s=s@sigbase(ch,fs);
			s.signals=varargin;
		end

		function s=tostring(sig)
			n=length(sig.signals);
			strx=map(@tostring,sig.signals);
			if n==1, s=strx{1};
			elseif n==2, s=sprintf('%s & %s',strx{1},strx{2});
			else s=sprintf('sigcat(%s,...)',strx{1});
			end
		end

		function s=construct(sig)
			sc=construct(sig.signals{1});
			sx=sig.signals(2:end);

			s.start   = @start;
			s.stop    = @stop;
			s.dispose = @dispose;
			s.reader  = @reader;

			function start, sc.start(); end
			function stop, sc.stop(); end
			function dispose, sc.dispose(); end 

			function r=reader(n)
				rc=sc.reader(n);
				r = @next;
				function [x,rem]=next
					[x,rem]=rc();
					while rem>0 && ~isempty(sx) % current signal exhausted, try next
						sc.dispose();
						sc=construct(sx{1}); sx=sx(2:end);
						[x(:,end-rem+1:end),rem]=sigreadn(sc,rem);
						rc=sc.reader(n);
					end
				end
			end
		end
	end
end
