function update_plot(hFig)
%UPDATE_PLOT Update plot area for quantized filters.
%   UPDATE_PLOT(hFig) where hFig is the figure handle updates the
%   plots for FDATOOL.

%   Thomas A. Bryan, 12 November 1999
%   Copyright 1988-2000 The MathWorks, Inc.
%   $Revision: 1.33 $  $Date: 2000/07/18 18:14:30 $

wrn = warning('off');
ud = get(hFig,'userdata');

setPlotParams(hFig);
currentmode = ud.mode.current;

% The user data might have been modified by quantizeapply
ud = get(hFig,'userdata');
G = ud.filter;
% Autocorrect for wrong length scale values
G = scalevaluefixup(G);

try
  [fun,ax,filtcoeff_eb,xunits,yunits,xlbl,fs] = init(hFig);
  % Is this a quantize plot?
  isqnt = ud.flags.quantizationswitch & isa(G,'qfilt');
  
  switch fun
    case 'filtercoeffs'
      filtercoeffs(G,ax,hFig,filtcoeff_eb);
      
    case 'filterresponsespecs'
      % Static filter response specs.
      filterresponsespecs(hFig);
      
    case {'magnphaseresp','groupdelay'}
      update_status(hFig,'Computing filter response...');
      feval(fun,G,ax,xunits,yunits,fs,isqnt,xlbl);
      
    otherwise
      update_status(hFig,'Computing filter response...');
      feval(fun,G,ax,xunits,yunits,fs,isqnt);
  end
  warning(wrn)
  
  update_status(hFig,'Ready');
catch
  fdatoolerror(hFig);
  return;
end

%----------------------------------------------------------------------
function [fun,ax,filtcoeff_eb,xunits,yunits,xlbl,fs] = init(hFig)
ud = get(hFig,'userdata');
fun = ud.toolbar.analysis;
ax = ud.h.analysis.ax;
axes(ax(1));
axes(ax(2));
filtcoeff_eb = ud.h.analysis.filtcoeff_eb; % Handle of filter coefficient
                                           % edit box.
yunits = ud.plot.magUnits;
if strcmpi(yunits,'weights')
  yunits = 'db';
end
xunits = lower(ud.plot.freqUnits);


switch xunits
  case 'hz'
    xlbl = 'Frequency (Hz)';
    fs = evaluatefs(ud.plot.Fs);
case 'khz'
    xlbl = 'Frequency (kHz)';
    fs = evaluatefs(ud.plot.Fs);
  case 'mhz'
    xlbl = 'Frequency (MHz)';
    fs = evaluatefs(ud.plot.Fs);
  case 'ghz'
    xlbl = 'Frequency (GHz)';
    fs = evaluatefs(ud.plot.Fs);
  case 'normalized (0 to 1)'
    xlbl = 'Normalized Frequency (\times\pi rad/sample)';
    xunits = 'rad/sample';
    fs = [];
end

%-------------------------------------------------------------------------
function filterresponsespecs(hFig)
%FILTERRESPONSESPECS Filter response specs.
%   FILTERRESPONSESPECS(hFig) plots the filter response specifications, where
%   hFig is the handle to the filter design gui.

% Extract info from userdata structure.
ud = get(hFig,'Userdata');
hax = ud.h.analysis.ax(1);

filterType = ud.specs.design.type;
method = ud.specs.design.method;


switch filterType,
case {'lp','hp','bp','bs'},
    
    frame = 'freq';
    ismagframe = 1; % Magnitude specs. frame is present
    
otherwise
    
    frame = 'freqmag';
    ismagframe = 0; % Magnitude specs. frame is NOT present
    
end


% Get Frequency specifications.
freq_vals = get_specvals(hFig,frame);
xunits = freq_vals.units;

if ismagframe,
    % Get Magnitude specifications.
    mag_vals = get_specvals(hFig,'mag');
    yunits = mag_vals.units;
    
else
    yunits = 'linear';
end


