function labelAxes( xAxisDivisions, figHandleVec, axisMat, zoomOut, ...
                    timeAxisGPSWeek, localOffset )
% $Id: labelAxes.m,v 1.4 2002/05/31 00:44:51 stuart Exp $
%
% labelAxes( xAxisStep, figHandle, axisMat, zoomOut )
% Passed [optional parameters in brackets]:
%   [xAxisDivisions]: number of divisions between labels. Thus number of
%                     labels = xAxisDivisions+1.
%   [figHandleVec]: figure handles. If not passed then set to the current
%                   figure handle.
%   [axisMat]: Matrix of original axis xmin,xmax,ymin,ymax values from
%              a call to axis(). Used to reset the ymin,ymax values, for
%              example after using the Matlab zoom feature when only the
%              x-axis (e.g. time) axis needs to be zoomed.
%   [zoomOut]: Flag, set = zoom out x and y axes to original limits.
%   [timeAxisGPSWeek]: plots x-axis as hours:minutes:seconds.
%   [localOffset]: local time offset in hours (ahead of UTC).
%                  If emtpy, assumed to be zero.
%
% Relabel x-axis. Matlab displays large values in exponent form, for
% example 7.3 x 10^4. To display as integers, an array of suitable
% integer labels is created, and turned into string values (which won't be
% "messed" with by Matlab).
%
% Also used to relabel x-axis and set y-axis to original plot max/min
% after using the Matlab zoom feature. It is assumed that only the
% x-axis needs to be zoomed (for example time), but its convenient to
% ignore the effect on the y-axis when selecting the x-axis zoom width.
%
% Also used to zoom out both x and y axis after using the Matlab zoom
% feature. The y-axis labelling is unchanged, and the x-axis is
% relabelled.
%
% Works with a vector of figure handles, which may contain multiple axes
% (legends ignored). With multiple axes figures, the y-axes are assumed
% to have the same originals limits (when restored).


if nargin < 1 | isempty( xAxisDivisions )
  xAxisDivisions = 5 ;
end
if nargin < 2 | isempty( figHandleVec )
  figHandleVec = gcf ;
end
if nargin < 3 | isempty( axisMat )
  resetYAxis = 0 ;
else
  resetYAxis = 1 ;  % Use axisMat to set y-axis to original values.
end
if nargin < 4 | isempty( zoomOut )
  zoomOut = 0 ;
end
if nargin < 5 | isempty( timeAxisGPSWeek )
  timeAxisGPSWeek = 0 ;
end  
if nargin < 6 | isempty( localOffset )
  localOffset = 0 ;
end  

