function dummy = addpz(Editor)
%ADDPZ  Adds pole or zero graphically.

%   Author(s): P. Gahinet
%   Copyright 1986-2000 The MathWorks, Inc. 
%   $Revision: 1.8 $  $Date: 2000/06/14 20:21:48 $

% REVISIT
dummy = [];

% Pointers
HG = Editor.HG;
CompData = Editor.LoopData.Compensator;

% Gather info about added root
AddType =  Editor.ModeData;  % {Type,ID}

% Acquire new pole/zero position 
% RE: Adjust position based on pole/zero type
CP = get(HG.PlotAxes,'CurrentPoint');
[Zeros,Poles,Type,Status,Action] = ...
    LocalGetRootValue(CP(1,1),CP(1,2),AddType{:},CompData.Ts);
   
% Start transaction
T = handle.transaction(get(findpackage('sisodata'),'DefaultDatabase'));
set(T,'Name',Action,'OperationStore','on','InverseOperationStore','on');

% Add new pole/zero group to compensator
addpz(CompData,Type,Zeros,Poles);

% Register transaction 
register(Editor.LoopData,T);

% Notify peers of data change
dataevent(Editor.LoopData,'all');

% Confirm operation in status bar and update history
Editor.up.send('StatusChanged',...
    sisodata.dataevent(Editor.up,'StatusChanged',{Status,Status}));


%----------------- Local functions -----------------

%%%%%%%%%%%%%%%%%%%%%
% LocalGetRootValue %
%%%%%%%%%%%%%%%%%%%%%
function [Zeros,Poles,Type,Status,Action] = LocalGetRootValue(X,Y,Type,ID,Ts)
% Infers specified root value from mouse location

if Ts
    DomainVar = 'z';
else
    DomainVar = 's';
end

switch Type
case 'Real'
    % Real pole/zero
    if strcmpi(ID,'Zero')
        Zeros = X;  Poles = zeros(0,1);
    else
        Poles = X;  Zeros = zeros(0,1);
    end
    Status = sprintf('Added real compensator %s at %s = %.3g',lower(ID),DomainVar,X);
    Action = sprintf('Add %s',ID);
    
case 'Complex'
    % Complex pole/zero
    Y = abs(Y);
    if strcmpi(ID,'Zero')
        Zeros = [X + i*Y ; X - i*Y];  Poles = zeros(0,1);
    else
        Poles = [X + i*Y ; X - i*Y];  Zeros = zeros(0,1);
    end
    Status = sprintf('Added complex pair of compensator %ss at %s = %.3g %s %.3gi',lower(ID),DomainVar,X,char(177),Y);
    Action = sprintf('Add %s',ID);
    
case {'Lead','Lag'}
    % Lead or lag network (s+tau1)/(s+tau2) 
    % Compute factor F such that the frequencies of the added pole and
    % its companion are Wn and F*Wn
    F = 1.5^(-1+2*strcmpi(Type,'Lag'));
    
    % Enforce stability and separate pair to facilitate adjustments
    if Ts
        % Natural frequency constrained to [1e-3,pi/Ts]
        wmin = 1.01 * exp(-pi);
        wmax = exp(-0.001*Ts);
        X = max(wmin,min(X,wmax));
        Poles = X;   Zeros = max(wmin,X^F);
    else
        X = min(X,-0.001);
        Poles = X;   Zeros = F*X;
    end
    Status = sprintf('Added %s network with zero at %s = %.3g and pole at %s = %.3g',...
        lower(Type),DomainVar,Zeros,DomainVar,Poles);
    Action = sprintf('Add %s',Type);
    
    % Set @pzgroup type
    Type = 'LeadLag';
    
case 'Notch'
    % Notch filter. Mouse position is the pole position. Place the zero to 
    % achieve 20 dB drop
    r2 = X + i * abs(Y);      % pole position
    [Wn,Z2] = damp(r2,Ts);    % corresponding damping and natural freq
    Z1 = 0.1 * Z2;            % zero damping
    if Ts
        r1 = exp(Ts * Wn * (-Z1 + 1i * sqrt(1-Z1^2)));
    else
        r1 = Wn * (-Z1 + 1i * sqrt(1-Z1^2));
    end
    Zeros = [r1;conj(r1)];
    Poles = [r2;conj(r2)];
    
    Status = sprintf('Added notch filter with zeros at %s = %.3g %s %.3gi and poles at %s = %.3g %s %.3gi',...
        DomainVar,real(r1),char(177),abs(imag(r1)),DomainVar,real(r2),char(177),abs(imag(r2)));
    Action = 'Add Notch';
end