set(hax,'Visible','On');
staticresp(hax,filterType,method,yunits,xunits);

%----------------------------------------------------------------------
function magresp(G,ax,xunits,yunits,fs,isqnt)
%MAGRESP Magnitude response.
%   MAGRESP(G,AX,XUNITS,YUNITS,FS,ISQNT) plots the magnitude of the frequency
%   response, where G is a filter object (either QFILT or DFILT), AX is a
%   vector of handles to the axes to plot in, XUNITS is the x-axis units,
%   YUNITS is the y-axis units, FS is the sampling frequency, and ISQNT
%   indicates whether to plot a quantized plot.
N = 512;
[H,W,S,Hr] = localfreqz(G,N,fs);
if isqnt
  drawanalysisplot('magresp',ax,W,[Hr(:),H(:)],S,xunits,yunits);
  if ~isempty(ax(1))
    legend(ax(1),'Reference','Quantized',0)
  end
else
  drawanalysisplot('magresp',ax,W,Hr(:),S,xunits,yunits);
end

%----------------------------------------------------------------------
function phaseresp(G,ax,xunits,yunits,fs,isqnt)
%PHASERESP Phase response.
%   PHASERESP(G,AX,XUNITS,YUNITS,FS,ISQNT) plots the phase of the frequency
%   response, where G is a filter object (either QFILT or DFILT), AX is a vector
%   of handles to the axes to plot in, XUNITS is the x-axis units, YUNITS is the
%   y-axis units, FS is the sampling frequency, and ISQNT indicates whether to
%   plot a quantized plot.
N = 512;
[H,W,S,Hr] = localfreqz(G,N,fs);
if isqnt
  drawanalysisplot('phaseresp',ax,W,[Hr(:),H(:)],S,xunits,yunits);
  if ~isempty(ax(1))
    legend(ax(1),'Reference','Quantized',0)
  end
else
  drawanalysisplot('phaseresp',ax,W,Hr(:),S,xunits,yunits);
end

%----------------------------------------------------------------------
function magnphaseresp(G,ax,xunits,yunits,fs,isqnt,xlbl)
%MAGNPHASERESP  Magnitude and phase response.
%   MAGNPHASERESP(G,AX,XUNITS,YUNITS,FS,ISQNT,XLBL) plots the phase of the frequency
%   response, where G is a filter object (either QFILT or DFILT), AX is a vector
%   of handles to the axes to plot in, XUNITS is the x-axis units, YUNITS is the
%   y-axis units, FS is the sampling frequency, ISQNT indicates whether to
%   plot a quantized plot, and XLBL is the text of the x-axis label.
N = 512;
[H,W,S,Hr] = localfreqz(G,N,fs);
if isqnt
  hline = drawanalysisplot('magnphaseresp',ax,W,[Hr(:),H(:)],...
      S,xunits,yunits,xlbl);
  if ~isempty(hline)
    legend(hline,'Reference magnitude','Quantized magnitude',...
        'Reference phase','Quantized phase');
  end
else
  drawanalysisplot('magnphaseresp',ax,W,Hr(:),S,xunits,yunits,xlbl);
end

%----------------------------------------------------------------------
function groupdelay(G,ax,xunits,yunits,fs,isqnt,xlbl)
%GROUPDELAY Group delay.
%   GROUPDELAY(G,AX,XUNITS,YUNITS,FS,ISQNT) plots the filter group delay, where G
%   is a filter object (either QFILT or DFILT), AX is a vector of handles to the
%   axes to plot in, XUNITS is the x-axis units, YUNITS is the y-axis units, FS
%   is the sampling frequency, and ISQNT indicates whether to plot a quantized
%   plot.
wrn = warning('off');
N = 512;
if isa(G,'qfilt')
  [bq,aq,br,ar] = qfilt2tf(G);
  if isempty(fs)
    % Normalized frequency
    [Gdq,W] = grpdelay(bq,aq,N);
    [Gdr,W] = grpdelay(br,ar,N);
    W=W/W(end);
  else
    [Gdq,W] = grpdelay(bq,aq,N,fs);
    [Gdr,W] = grpdelay(br,ar,N,fs);
  end    
