function dummy = update(Editor)
%UPDATE  Updates Root Locus Editor and regenerates plot.

%   Authors: P. Gahinet and K. Gondoly
%   Copyright 1986-2000 The MathWorks, Inc. 
%   $Revision: 1.19 $  $Date: 2000/08/02 16:06:37 $

% REVISIT
dummy = [];

if strcmp(Editor.EditMode,'off') | strcmp(Editor.Visible,'off')
    % Editor is inactive
    return
end

%%%%%%%%%%%%%%%%%%%%
% Update Locus Data
%%%%%%%%%%%%%%%%%%%%

% Get normalized open-loop and absolute value of compensator gain
NormOpenLoop = Editor.LoopData.OpenLoop;
GainMag = abs(getgain(Editor.LoopData));

% Compute root locus for normalized open-loop model and current closed-loop poles 
[Roots,Gains] = rlocus(NormOpenLoop);
CLpoles = fastrloc(NormOpenLoop,GainMag);

% Make sure the locus extends beyond the current CL poles, and that 
% the locus goes through the red squares
[NewGain,RefRoot] = extendlocus(Gains,Roots,GainMag);
if ~isempty(NewGain)
   % Extend locus
   NewRoot = matchlsq(RefRoot,fastrloc(NormOpenLoop,NewGain));
   Roots = [NewRoot,Roots];
   [Gains,is] = sort([NewGain,Gains]);
   Roots = Roots(:,is);
elseif length(Gains) & ~any(Gains==GainMag)
   % Insert current gain in locus data 
   idx = find(Gains>GainMag);
   Gains = [Gains(:,1:idx(1)-1) , GainMag , Gains(:,idx(1):end)];
   Roots = [Roots(:,1:idx(1)-1) , ...
         matchlsq(Roots(:,idx(1)-1),CLpoles) , Roots(:,idx(1):end)];
end

% Update locus data 
Editor.LocusRoots = Roots;
Editor.LocusGains = Gains;
Editor.ClosedPoles = CLpoles;  % triggers update of optimal X/Y lims


%%%%%%%%%%%%%%%%%%%%
% Render Locus Data
%%%%%%%%%%%%%%%%%%%%
LoopData = Editor.LoopData;
HG = Editor.HG;
PlotAxes = HG.PlotAxes;
Style = Editor.LineStyle;
UIC = get(PlotAxes,'uicontextmenu'); % axis ctx menu

%---Clear existing plot 
DeleteH = get(PlotAxes,'children');
delete(DeleteH(ishandle(DeleteH)))

%---Plot X and Y axis lines
XaxisLine = line([-1 1],[0 0],'Color',Editor.AxesForegroundColor,...
    'LineStyle',':','Parent',PlotAxes,'HitTest','off');
YaxisLine = line([0 0],[-1 1],'Color',Editor.AxesForegroundColor,...
    'LineStyle',':','Parent',PlotAxes,'HitTest','off');
HG.AxisLines = [XaxisLine;YaxisLine];

%---Plot the fixed poles and zeros (plant+sensor)
% REVISIT
out = fixedpz(LoopData);
[FixedZeros,FixedPoles] = deal(out{:});
HG.System = struct('Zero',zeros(size(FixedZeros)),'Pole',zeros(size(FixedPoles)));
for ct=1:length(FixedZeros)
   HG.System.Zero(ct) = line(real(FixedZeros(ct)),imag(FixedZeros(ct)),...
      'LineStyle','none','Marker','o','MarkerSize',5,'Color',Style.Color.System,...
      'Parent',PlotAxes,'UIContextMenu',UIC,...
      'ButtonDownFcn',{@LocalShowData Editor},...
      'HelpTopicKey','sisosystempolezero');
end % for ct
for ct=1:length(FixedPoles),
   HG.System.Pole(ct) = line(real(FixedPoles(ct)),imag(FixedPoles(ct)),...
      'LineStyle','none','Marker','x','MarkerSize',6,'Color',Style.Color.System,...
      'Parent',PlotAxes,'UIContextMenu',UIC,...
      'ButtonDownFcn',{@LocalShowData Editor},...
      'HelpTopicKey','sisosystempolezero');
end % for ct

%---Plot the root locus
if ~isempty(Gains)
    HG.Locus = line(real(Roots.'),imag(Roots.'),...
        'Parent',PlotAxes, ...
        'UIContextMenu',UIC,...
        'ButtonDownFcn',{@LocalSelectGain Editor},...
        'HelpTopicKey','sisorootlocusplot',...
        'Color',Style.Color.Response); 
    
    %---Plot the movable closed-loop poles
    HG.ClosedLoop = zeros(size(CLpoles));
    for ct=1:length(CLpoles),
        HG.ClosedLoop(ct,1) = ...
            line(real(CLpoles(ct)),imag(CLpoles(ct)),...
            'Parent',PlotAxes, ...
            'LineStyle','none',...
            'Marker',Style.Marker.ClosedLoop,...
            'MarkerSize',5,...
            'MarkerFaceColor',Style.Color.ClosedLoop, ...
            'MarkerEdgeColor',Style.Color.ClosedLoop,...
            'MarkerFaceColor',Style.Color.ClosedLoop,...
            'HelpTopicKey','closedlooppoles',...
            'ButtonDownFcn',{@LocalMoveGain Editor});  
    end 
else
    HG.Locus = zeros(0,1);
    HG.ClosedLoop = zeros(0,1);
end

% Update HG database
Editor.HG = HG;

%---Plot the compensator poles and zeros
plotcomp(Editor);

% Update axis limits
% RE: Includes line handle restacking for proper layering
optlims(Editor);  % update "optimal" limits
updatelims(Editor);


%-------------------------Callback Functions-------------------------

%%%%%%%%%%%%%%%%%%%%%%%
%%% LocalSelectGain %%%
%%%%%%%%%%%%%%%%%%%%%%%
function LocalSelectGain(hLine,event,Editor)
% Update gain by clicking on the locus
if strcmp(get(gcbf,'SelectionType'),'normal')
    selectgain(Editor);
end


%%%%%%%%%%%%%%%%%%%%%
%%% LocalShowData %%%
%%%%%%%%%%%%%%%%%%%%%
function LocalShowData(hSrc,event,Editor)
% Show system data
send(Editor.up,'ShowData');  % notify parent of open request


%%%%%%%%%%%%%%%%%%%%%
%%% LocalMoveGain %%%
%%%%%%%%%%%%%%%%%%%%%
function LocalMoveGain(hSrc,event,Editor)
% Callback for button down on closed-loop poles

SISOfig = gcbf;
if strcmp(Editor.EditMode,'idle')  
    switch get(SISOfig,'SelectionType')
    case 'open'
        % Double click: open info box for closed-loop pole
        % REVISIT: do it??
    case 'normal'
        % Left click: initialize dragging of closed-loop pole
        % Switch edit mode to drag
        Editor.ModeData = 'gain';
        Editor.EditMode = 'drag';
        % Change pointer
        setptr(SISOfig,'closedhand')
        % Initialize tracking algorithm and notify peers
        Status = trackgain(Editor,'init');
		hgset_status(Editor,Status);
    end
end