rowIndex = 0 ;
for figHandle = figHandleVec

  % Note transpose to row vector to use in for loop.
  axisHandleVec = get( figHandle, 'children' )' ; 

  % Select only axes objects that are children of the figure, and
  % ignore axes that are legends.
  % Must order these so that subplots are serviced in the order top,
  % bottom. The order returned by get() above depends on which axes was
  % current at the end of plotting for this figure. This is critical.
  axisHandleVec = sort( axisHandleVec( ...
                     strcmp( get( axisHandleVec, 'type' ), 'axes' ) & ...
                    ~strcmp( get( axisHandleVec, 'tag'  ), 'legend' ) ) ) ;
  xMin = [] ;
  if ~zoomOut
    for axisHandle = axisHandleVec
    % Obtain max/min values for xmin and xmax for all axes. This enables
    % all axes to be zoomed-in to the same x-axis limits when using the
    % Matlab zoom feature on a single axis.
      axisLimitsVec = axis( axisHandle ) ;        % xmin,xmax,ymin,ymax.
      if isempty( xMin )
        xMin = axisLimitsVec( 1 ) ;
        xMax = axisLimitsVec( 2 ) ;
      else
        if axisLimitsVec( 1 ) > xMin
          xMin = axisLimitsVec( 1 ) ;
        end
        if axisLimitsVec( 2 ) < xMax
          xMax = axisLimitsVec( 2 ) ;
        end
      end
    end
  end

  for axisHandle = axisHandleVec
    rowIndex = rowIndex + 1 ;  % Every axis has a row in axisMat.

    axisLimitsVec = axis( axisHandle ) ;        % xmin,xmax,ymin,ymax.
    if zoomOut
    % Update axis x,y limits to original values when first plotted.
    % y axis limits are usually already restored, but if a Matlab zoom
    % is followed directy by the piLab zoom out, the y-axis is not yet
    % restored.
      axisLimitsVec = axisMat( rowIndex, : ) ;
      axis( axisHandle, axisLimitsVec ) ;            % Refresh.
    elseif resetYAxis
    % Update axis y limits to original values when first plotted.
    % Update axis x limits to "smallest" axes from all subplots.
    % Used after a Matlab zoom to remove the yaxis zoom, and
    % "transfer" a single zoom to all x-axes.
      axisLimitsVec( 1 ) = xMin ;  % xmin.

      axisLimitsVec( 2 ) = xMax ;  % xmax.
      axisLimitsVec( 3 ) = axisMat( rowIndex, 3 ) ;  % ymin.
      axisLimitsVec( 4 ) = axisMat( rowIndex, 4 ) ;  % ymax.
      axis( axisHandle, axisLimitsVec ) ;            % Refresh.
    end

    % Divide into 5 segments which will produce 6 labels, for example,
    % 10, 12, 14, 16, 18, 20. Accounts for min user selectable range of 10
    % seconds.
    % Must take the floor/ceil integer values in case the Matlab "zoom"
    % feature has been used which produces non-integer time axis limits.
    xMin = ceil( axisLimitsVec( 1 ) ) ;  % Ticks must be within axes.
    xMax = floor(  axisLimitsVec( 2 ) ) ;
    xStep = floor( ( xMax - xMin ) / xAxisDivisions ) ;
    if xStep == 0  % Zoomed in to a time duration < xAxisDivisions seconds.
      xStep = 1 ;
    end

    if timeAxisGPSWeek == 0  % Display time as hours:minutes:seconds of day.
      % For data sets > 1 hours, ensure that start time and intervals are on
      % even minutes.
      if xMax - xMin >= 3600
        startSeconds = mod( xMin, 60 ) ;
        % Ticks must be within axis, so step to next minute.
        if startSeconds > 0
          xMin = xMin - startSeconds + 60 ;
        end
        xStep = xStep - mod( xStep, 60 ) ;
      end
      xTick = xMin:xStep:xMax ;

      secondsVec = mod( xTick, 60 ) ;
      plotSeconds = any( secondsVec ) ;  % Set flag.
        
      for i = 1:length( xTick )
      % Build time labels as a cell array of strings.
        timeDay = xTick( i ) ;
        timeDay = timeDay + localOffset * 3600 ;  % Add local offset in hours.
        if timeDay < 0  % Offset has shifted into previous week.
          timeDay = timeDay + 604800 ;
        end
        day = fix( timeDay / 86400 ) ;
        timeDay = timeDay - day * 86400 ;
        hours = fix( timeDay / 3600 ) ;
        timeDay = timeDay - hours * 3600 ;
        minutes = fix( timeDay / 60 ) ;
        seconds = fix( timeDay - minutes * 60 ) ;

        if i == 1      % First label. Inlcude the day number.
          if day > 6   % Day range 0 to 6
            day = 0 ;  % Overflow can occur when localOffset applied above.
          end
          if plotSeconds
            % One or more of the labels includes seconds.
            xTickLabel = { sprintf( 'Day%d  %02d:%02d:%02d', ...
                                    day, hours, minutes, seconds ) } ;
          else
            % All seconds are zero, so omit from labels.
            xTickLabel = { sprintf( 'Day%d  %02d:%02d', ...
                                    day, hours, minutes ) } ;
          end
        else
          if plotSeconds
            xTickLabel = [ xTickLabel ...
                           { sprintf( '%02d:%02d:%02d', ...
                                      hours, minutes, seconds ) } ] ;
          else
            xTickLabel = [ xTickLabel ...
                           { sprintf( '%02d:%02d', hours, minutes ) } ] ;
          end
        end

      end
    else  
    % Display time as second of GPS week
      xTick = xMin:xStep:xMax ;

      % Convert integer label vector to string vector. num2str adds double
      % spaces between the numbers; or if the integers are single
      % digits, num2str adds triple spaces; or if the integers are 7
      % digits, num2str adds single spaces. This is simply handled by
      % specifying a format string in num2str (rather than using
      % strrep() to replace the white space with the '|' delimiter
      % required by the set() function).
      xTickLabel = num2str( xTick, '%.0f|' ) ;
      xTickLabel( end ) = [] ;  % Remove trailing '|' delimiter.
    end

    % xTickLabel is either a string, or a cell array of strings.
    set( axisHandle, 'XTick', xTick, ...
                     'XTickLabel', xTickLabel ) ;
  end    % for loop.
end      % for loop.


% End of function labelAxes.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% $Log: labelAxes.m,v $
% Revision 1.4  2002/05/31 00:44:51  stuart
% o Corrected a bug in the ACF code
% o Added a new mode which allows the C/No tests to be turned off.
%
% Revision 1.5  2002/05/28 14:41:35  timo
% Fix underflow at start of week when applying a negative 'local
% time offset'. Resulted in negative time on axis (hours:mins).
%
% Revision 1.4  2002/03/27 09:43:08  timo
% Add comment.
%
% Revision 1.3  2002/03/06 09:34:52  timo
% Fix problem with large time axis values. num2str can use single
% spaces between the fields when passing a vector.
%
% Revision 1.2  2002/02/14 10:37:03  timo
% Include time axis in hours:minutes:seconds, and local time offset.
%
% Revision 1.1  2001/02/20 11:09:01  timo
% Time (x-axis) relabelling and maintenance after using the Matlab
% zoom feature.
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
