function update_specs(fcn,hFig,varargin)
%UPDATE_SPECS   Updates the freq. and mag. specs. frames.
%
%   Inputs:
%     fcn  - string to be fevaled. This will indicate what main local
%            function to call within this function. The main local
%            functions are:
%            update_freqFrame - updates the entire freq. specs frame.
%            update_magFrame  - updates the entire mag. specs frame.
%            update_freqlbls  - updates the freq. specs frame labels.
%            update_maglbls   - updates the mag. specs frame labels.
%    hFig  - handle to the GUI's figure.
%    varargin - optional input arguments that are used when calling
%               update_freqlbls and update_maglbls.

%   Author(s): R. Losada
%   Copyright 1988-2000 The MathWorks, Inc.
%   $Revision: 1.20 $  $Date: 2000/06/13 21:41:02 $ 

feval(fcn,hFig,varargin{:});

%-------------------------------------------------------------------------
function update_all(hFig);
% UPDATE_ALL Calls the appropriate update functions to update the design params
%            area.

% Get userdata from figure
ud = get(hFig,'userdata');


% Read type from ud
filterType = ud.specs.design.type;

switch filterType,
case {'lp','hp','bp','bs'},
    
    update_freqFrame(hFig);  % Update freq. specs. frame.
    update_magFrame(hFig); % Update the magnitude specs. frame.
    
case {'diff','hilb','multiband','arbitrarymag','sincx','arbitrarygrp'},
    
    update_freqmagFrame(hFig); % Update the freqmag (freq. amplitude and weights) frame.
end

%-----------------------------------------------------------------------
%   **************       Main  Local Functions    ********************
%-----------------------------------------------------------------------
function update_freqFrame(hFig)
%UPDATE_FREQFRAME   Updates the entire frequency specs. frame.
%

% Turn off the visibility of all uicontrols in the freqmag 
% (freq. amplitude and weights) frame.
set_visibility(hFig,'freqmag','off');

% Turn on the visibility of all uicontrols in the freq. specs frame.
set_visibility(hFig,'freq','on');

% Get values of units, fs and freq. specs from ud
vals = get_specvals(hFig,'freq');

% Set freq popup string with units in ud
set_freqPopup(hFig,'freq',vals.units);

% Set fs edit box with value in ud
set_fsval(hFig,'freq',vals.fs);

% Set values and visibility of the other edit boxes
set_ebvalsNvis(hFig,'freq',vals.data); 

% Set values and visibility of labels of the edit boxes
set_lblvalsnvis(hFig,'freq');

% Update the labels to freq. specs. edit boxes 
update_freqlbls(hFig,vals.units);

drawnow; % Flush HG buffer.

%-----------------------------------------------------------------------
function update_magFrame(hFig)
%UPDATE_MAGFRAME   Updates the entire magnitude specs. frame.

% Turn on the visibility of all uicontrols in the mag. specs frame.
set_visibility(hFig,'mag','on');

% Set mag popup with units in ud
set_magPopup(hFig);

% Get values of units and mag. specs from ud
vals = get_specvals(hFig,'mag');

% Set values and visibility of the edit boxes
set_ebvalsNvis(hFig,'mag',vals.data); 

% Set values and visibility of labels of the edit boxes
set_lblvalsnvis(hFig,'mag');

% Update the labels to mag. specs. edit boxes 
update_maglbls(hFig,vals.units);

drawnow; % Flush HG buffer.

%----------------------------------------------------------------------
function update_freqmagFrame(hFig)
%UPDATE_FREQMAGFRAME   Updates the entire freqmag (freq. amplitude and weigths)
% frame.


% Turn off the visibility of all uicontrols in the freq and mag frames
set_visibility(hFig,'freq','off');
set_visibility(hFig,'mag','off');

% Turn on the visibility of all uicontrols in the freqmag specs frame.
set_visibility(hFig,'freqmag','on');

% Get values of units, fs and freq. specs from ud
vals = get_specvals(hFig,'freqmag');

