function resize(Constr,action,SelectedMarkerIndex)
%RESIZE  Keeps track of gain constraint whilst resizing.

%   Author(s): A. Stothert
%   Copyright 1986-2004 The MathWorks, Inc. 
%   $Revision: 1.1.6.2 $  $Date: 2004/12/26 21:51:28 $

persistent Yinit Xinit sty mve Slope 
persistent MouseEditData

MagAxes = handle(Constr.Parent);
EventMgr = Constr.EventManager;

% Process event
switch action
case 'init'
   % Initialize RESIZE
   MouseEditData = ctrluis.dataevent(EventMgr,'MouseEdit',[]);
   
   % Convert the constraint line Y into dB
   Yinit  = Constr.yCoords(Constr.SelectedEdge,:);
   Xinit  = Constr.xCoords(Constr.SelectedEdge,:);
   mve = SelectedMarkerIndex;      % 1 if left marker moved, 2 otherwise
   sty = 3 - SelectedMarkerIndex;
   
   % Initialize axes expand
   moveptr(MagAxes,'init');
   
case 'acquire'    
   % Track mouse location
   CP = get(MagAxes,'CurrentPoint');
   CPX = unitconv(CP(1,1),Constr.xDisplayUnits,Constr.xUnits);
   CPY = unitconv(CP(1,2),Constr.yDisplayUnits,Constr.yUnits);
     
   %Prevent move beyond limits of neighbours
   [CPX,CPY] = localLimitResize(Constr,CPX,CPY,mve);
         
   % Calculate new slope of constraint line
   Slope = [ -(Xinit(sty) - CPX), -(Yinit(sty) - CPY)]; %Parameterize to avoid inf slope problems

   % Update the constraint X and Y data properties
   Xinit(mve) = CPX;
   Yinit(mve) = CPY;

   LocalUpDate(Constr,Xinit,Yinit);

   % Adjust axis limits if moved constraint gets out of focus
   % Issue MouseEdit event and attach updated extent of resized objects (for axes rescale)
   Extent = Constr.extent;
   MouseEditData.Data = ...
      struct('XExtent',Extent(1:2),'YExtent',Extent(3:4),'X',CP(1,1),'Y',CP(1,2));
   EventMgr.send('MouseEdit',MouseEditData)

   % Update status bar with gradient of constraint line
   LocStr = sprintf('Location:  from %0.3g to %0.3g',...
      Constr.xCoords(Constr.SelectedEdge,1),Constr.xCoords(Constr.SelectedEdge,2));
   SlopeStr = sprintf('Slope:  %0.3g rad',atan2(Slope(2),Slope(1)));
   EventMgr.poststatus(sprintf('%s\n%s',LocStr,SlopeStr));
   
case 'finish'
   % Clean up
   MouseEditData = [];
 
   % Update the constraint X and Y data properties
   Yinit(mve) = Yinit(sty) + Slope(2);
   LocalUpDate(Constr,Xinit,Yinit);
      
   % Update status
   EventMgr.newstatus(Constr.status('resize'));
   
end

%--------------------------------------------------------------------------
function LocalUpDate(Constr,Xinit,Yinit)
% Calculate and update the constraint X and Y data properties

%Set Y values, disable listeners.
set(Constr.Listeners,'Enable','off');
Constr.yCoords(Constr.SelectedEdge,:) = Yinit;
set(Constr.Listeners,'Enable','on');
%Set X values, fire listeners to update coordinates and redraw.
Constr.xCoords(Constr.SelectedEdge,:) = Xinit;

%--------------------------------------------------------------------------
function [CPX,CPY] = localLimitResize(Constr,CPX,CPY,mve)

%Copy coordinate to limit so that can use same code block
switch Constr.Orientation
   case 'horizontal'
      CPV = CPX;
      fldLimit = 'xCoords';
   case 'vertical'
      CPV = CPY;
      fldLimit = 'yCoords';
   case 'both'
      %Nothing to do
      return
end

%Perform the limit check
iElement = Constr.SelectedEdge;
minSize = eps;   %Percentage used to limit minimum constraint size.
switch mve
   case 1
      %Left end selected
      if size(Constr.xCoords,1)>1
         %Limit left extent to left end of next constraint
         if iElement > 1
            CPV = max(CPV,Constr.(fldLimit)(iElement-1,1)*...
               (1+minSize*sign(Constr.(fldLimit)(iElement-1,1))));
         end
      end
      %Limit right extent to right end
      CPV = min(CPV,Constr.(fldLimit)(iElement,2)*...
         (1-minSize*sign(Constr.(fldLimit)(iElement,2))));
   case 2
      %Right end selected
      if size(Constr.xCoords,1)>1
         %Limit right extent to right end of next constraint
         if iElement < size(Constr.xCoords,1)
            CPV = min(CPV,Constr.(fldLimit)(iElement+1,2)*...
               (1-minSize*sign(Constr.(fldLimit)(iElement+1,2))));
         end
      end
      %Limit left extent to left end
      CPV = max(CPV,Constr.(fldLimit)(iElement,1)*...
         (1+minSize*sign(Constr.(fldLimit)(iElement,1))));
end

%Limit correct return coordinate
switch Constr.Orientation
   case 'horizontal'
      CPX = CPV;
   case 'vertical'
      CPY = CPV;
end


