%
% Show a text-based progress meter for Matlab:
%    progress(current, start, end)
%
% Plots a bar, and gives time remaining in seconds/minutes/hours, based
% on how the 'current' value compares to the 'start' and 'end' values.
% current, start, and end must all be real scalars
%
% Example:
%   for i=1:100,
%      progress(i,1,100);
%      % do something computationally intensive here
%   end
%

%
% P. Fieguth
% 2009
%

function progress(cv,lv,hv)
global progress_time progress_ltime progress_val progress_parms progress_strlen

if (lv>=hv), lv=hv-1; end;
if (cv<lv), cv=lv; end;
if (cv>hv), cv=hv; end;
backchar = sprintf( '\b' );

if (isempty(progress_parms)) || sum(abs(progress_parms-[lv hv]))>0 || cv<progress_val
  progress_val = lv;
  progress_parms = [lv hv];
  progress_time = clock;
  progress_ltime = clock;
  progress_strlen = 0;
else
  if ((cv-progress_val > (hv-lv)/50) || (etime(clock,progress_ltime) > 2))
    nd = round(55*(cv-lv)/(hv-lv));
    ns = 55-nd;
    s = [45*ones(1,nd) 32*ones(1,ns)];
    t = 0;
    u = 'sec';
    if (cv > lv) t = etime(clock,progress_time)*(hv-cv)/(cv-lv); end;
    if (t > 120), t = t/60; u = 'min'; end;
    if (t > 120), t = t/60; u = 'hrs'; end;
    strout = sprintf( '%3d%% [%s] (Left: %3d %s)',round(100*(cv-lv)/(hv-lv)),char(s),round(t),u);
    fprintf( 1, '%s', ones(1,progress_strlen)*backchar );
    fprintf( 1, '%s', strout );
    progress_strlen = length(strout);
    progress_val = cv;
    progress_ltime = clock;
  end;
  if (cv >= hv),
    fprintf( 1, '%s', ones(1,progress_strlen)*backchar );
  end;
end;