% Set freq popup string with units in ud
set_freqPopup(hFig,'freqmag',vals.units);

% Set fs edit box with value in ud
set_fsval(hFig,'freqmag',vals.fs);

% Set values and visibility of the other edit boxes
set_ebvalsNvis(hFig,'freqmag',vals.data); 

% Set values and visibility of labels of the edit boxes
set_lblvalsnvis(hFig,'freqmag');

% Update the fs edit box and label
update_fs(hFig,vals.units,'freqmag');

%---------------------------------------------------------------------------
%   **************    Utility Local Functions       ********************
%---------------------------------------------------------------------------

function set_visibility(hFig,frame,vis_str)
%SET_VISIBILITY  Turn visibility on or off for all uicontrols in the
%                 freq. specs. frame.
%
%  frame - string indicating which frame to work on:
%          'freq', 'mag' or 'freqmag'.
%  vis_str - string indicating whether to turn visbility 'on' or 'off'.

% Get the user data stored in the figure
ud = get(hFig,'Userdata');

% Get structure of handles
h = getfield(ud.h.design_params.specs,frame);

% Convert structure to cell array
c = struct2cell(h);

% Convert the cell array to a vector
c = [c{:}];

% Set visibility
set(c,'visible',vis_str);
%---------------------------------------------------------------------------
function set_freqPopup(hFig,frame,freq_units)
% Set freq units popup string with units in ud.
%Local to update_freqFrame
%   Inputs:
%     frame       - frame where popup lives in ('freq' or 'freqmag')
%     freq_units  - string with new units from popup

% Get the user data stored in the figure
ud = get(hFig,'Userdata');

% Cache handle to the popup
h_freqUnitsPop = getfield(ud.h.design_params.specs,frame,'popup');

% Get list of possible units
freqUnitStrs = get(h_freqUnitsPop,'String');
  
% Get the index of the new units
indx = strmatch(freq_units,lower(freqUnitStrs));

% Set new_units in popup
set(h_freqUnitsPop,'Value',indx);

%---------------------------------------------------------------------------
function set_fsval(hFig,frame,fs)
%SET_FSVAL  Set fs edit box with value in ud.

% Get the user data stored in the figure
ud = get(hFig,'Userdata');

% Get handle to the edit box
h_fseb = getfield(ud.h.design_params.specs,frame,'fs_eb');

% Set value for Fs
set(h_fseb,'string',fs);

%---------------------------------------------------------------------------
function set_magPopup(hFig)
%SET_MAGPOPUP   Set the string in the popup for the units in the
%               magnitude frame.

% This function also checks that the mag_units passed in as an input
% are a valid option for the particular method selected. If not, it will
% choose default units, and save them to ud.

% Get userdata from figure
ud = get(hFig,'userdata');

% Read type from ud
filterType = ud.specs.design.type;

% Get method from ud
method = ud.specs.design.method;

% Get the cell of strings of possible units for mag. popup
popup_strs = get_mag_popupStrs(method,ud);

% Get handle to the units popup
h_popup = getfield(ud.h.design_params.specs.mag,'popup');

% Set the appropriate strings in the popup
set(h_popup,'string',popup_strs);

% Get mag units from ud
mag_units = getfield(ud.specs.design,'mag',filterType,'units');

% Compare mag. units to possible units, if empty, assign default units
if isempty(strmatch(mag_units,lower(popup_strs))),
    mag_units = lower(popup_strs{1});
    % Save units
    ud.specs.design.mag = setfield(ud.specs.design.mag,filterType,'units',mag_units);
    set(hFig,'userdata',ud);
end  

% Get the index of the new units
indx = strmatch(mag_units,lower(popup_strs));

% Set new_units in popup
set(h_popup,'Value',indx);

%---------------------------------------------------------------------------
function popup_strs = get_mag_popupStrs(method,ud)
%GET_MAG_POPUPSTRS   Returns the string to populate the mag. units
%                    popup, depending on the design method.

