function RespObj = axeslims(RespObj)
%AXESLIMS  Sets the axes limits for Bode Response Objects
%
%   RespObj = AXESLIMS(RespObj)

%   Authors: Karen Gondoly, 5-14-98
%   Revised: Adam DiVergilio, 11-99
%   Copyright 1986-2000 The MathWorks, Inc. 
%   $Revision: 1.24 $  $Date: 2000/06/14 20:11:34 $

% RE: RespObj is a BODPLOT object

%---Get key response properties
AllRespProps = get(RespObj,'Undocumented');
DispAx = AllRespProps.PlotAxes;  
Xlims = AllRespProps.Xlim;
Ylims = AllRespProps.Ylim;
AutoX = strcmp(AllRespProps.XlimMode,'auto');
AutoY = strcmp(AllRespProps.YlimMode,'auto');

%---Find visible Nyquist lines and response characteristic lines 
SHH = get(0,'ShowHiddenHandles');
set(0,'ShowHiddenHandles','on');
NyqLine = findobj(DispAx,'Tag','NyquistLines','Visible','on');
PRLines = findobj(DispAx,'Tag','PeakResponseMarker','Visible','on','Marker','none');
MargLines = findobj(DispAx,'Tag','StabilityMarginMarker','LineStyle','-.','Visible','on');
set(0,'ShowHiddenHandles',SHH)

%---Set axis lim mode
if AutoX,
   set(MargLines,'visible','off')
   set(DispAx(:),'XlimMode','auto')
end
if AutoY,
   %--Hide extra lines as they may interfer with Y limit computation when making  
   %  some models invisible 
   set([NyqLine;PRLines],'visible','off')
   set(DispAx(:),'YlimMode','auto')
end  


%---Adjust X-limits
if AutoX,
   % Compute first tick past largest Nyquist frequency
   % (to show at least one tick past largest visible Nyquist frequency)
   if ~isempty(NyqLine)
      nfs = get(NyqLine,{'Xdata'});
      nfs = cat(1,nfs{:});
      nfmax = max(nfs(:,1));             % largest Nyquist freq
      nfdec = 10^floor(log10(nfmax));    % corresponding decade
      nftick = round(nfmax/nfdec);
      LastXtick = max(nftick+1,(nftick>6)*10) * nfdec;
   else
      LastXtick = [];
   end
   
   %---Make sure X-limits do not exceed range of data
   % REVISIT: Not FRD-robust
   %          LastXtick should be incorporated in [FMIN,FMAX] range attached to each model
   %          and X limits will be set manually all the time
   Xextent = datext(findobj(DispAx(:),'Tag','LTIresponseLines','Visible','on'),'x','log');
   Xmin = Xextent(1);
   Xmax = max([LastXtick ; Xextent(2)]);
   if AutoY,
      Xlims(:) = {[Xmin Xmax]};
   else
      %---Take into account auto X-limits when not all data is shown
      for ctax=1:size(DispAx,2),
         aXlims = get(DispAx(:,ctax),{'Xlim'});
         aXlims = cat(1,aXlims{:});
         Xlims{ctax}(1) = max(Xmin,min(aXlims(:,1)));
         Xlims{ctax}(2) = min(Xmax,max(aXlims(:,2)));
      end
   end
end % if XlimMode=='auto'

%---Adjust Y limits
if AutoY,
   %---Enforce uniform Y-axis limits across each row
   for ctax=1:size(DispAx,1),
      Ylims{ctax} = findlims(DispAx(ctax,:),'Ylim');
   end 
end 

%---Adjust Y ticks (make them multiple of 45 degrees)
if strcmp(AllRespProps.ResponseType,'bode')
   set(DispAx(2:2:end,1),'YtickMode','auto')
   for ctax=2:2:size(DispAx,1),
      % Make sure ticks are relative to common Y range
      % (e.g., bode([tf(1,[1 0]),tf(1,[1 -1 1])]) )
      set(DispAx(ctax,:),'Ylim',Ylims{ctax})  
      Yticks = get(DispAx(ctax,1),'YTick');
      if AutoY
         % Auto mode. Determine data extent   
         VisLines = findobj(DispAx(ctax,:),'Tag','LTIresponseLines','Visible','on');
         Yextent = datext([VisLines;MargLines],'y'); 
         [NewTicks,NewLims] = phaseticks(Yticks,Ylims{ctax},Yextent);
         % Adjust Y limits so that new ticks extend to plot edges
         % (watch for constant phase lines flush with axis borders) 
         Ylims{ctax} = NewLims + [-0.01 0.01] * (NewLims(2)-NewLims(1));
      else
         % Fixed limit mode
         NewTicks = phaseticks(Yticks,Ylims{ctax});
      end
      set(DispAx(ctax,:),'YTick',NewTicks)
   end
end

%---Toggle grid
RespObj = plotgrid(RespObj);

%---Update axis limits in RespObj
%  RE: Leave XlimMode and YlimMode untouched
RespObj = respfcn('setxylims',RespObj,Xlims,Ylims);

%---Make sure Nyquist lines spans entire Ylimit range
if AutoY & ~isempty(NyqLine)
   Parent = get(NyqLine,{'Parent'});
   set(NyqLine,{'Ydata'},get(cat(1,Parent{:}),{'Ylim'}))
end

%---Make sure Margin lines spans entire Xlimit range
if AutoX & ~isempty(MargLines),
   Parent = get(MargLines,{'Parent'});
   set(MargLines,{'Xdata'},get(cat(1,Parent{:}),{'Xlim'}));
end

%---Make sure Peak Response lines span the X and Y limits
for ctL=1:length(PRLines),
   X = get(PRLines(ctL),'Xdata');
   Y = get(PRLines(ctL),'Ydata');
   Parent = get(PRLines(ctL),'Parent');
   if Y(1)~=Y(2),
      % Vertical line
      Ylim = get(Parent,'Ylim');
      set(PRLines(ctL),'Ydata',[Ylim(1) Y(2)])
   else
      % Horizontal line
      Xlim = get(Parent,'Xlim');
      set(PRLines(ctL),'Xdata',[Xlim(1) X(2)])
   end
end % for ctL

set([NyqLine;MargLines;PRLines],'visible','on')