else
  if isempty(fs)
    % Normalized frequency
    [Gdr,W] = grpdelay(G,N);
    W=W/W(end);
  else
    [Gdr,W] = grpdelay(G,N,fs);
  end    
end
if isqnt
  hline = drawanalysisplot('groupdelay',ax,W,[Gdr(:),Gdq(:)],xlbl);
  if ~isempty(hline)
    legend(hline,'Reference','Quantized',0);
  end
else
  drawanalysisplot('groupdelay',ax,W,Gdr(:),xlbl);
end
lastwarn('');
warning(wrn)
%----------------------------------------------------------------------
function impresp(G,ax,xunits,yunits,fs,isqnt)
%IMPRESP Impulse response.
%   IMPRESP(G,AX,XUNITS,YUNITS,FS,ISQNT) plots the filter impulse response, where
%   G is a filter object (either QFILT or DFILT), AX is a vector of handles to
%   the axes to plot in, XUNITS is the x-axis units, YUNITS is the y-axis units,
%   FS is the sampling frequency, and ISQNT indicates whether to plot a quantized
%   plot.
if isa(G,'qfilt')
  [yq,t,yr] = impz(G);
else
  [yr,t] = impz(G);
end
if isqnt
  hline = drawanalysisplot('impresp',ax,t,[yr(:), yq(:)],xunits);
  if ~isempty(hline)
    legend(hline,'Reference','Quantized',0)
  end
else
  drawanalysisplot('impresp',ax,t,yr(:),xunits);
end
%----------------------------------------------------------------------
function stepresp(G,ax,xunits,yunits,fs,isqnt)
%STEPRESP Step response.
%   STEPRESP(G,AX,XUNITS,YUNITS,FS,ISQNT) plots the filter step response, where G
%   is a filter object (either QFILT or DFILT), AX is a vector of handles to the
%   axes to plot in, XUNITS is the x-axis units, YUNITS is the y-axis units, FS
%   is the sampling frequency, and ISQNT indicates whether to plot a quantized
%   plot.
N=100;
if isa(G,'qfilt')
  t=0:N-1;
  x=.25*ones(N,1);
  yq = filter(G,x);
  Hqr = G;
  Hqr = set(Hqr,'mode','double');
  yr = filter(Hqr,x);
else
  [yr,t] = stepz(G,N);
end
if isqnt
  hline = drawanalysisplot('stepresp',ax,t,[yr(:), yq(:)],xunits);
  if ~isempty(hline)
    legend(hline,'Reference','Quantized',0)
  end
else
  drawanalysisplot('stepresp',ax,t,yr(:),xunits);
end
if isa(G,'qfilt')
  set(get(ax(1),'ylabel'),'string',...
      ['Step height = ',num2str(x(1))]);
end

%----------------------------------------------------------------------
function pzplot(G,ax,xunits,yunits,fs,isqnt)
%PZPLOT Pole-zero plot.
%   PZPLOT(G,AX,XUNITS,YUNITS,FS,ISQNT) plots the poles and zeros, where G
%   is a filter object (either QFILT or DFILT), AX is a vector of handles to the
%   axes to plot in, XUNITS is the x-axis units, YUNITS is the y-axis units, FS
%   is the sampling frequency, and ISQNT indicates whether to plot a quantized
%   plot.
if isa(G,'qfilt')
  [Zq,Pq,Kq,Zr,Pr,Kr]=zplane(G);
  if iscell(Zq)
    Zq = cat(1,Zq{:});
    Pq = cat(1,Pq{:});
    Kq = cat(1,Kq{:});
    Zr = cat(1,Zr{:});
    Pr = cat(1,Pr{:});
    Kr = cat(1,Kr{:});
  end
else
  [Zr,Pr,Kr] = zpk(G);