switch lower(method),
case 'remez',
    if strcmp(ud.specs.design.order.calc,'minimum order'),
        popup_strs = {'dB','Linear'};   
    else
        popup_strs = {'Weights'};   
    end
    
case 'firls',
    popup_strs = {'Weights'};   
    
case 'fir1',
    if strcmp(ud.specs.design.order.calc,'minimum order'),
        popup_strs = {'dB','Linear'};   
    else
        popup_strs = {'dB'};   
    end
    
case {'butter','cheb1','cheb2','ellip','maxflat'},
    if strcmp(ud.specs.design.order.calc,'minimum order'),
        popup_strs = {'dB','Squared'};   
    else
        popup_strs = {'dB'};   
    end
end

%--------------------------------------------------------------------------
function set_ebvalsNvis(hFig,frame,data)
%SET_EBVALSNVIS  Set the edit boxes with the data values from ud.
%    Also turn off visibility of unused edit boxes.

ud = get(hFig,'userdata');

% Get method and filter order mode
method = ud.specs.design.method;
filterOrder = ud.specs.design.order.calc;
window = ud.specs.design.window;

% Get specs mode
specsmode = determine_specsmode(frame,method,filterOrder,window);

% Get handle to edit boxes
h_eb = getfield(ud.h.design_params.specs,frame,'eb');

ndata = length(data); % This will be the number of uicontrols that remain visible
      
% Set values in edit boxes
for n = 1:ndata,   
    set(h_eb(n),'string',data{n});    
end

% Set visibility off for unused edit boxes
set(h_eb(ndata+1:end),'visible','off');    

% For the case where the cutoff gain is fixed, turn off all edit boxes
if any(strcmpi(specsmode,{'butter','fircutoff'})) & strcmpi(frame,'mag'),
   set(h_eb,'visible','off');    
end


%--------------------------------------------------------------------------
function set_lblvalsnvis(hFig,frame)
%SET_LBLVALSNVIS  Set the right labels and turn off visibility of unused labels.

ud = get(hFig,'userdata');

% Get method and filter order mode
method = ud.specs.design.method;
filterOrder = ud.specs.design.order.calc;
window = ud.specs.design.window;

% Get specs mode
specsmode = determine_specsmode(frame,method,filterOrder,window);

% Get type from ud
filterType = ud.specs.design.type;

% Get the appropriate labels
lbls = get_lbls;
celloflbls = getfield(lbls,frame,filterType,specsmode);
nlbls = length(celloflbls);
uiWidth = largestuiwidth(celloflbls);

% Get handle to the labels
h_lbl = getfield(ud.h.design_params.specs,frame,'lbl');

% Turn all labels off temporarily
set(h_lbl,'visible','off');        

for n = 1:nlbls,  
    % Set the appropriate labels
    set(h_lbl(n),'string',celloflbls{n});
    
    % Adjust the width of the label
    lbl_pos = get(h_lbl(n),'position');  
    set(h_lbl(n),'position',[lbl_pos(1),...
            lbl_pos(2), lbl_pos(1)+uiWidth, lbl_pos(4)]);
    setStrNPos(h_lbl(n), celloflbls{n}); 
end

% Turn on the labels we use
set(h_lbl(1:nlbls),'visible','on');        
%--------------------------------------------------------------------------
function lbls = get_lbls
% Form a database of all labels for the freq. and mag. edit boxes

lbls.freq.lp.passStop = {'Fpass:','Fstop:'};
lbls.freq.lp.pass = {'Fpass:'};
lbls.freq.lp.stop = {'Fstop:'};
lbls.freq.lp.cutoff = {'Fc:'};

lbls.freq.hp.passStop = {'Fstop:','Fpass:'};
lbls.freq.hp.pass = {'Fpass:'};
lbls.freq.hp.stop = {'Fstop:'};
lbls.freq.hp.cutoff = {'Fc:'};

lbls.freq.bp.passStop = {'Fstop1:','Fpass1:','Fpass2:','Fstop2:'};
lbls.freq.bp.pass = {'Fpass1:','Fpass2:'};
lbls.freq.bp.stop = {'Fstop1:','Fstop2:'};
lbls.freq.bp.cutoff = {'Fc1:','Fc2:'};

