function Status = trackgain(Editor,action)
%TRACKGAIN  Keeps track of gain value while dragging closed-loop pole.
%
%   See also SISOTOOL

%   Author(s): P. Gahinet
%   Copyright 1986-2000 The MathWorks, Inc. 
%   $Revision: 1.16 $  $Date: 2000/08/15 20:14:58 $

persistent CurrentGdB FreqData TransAction
persistent AutoScaleOn MagRange FreqLims MagLims 

HG = Editor.HG;
MagAx = HG.PlotAxes(1);

% Process ACTION
switch action 
    
case 'init'
    % Initialize persistent
    CurrentGdB = 20*log10(abs(getgain(Editor.LoopData)));  % current gain in dB
    FreqData = unitconv(Editor.Frequency,'rad/sec',Editor.FrequencyUnits);
    
    % Initialize parameters used to adjust mag limits
    AutoScaleOn = strcmp(Editor.YlimMode{1},'auto');
    if AutoScaleOn
        FreqLims = get(MagAx,'Xlim');
        MagLims = get(MagAx,'Ylim');   % mag limits
        % Initialize pointer motion control
        relocptr('init',MagAx)
        % Interval of normalized mag values (in dB)
        MagRange = 20*log10(yextent(Editor,'mag'));
    end
    
    % Broadcast MOVEGAIN:init event
    % RE: Sets RefreshMode='quick' and attaches listener to Gain data changes
    Editor.up.send('MoveGain',sisodata.dataevent(Editor.up,'MoveGain','init'));
    Status = 'Drag the magnitude curve up or down to change the loop gain.';
    
    % Start transaction
    TransAction = handle.transaction(get(findpackage('sisodata'),'DefaultDatabase'));
    set(TransAction,'Name','Edit Gain','OperationStore','on',...
        'InverseOperationStore','on','Compression','on');
    
case 'acquire'
    % Acquire new gain value during drag.
    % RE: Restrict X position to be in freq. data range 
    CP = get(MagAx,'CurrentPoint');
    X = max(FreqData(1),min(CP(1,1),FreqData(end)));
    Y = CP(1,2);
    
    % Get new gain value (interpolate in plot units to limit distorsions)
    NewGain = unitconv(Y,Editor.MagnitudeUnits,'abs') / ...
        interpmag(Editor,FreqData,Editor.Magnitude,X);
    NewGdB = 20*log10(NewGain);
    
    % Update loop data (triggers plot update)
    % REVISIT: merge
    GainData = Editor.LoopData.Compensator.Gain; 
    GainData.Magnitude = NewGain;
    Editor.LoopData.Compensator.Gain = GainData;
    
    % Adjust Y limits if hand moves outside current limits
    if AutoScaleOn
        % Check mag. axis limits
        % REVISIT
        out = shiftlims(Editor,MagLims,MagRange+NewGdB,NewGdB-CurrentGdB);
        [MagLims,MovePtr] = deal(out{:});
        if MovePtr
            % Adjust pointer position when mag limits are changed
            relocptr('move',X,Y,[FreqLims,MagLims])
        end
    end
    
    % Update status and current comp. gain
    Status = 'Drag the magnitude curve up or down to change the loop gain.';
    CurrentGdB = NewGdB;
    
case 'finish'
    % Button up event.   
    Status = '';  % ignored
    
    % Commit and stack transaction
	register(Editor.LoopData,TransAction);
    TransAction = [];   % release persistent objects

    % Broadcast MOVEGAIN:finish event (exit RefreshMode=quick,...) 
    Editor.up.send('MoveGain',...
        sisodata.dataevent(Editor.up,'MoveGain','finish'));
    
    % Update status and command history
    Str = sprintf('Loop gain changed to %0.3g',getgain(Editor.LoopData));
    Editor.up.send('StatusChanged',...
        sisodata.dataevent(Editor.up,'StatusChanged',...
        {sprintf('%s\nRight-click on plots for more design options.',Str),Str}));
    
    % Trigger global update
    dataevent(Editor.LoopData,'gain');
    
end