end
if isqnt
  hline = drawanalysisplot(...
      'pzplot',ax,Zr,'o','k',Pr,'x','k',Zq,'s','r',Pq,'+','r');
  if ~isempty(hline)
    legend(hline,'Reference zeros','Reference poles',...
        'Quantized zeros','Quantized poles');
  end
else
  drawanalysisplot('pzplot',ax,Zr,'o','k',Pr,'x','k')
end
%----------------------------------------------------------------------
function filtercoeffs(G,ax,hFig,filtcoeff_eb)
%FILTERCOEFFS Filter coefficients.
%   FILTERCOEFFS(G,AX,HFIG,FILTCOEFF_EB) plots the poles and zeros, where G is a
%   filter object (either QFILT or DFILT), AX is a vector of handles to the axes
%   to plot in, HFIG is the handle to the callback figure, and FILTCOEFF_EB is
%   the handle to the edit box to display the coefficients in.

set(ax,'visible','off');

% Get the value of the selected listbox item
val = get(filtcoeff_eb,'Value');
m = size(dispstr(G),1);

% Select the first item in the listbox if previous list item had more rows
if m < val,
	val = 1;
end

set(filtcoeff_eb,'Visible','On','String',dispstr(G),'Value',val);


%-------------------------------------------------------------------
%                       Utility Functions
%-------------------------------------------------------------------
function setPlotParams(hFig)
% SETPLOTPARAMS Set plotting parameters based on which mode created 
%              the filter.
%
% This function determines which mode(state) created the filter
% and sets the ud.plot leg with the appropriate Sampling 
% Frequency Fs, Magnitude Units, and Frequency Units.
%
%  Input:
%    hFig   - Handle to the Filter Designer GUI 

ud = get(hFig,'UserData');

% Indicates which mode created the filter; the choices are
% 1 - Design  
% 2 - Specify (import)  

switch ud.mode.filtermadeby
case 1,
    filterType = ud.specs.design.type;
    
    switch filterType,
    case {'lp','hp','bp','bs'},
        
        frame = 'freq';
        ismagframe = 1; % Magnitude specs. frame is present
        
    otherwise
        
        frame = 'freqmag';
        ismagframe = 0; % Magnitude specs. frame is NOT present
        
    end
    % Sampling Frequency
    ud.plot.Fs = getfield(ud.specs.design,frame,filterType,'fs'); 
    
    % Frequency Units
    ud.plot.freqUnits = getfield(ud.specs.design,frame,filterType,'units');
    
    if ismagframe,
        % Magnitude Units
        ud.plot.magUnits = getfield(ud.specs.design.mag,filterType,'units');
    else
        ud.plot.magUnits = 'db';
    end
        
case 2,
    ud.plot.Fs = ud.specs.import.fs.Fs;
    ud.plot.freqUnits = ud.specs.import.fs.freqUnits;
    
    % Magnitude Units: This is currently hard-coded as we do not yet
    % allow users to select the Magnitude Units
    ud.plot.magUnits = 'db';
end

set(hFig,'UserData',ud);


%-------------------------------------------------------------------
function [H,W,S,Hr] = localfreqz(G,N,fs)
%LOCALFREQZ Local frequency response function.
%   [H,W,S,Hr] = LOCALFREQZ(G,N,Fs) computes the frequency response for DFILT
%   or QFILT object G with N frequency points and sampling frequency Fs.  If
%   Fs is empty, then normalized units are used.  H is the quantized
%   response, W is the frequency vector, S is the structure for FREQZPLOT,
%   and Hr is the double-precision response.
if isa(G,'qfilt')
  if isempty(fs)
    [H,W,S,Hr] = freqz(G,N);
  else
    [H,W,S,Hr] = freqz(G,N,fs);
  end
else  
  H = [];
  if isempty(fs)
    [Hr,W,S] = freqz(G,N);
  else
    [Hr,W,S] = freqz(G,N,fs);
  end    
end

% [EOF] update_plot.m