lbls.freq.bs.passStop = {'Fpass1:','Fstop1:','Fstop2:','Fpass2:'};
lbls.freq.bs.pass = {'Fpass1:','Fpass2:'};
lbls.freq.bs.stop = {'Fstop1:','Fstop2:'};
lbls.freq.bs.cutoff = {'Fc1:','Fc2:'};


fircutofflbl = {'The attenuation at cutoff',...
        'frequency(ies) is fixed at 6dB','(half the passband gain).'};
iircutofflbl = {'The attenuation at cutoff',...
        'frequency(ies) is fixed at 3dB','(half the passband power).'};


lbls.mag.lp.passStop = {'Apass:','Astop:'};
lbls.mag.lp.ellip = {'Apass:','Astop:'};
lbls.mag.lp.cheby1 = {'Apass:'};
lbls.mag.lp.cheby2 = {'Astop:'};
lbls.mag.lp.butter = iircutofflbl;
lbls.mag.lp.fircutoff = fircutofflbl;

lbls.mag.hp.passStop = {'Astop:','Apass:'};
lbls.mag.hp.ellip = {'Astop:','Apass:'};
lbls.mag.hp.cheby1 = {'Apass:'};
lbls.mag.hp.cheby2 = {'Astop:'};
lbls.mag.hp.butter = iircutofflbl;
lbls.mag.hp.fircutoff = fircutofflbl;

lbls.mag.bp.passStop = {'Astop1:','Apass:','Astop2:'};
lbls.mag.bp.ellip = {'Astop:','Apass:'};
lbls.mag.bp.cheby1 = {'Apass:'};
lbls.mag.bp.cheby2 = {'Astop:'};
lbls.mag.bp.butter = iircutofflbl;
lbls.mag.bp.fircutoff = fircutofflbl;

lbls.mag.bs.passStop = {'Apass1:','Astop:','Apass2:'};
lbls.mag.bs.ellip = {'Apass:','Astop:'};
lbls.mag.bs.cheby1 = {'Apass:'};
lbls.mag.bs.cheby2 = {'Astop:'};
lbls.mag.bs.butter = iircutofflbl;
lbls.mag.bs.fircutoff = fircutofflbl;

remez_strs = {'Freq. vector:','Mag. vector:','Weight vector:'};
firls_strs = remez_strs;
iirlpnorm_strs = {'Freq. vector:','Freq. edges:','Mag. vector:','Weight vector:'};
iirlpnormc_strs = {'Freq. vector:','Freq. edges:','Mag. vector:','Weight vector:',...
        'Max pole radius:'};

lbls.freqmag.diff.remez = remez_strs;
lbls.freqmag.diff.firls = firls_strs;

lbls.freqmag.hilb.remez = remez_strs;
lbls.freqmag.hilb.firls = firls_strs;

lbls.freqmag.sincx.remez = remez_strs;

lbls.freqmag.multiband.remez = remez_strs;
lbls.freqmag.multiband.firls = firls_strs;

lbls.freqmag.arbitrarymag.remez = remez_strs;
lbls.freqmag.arbitrarymag.firls = firls_strs;
lbls.freqmag.arbitrarymag.iirlpnorm = iirlpnorm_strs;
lbls.freqmag.arbitrarymag.iirlpnormc = iirlpnormc_strs;

lbls.freqmag.arbitrarygrp.iirlpnormc = ...
    {'Freq. vector:','Freq. edges:','Grpdelay vector:','Weight vector:',...
    'Max pole radius:'};

%---------------------------------------------------------------------
function update_freqlbls(hFig,units)
%Updates the labels for the edit boxes in the frequency frame.
%
%   Inputs: 
%     hFig  - handle to GUI's figure - currently not used.
%     units - freq. units for current type

switch units
case {'hz', 'khz', 'mhz'}
    convert_freq_lbls(hFig,units,'F');

