function varargout = zoomsm(Event,varargin)
%ZOOMSM  SISO Tool zoom management.
%
%   See also SISOTOOL.

%   Author(s): P. Gahinet  
%   Copyright 1986-2000 The MathWorks, Inc. 
%   $Revision: 1.7 $  $Date: 2000/07/26 17:14:40 $

% Parameters
ZoomFactor = 2/5;

persistent ZoomType AxisGrid Row Col X0 Y0 ZoomLine

% Process events
switch Event
    
case 'start'
    % Start zooming
    % ZOOMSM('start',ZoomType,AxisGrid,i,j)
    [ZoomType,AxisGrid,Row,Col] = deal(varargin{:});
    
    % Get initial position
    CP = get(AxisGrid(Row,Col),'CurrentPoint');
    X0 = CP(1,1);  Y0 = CP(1,2);
    
    % Create zoom line
    props = struct(...
        'Parent',AxisGrid(Row,Col),...
        'Visible','on',...
        'EraseMode','xor',...
        'Color',[0.5 0.5 0.5]);
    switch ZoomType
    case 'x-y'
        ZoomLine = line(NaN,NaN,props);
    case 'in-x'
        Ylim = get(AxisGrid(Row,Col),'Ylim');
        dY = 0.05 * (Ylim(2)-Ylim(1));
        ZoomLine = [line([X0 X0],[Y0-dY Y0+dY],props);...
                line([X0 X0],[Y0 Y0],props);...
                line([X0 X0],[Y0-dY Y0+dY],props)];
    case 'in-y'
        Xlim = get(AxisGrid(Row,Col),'Xlim');
        dX = 0.05 * (Xlim(2)-Xlim(1));
        ZoomLine = [line([X0-dX X0+dX],[Y0 Y0],props);...
                line([X0 X0],[Y0 Y0],props);...
                line([X0-dX X0+dX],[Y0 Y0],props)];
    end
        
    
case 'update'
    % Update zoom lines to track mouse movement
    CP = get(AxisGrid(Row,Col),'CurrentPoint');
    X = CP(1,1);  Y = CP(1,2);

    switch ZoomType
    case 'x-y'
        set(ZoomLine,'Xdata',[X0 X X X0 X0],'Ydata',[Y0 Y0 Y Y Y0])
    case 'in-x'
        set(ZoomLine(2),'Xdata',[X0 X])
        set(ZoomLine(3),'Xdata',[X X])
    case 'in-y'
        set(ZoomLine(2),'Ydata',[Y0 Y])
        set(ZoomLine(3),'Ydata',[Y Y])
    end
    
    
case 'finish'
    % Finish zooming
    [XlimMode,YlimMode] = deal(varargin{:});
	ZoomAxes = AxisGrid(Row,Col);
    
    % Current position
    CP = get(ZoomAxes,'CurrentPoint');
    X = CP(1,1);  Y = CP(1,2);

    % Get new X limits
    Xlim = get(ZoomAxes,'Xlim');
    if any(strcmp(ZoomType,{'x-y','in-x'})),
        NewX = LocalGetLims(sort([X0 X]),Xlim,...
			strcmp(get(ZoomAxes,'Xscale'),'log'));
	end
	
    % Get new Y limits
    Ylim = get(ZoomAxes,'Ylim');
    if any(strcmp(ZoomType,{'x-y','in-y'})),
		NewY = LocalGetLims(sort([Y0 Y]),Ylim,...
			strcmp(get(ZoomAxes,'Yscale'),'log'));
    end
    
    % Set new limits
    switch ZoomType
    case 'x-y'
        % Check if in point mode or rubber band mode
        set(AxisGrid(:,Col),'Xlim',NewX)
        set(AxisGrid(Row,:),'Ylim',NewY)
        XlimMode{Col} = 'manual';
        YlimMode{Row} = 'manual';
    case 'in-x'
        % Check if in point mode or rubber band mode
        set(AxisGrid(:,Col),'Xlim',NewX)
        XlimMode{Col} = 'manual';
    case 'in-y'
        % Check if in point mode or rubber band mode
        set(AxisGrid(Row,:),'Ylim',NewY)
        YlimMode{Row} = 'manual';
    end
    
    % Delete zoom lines
    delete(ZoomLine)
    
    % Return updated lim modes
    varargout = {XlimMode,YlimMode};
    
end

%%%%%%%%%% Local Functions %%%%%%%%%%%%%%%%%%%%%

function NewLims = LocalGetLims(NewLims,Lims,isLogScale)
			
if isLogScale,
	NewLims = log10(NewLims);
	Lims = log10(Lims);
end

if abs(NewLims(2)-NewLims(1))<0.01*(Lims(2)-Lims(1)),
	% Use point zoom (x2/5)
	dL = (Lims(2)-Lims(1))/5;
	NewLims = mean(NewLims) + [-dL,dL];
end

if abs(NewLims(2)-NewLims(1))<sqrt(eps)*max(abs(NewLims))
	% Stop zooming when running out of resolution
	NewLims = Lims;
end

if isLogScale,
	NewLims = 10.^NewLims;
end