function changeZPK(Hand, pt, handles)
% changeZPK
%   change zero/pole/gain

%   Project: IMPACT
%   Title of Code: changeZPK
%   Relevant additional documentation:
%   Developer: Carlos Gonzalez
%   External Dependencies: NA
%
%   Disclaimer
%   CAUTION: It is strongly recommended that changes to this code
%   should be avoided without first consulting with authors.

% drag zero, pole/gain for plot
% specifically for mouse motion update

w = handles.Data.w;

% 
pt(1) = min(w(end), pt(1));
pt(1) = max(w(1), pt(1));

z = Hand.z;
p = Hand.p;
k = Hand.k;
ind = Hand.zpkInd;
switch Hand.zpk
    case 'rz' % real zero
        if z(ind) > 0 
            z(ind) = pt(1);
        else
            z(ind) = -pt(1);
        end
    case 'rp' % real pole
        if p(ind) > 0
            p(ind) = pt(1);
        else
            p(ind) = -pt(1);
        end
    case 'k' % change gain
        if strcmpi(get(handles.hUimenu.CrossF.freeze, 'Checked'), 'on')
            return;
        end
        valX = handles.Data.w;
        valY = get(handles.hMag(2), 'YData');
        valPrev = interp1(valX, valY, pt(1));
        val = pt(2) - valPrev;
        %         val = pt(2) - Hand.prevPoint(2);
        %
        % limit the value of k
        k = k*10^(val/20);
        
    case 'cz'% complex zero
        zero1 = z(ind(1));
        rpart = real(zero1);

        % vertical direction
        % z2 = z1*(10^((y2-y1)/20))
        rpartNew = rpart*(10^((pt(2) - Hand.prevPoint(2))/20));
        ipartNew = sqrt((abs(zero1))^2 - rpartNew^2);
        if ~isreal(ipartNew) % higher than ipartNew = 0;
            if rpartNew > 0
                rpartNew = abs(zero1);
            else
                rpartNew = -abs(zero1);
            end
            ipartNew =1e-4;
        end
        % horizontal direction
        rpartNew = pt(1)/Hand.prevPoint(1)*rpartNew;
        ipartNew = pt(1)/Hand.prevPoint(1)*ipartNew;

        z(ind(1)) = complex(rpartNew, ipartNew);
        z(ind(1)+1) = conj(z(ind(1)));
    case 'cp'% complex pole
        pole1 = p(ind(1));
        rpart = real(pole1);
        
        % vertical direction
        % r2 = r1/(10^((y2-y1)/20))
        rpartNew = rpart/(10^((pt(2) - Hand.prevPoint(2))/20));
        ipartNew = sqrt((abs(pole1))^2 - rpartNew^2);
        if ~isreal(ipartNew) % lower than ipartNew = 0;
            if rpartNew > 0
                rpartNew = abs(pole1);
            else
                rpartNew = -abs(pole1);
            end
            ipartNew =1e-4;
        end
        % horizontal direction
        rpartNew = pt(1)/Hand.prevPoint(1)*rpartNew;
        ipartNew = pt(1)/Hand.prevPoint(1)*ipartNew;
        
        p(ind(1)) = complex(rpartNew, ipartNew);
        p(ind(1)+1) = conj(p(ind(1)));
end
Hand.z = z;
Hand.p = p;
Hand.k = k;
Hand.prevPoint = pt;
handles.Tb.Hand = Hand;

C = zpk(z, p, k);
handles.C = C;

guidata(handles.hFig, handles);
updatePlot(handles);