case 'normalized (0 to 1)',
    convert_freq_lbls(hFig,units,'w');
end

%---------------------------------------------------------------------
function update_maglbls(hFig,units)
%Updates the labels for the edit boxes in the magnitude frame.
%
%   Inputs: 
%     hFig  - handle to GUI's figure - currently not used.
%     units - mag. units for current type

% Get userdata from figure
ud = get(hFig,'userdata');

% Get method and filter order mode
method = ud.specs.design.method;
filterOrder = ud.specs.design.order.calc;
window = ud.specs.design.window;

% Get specs mode
mag_specs_mode = determine_specsmode('mag',method,filterOrder,window);

if ~any(strcmpi(mag_specs_mode,{'butter','fircutoff'})),
   
    switch lower(units)
    case 'db',
        convert_mag_lbls(hFig,'A');
    case 'linear',
        convert_mag_lbls(hFig,'D');
    case 'squared',
        convert_mag_lbls(hFig,'E');
    case 'weights',
        convert_mag_lbls(hFig,'W');
    end
end


%-------------------------------------------------------------------
function convert_freq_lbls(hFig,units,str)
%CONVERT_FREQ_LBLS  Convert labels to reflect current units.
%Local to update_freqlabels
%

update_fs(hFig,units,'freq');

ud = get(hFig,'userdata');
% Get handles to edit boxes labels
h_lbl = getfield(ud.h.design_params.specs,'freq','lbl');

% Change the labels
for n = 1:length(h_lbl),
    lbl = get(h_lbl(n),'string');
    lbl(1) = str;
    set(h_lbl(n),'string',lbl);
end    

%---------------------------------------------------------------------
function update_fs(hFig,units,frame)
%Updates the labels for the edit boxes in the frequency frame.
%
%   Inputs: 
%     hFig  - handle to GUI's figure - currently not used.
%     units - freq. units for current type

switch units
case {'hz', 'khz', 'mhz'}
    enable = 'on';
case 'normalized (0 to 1)',
    enable = 'off';
end

switch lower(enable),
case 'on',
    bgc = 'white';
case 'off',
    bgc = [.8 .8 .8];
end

ud = get(hFig,'userdata');
% Get handle to fs edit box and label
h_fseb = getfield(ud.h.design_params.specs,frame,'fs_eb');
h_fslbl = getfield(ud.h.design_params.specs,frame,'fs_lbl');

% Enable or disable fs as given in 'enable'
set(h_fslbl,'Enable',enable);
set(h_fseb,'Enable',enable,'BackgroundColor',bgc);

%------------------------------------------------------------------
function convert_mag_lbls(hFig,str)
%CONVERT_MAG_LBLS  Convert labels to reflect current units.
%Local to update_maglabels
%

% Get userdata from figure
ud = get(hFig,'userdata');

% Get handles to the mag labels
h_lbl = getfield(ud.h.design_params.specs,'mag','lbl');

% Change the labels
for n = 1:length(h_lbl),
    lbl = get(h_lbl(n),'string');
    lbl(1) = str;
    set(h_lbl(n),'string',lbl);
end    

%-------------------------------------------------------------------
function setStrNPos(h_textuicontrol, newStr)
% SETSTRNPOS Set the String and Position of static text in the "Current
%            Filter Information" frame.
%
% Inputs:
%  h_textuicontrol - Handles to the Text uicontrol(s).
%  newStr          - New strings for the text uicontrol(s).
%

width = largestuiwidth({newStr},'text');

% Make units compatiable with output of largestuiwidth 
prevUnits = get(h_textuicontrol,'Units');
set(h_textuicontrol,'Units','Pixels'); 
textUicontrolPos = get(h_textuicontrol,'Position');

% Set String and Position of the static text.
set(h_textuicontrol,'String',newStr,...
    'Position',...
    [textUicontrolPos(1) textUicontrolPos(2) width textUicontrolPos(4)]);

set(h_textuicontrol,'Units',prevUnits);

% [EOF] - update_specs.m
