function update_designparams(fcn,hFig)
%UPDATE_DESIGNPARAMS Updates all the frames that contain the uicontrols
%                    to set the filter parameters (Design mode).
% Input:
%   fcn    - Update function (for a frame in Design Mode).
%   hFig   - Handle to the Filter Design GUI figure.

%   Author(s): P. Costa, P. Pacheco, R. Losada
%   Copyright 1988-2000 The MathWorks, Inc.
%   $Revision: 1.11 $  $Date: 2000/06/13 21:23:44 $ 

feval(fcn,hFig);

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

update_filtTypeFrame(hFig);  % Update the Filter Type frame.
update_methodFrame(hFig);    % Update the Design Method frame.
update_filtOrderFrame(hFig); % Update the Filter Order frame.

%-------------------------------------------------------------------------
function update_filtTypeFrame(hFig)
%UPDATE_FILTTYPEFRAME Update the Filter Type Frame.
%
% Input:
%    hFig    - Handle to the Filter Design GUI figure.

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

% Create a flat list of handles to the Filter Type frame and uis, 
% and turn their visiblity ON.
h = ud.h.design_params.filtTypes;
h_filtTypeuis = [h.frame h.rb]; 
set(h_filtTypeuis,'Visible','On');

% Determine the current filter type selection.
currentFiltType = getcurrentType(hFig);

% Update the popupmenus with the available filter types.
update_filtTypePopStrs(ud);

% Create a list of the filter types.
filtTypes = lower(get(h.rb(1:end-2),'String'));  % Don't include "Other" rb & popupmenu
otherFiltTypes = lower(get(h.rb(end),'String')); % Get types in popupmenu.

% Unselect all radio buttons.
set(h.rb(1:end-1),'Value',0);  % Don't include the popupmenu ui.

% Select the appropriate radio button and popupmenu choice depending
% on the filter type chosen.
indx = find(strcmpi(currentFiltType,filtTypes));
if ~isempty(indx), % One of the common filter types is selected.
    set(h.rb(indx),'Value',1);
else               % look in the "Other" list.
    indx = find(strcmpi(currentFiltType,otherFiltTypes));
    set(h.rb(end-1),'Value',1);   % Select the "Other" radio button.
    set(h.rb(end),'Value',indx);  % Set the proper choice in the popupmenu.
end

%-------------------------------------------------------------------------
function currentFiltType = getcurrentType(hFig)
% GETCURRENTTYPE Gets the currently selected filter type.
%
% Input:
%    hFig - Handle to the Filter Design GUI figure.
% Output:
%    currentFiltType - string; currently selected filter type.

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

% Get the current filter type stored in the userdata (ud) structure.
currentFiltType = lower(ud.specs.design.type);
currentFiltType = tagStr2type(currentFiltType); 

%-------------------------------------------------------------------------
function update_filtTypePopStrs(ud);
%UPDATE_FILTTYPEPOPSTRS Updates the strings in the "Other" radio button 
%                       popupmenu.
% Inputs:
%   ud - structure saved in the fdool's figure userdata.

% Determine which filter Types are currently available by polling the menus.
h_otherEnabled = findobj(ud.h.menus.other_type,'Enable','on');

if isempty(h_otherEnabled),  % No "Other" types are enabled
    set(ud.h.design_params.filtTypes.rb(end-1:end),'Enable','off');
else
    otherTypes = removeampersands(get(h_otherEnabled,'Label'));

    % Update the "Other" popupmenu strings with the currently available types.
    set(ud.h.design_params.filtTypes.rb(end),'string',otherTypes);
end

%-------------------------------------------------------------------------
function update_methodFrame(hFig)
%UPDATE_METHODFRAME Update the Design Method frame.
%
% Input:
%    hFig - Handle to the Filter Design GUI figure.

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

% Turn the visiblity ON for the Design Method frame and its UIs.
h = ud.h.design_params.methods;
h_allMethoduis = [h.frame h.rb.iir h.rb.fir h.pop.iir h.pop.fir];
set(h_allMethoduis,'Visible','On');

% Currently selected filter design method.
currentMethod = getcurrentMethod(hFig);

% Update the popupmenus with the available design methods based on filter type.
updateMethPopStrs(ud);

% Get the latest available design methods list.
iirMethods = lower(get(h.pop.iir,'String'));
firMethods = lower(get(h.pop.fir,'String'));

% Unselect both radio buttons.
set([h.rb.iir h.rb.fir],'Value',0);

% Select the appropriate radio button and popupmenu choice depending
% on the filter design method chosen.
iir_indx = find(strcmpi(currentMethod,iirMethods));
fir_indx = find(strcmpi(currentMethod,firMethods));
if ~isempty(iir_indx),     % IIR method was selected.
    set(h.rb.iir,'Value',1);
    set(h.pop.iir,'Value',iir_indx,'Enable','on');

elseif ~isempty(fir_indx)  % FIR method was selected
    set(h.rb.fir,'Value',1); 
    set(h.pop.fir,'Value',fir_indx,'Enable','on');
end

% Update the Window frame UIs.
update_windowFrame(hFig);

%-------------------------------------------------------------------------
function currentMethod = getcurrentMethod(hFig)
% GETCURRENTMETHOD Get the currently selected filter design method.
%
% Input:
%   hFig - Handle to the Filter Design GUI figure.
% Output:
%   currentMethod - string; currently selected filter design method.

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

% Get the current design method stored in the userdata (ud) structure.
currentMethod = lower(ud.specs.design.method);
currentMethod = tagStr2method(currentMethod); 

%-------------------------------------------------------------------------
function updateMethPopStrs(ud)
%UPDATEMETHPOPSTRS Updates the strings in the IIR and FIR popupmenus
%                  according to the available design methods for the
%                  selected filter type.
% Inputs:
%   ud - structure saved in the fdool's figure userdata.

% Poll the menus to determine which methods are available.
[firMethods, iirMethods] = getMethods(ud.h.menus);

% Update the popupmenus.

% IIR radio button and popupmenu.
h = ud.h.design_params.methods;
if isempty(iirMethods),
    set(h.rb.iir,'Enable','off');
    setenableprop(h.pop.iir,'off','popupmenu');
else
    % Enable in case it was disabled before
    set(h.rb.iir,'Enable','on');
    setenableprop(h.pop.iir,'on','popupmenu');
    % If current value is larger than number of strings, reset value.
    resetpopupval(h.pop.iir,iirMethods);
    set(h.pop.iir,'String',iirMethods);
end

% FIR radio button and popupmenu.
if isempty(firMethods),
    set(h.rb.fir,'Enable','off');
    setenableprop(h.pop.fir,'off','popupmenu');
else
    % Enable in case it was disabled before
    set(h.rb.fir,'Enable','on');
    setenableprop(h.pop.fir,'on','popupmenu');
    % If current value is larger than number of strings, reset value.
    resetpopupval(h.pop.fir,firMethods);
    set(h.pop.fir,'String',firMethods);
end

%-------------------------------------------------------------------------
function resetpopupval(h,strs)
%RESETPOPUPVAL  If current value is larger than number of strings, reset value.
popval = get(h,'value');
if popval > length(strs),
    set(h,'value',1);
end

%-------------------------------------------------------------------------
function [firMethods, iirMethods] = getMethods(h_menus)
% GETMETHODS Polls the menus to determine which filter methods are 
%            available.
% Input:
%   h_menus - handle to the menus.
% Output:
%   firMethods - list of currently available FIR filter design methods.
%   iirMethods - list of currently available IIR filter design methods.

% IIR methods.
h_iirEnabled = findobj(h_menus.iir_methods,'Enable','on');
iirMethods = removeampersands(get(h_iirEnabled,{'Label'}));

% FIR methods.

% Don't include the Window menu choice in the findobj operation, otherwise
% it will return all the Window choices.
h_firEnabled = findobj(h_menus.fir_methods(1:end-1),'Enable','on');
if strcmp(get(h_menus.fir_methods(end),'Enable'),'on'),
    % Add the handle of the Window menu choice to the list.
    h_firEnabled(end+1) = h_menus.fir_methods(end);
end
firMethods = removeampersands(get(h_firEnabled,{'Label'}));

%-------------------------------------------------------------------------
function update_windowFrame(hFig)
%UPDATE_WINDOWFRAME Update the enable state of the Window frame UIs and
%                   select the correct Window.
% Input:
%   hFig - handle to the GUI's figure.

% Set the visibility of the Window frame uicontrols.
setWindowFrVis(hFig,'on');

% Update popupmenu with new list of window choices.
updateWindowPopStrs(hFig);

% Update the popupmenu to reflect current window selection.
update_WinFrpopup(hFig);

% Update the window parameter edit box.
update_winparam_eb(hFig);

%-------------------------------------------------------------------------
function setWindowFrVis(hFig,visState)
% SETWINDOWFRVIS Set the visibility for the Window frame uicontrols.
% 
% Input:
%   hFig - Handle to the Filter Design GUI figure.
%   visState - the visibility state of the frame and its uicontrols.

% Get the handles to the window frame that's stored in the figure's ud.
ud = get(hFig,'Userdata');
h = ud.h.design_params.methods;
h_win = ud.h.design_params.firwindow;

% Turn ON the visibility of the Window frame and its UIs.
h_allUIs = [h_win.frame h.pop.firWin h.pop.winLabel h.pop.eb h.pop.eblabel]; 
set(h_allUIs,'Visible',visState);

%-------------------------------------------------------------------------
function update_WinFrpopup(hFig)
% UPDATE_WINFRPOPUP Updates the enable state and value of the popupmenu
%                   in the Window Specifications frame.
% Input:
%   hFig - Handle to the Filter Design GUI figure.

% Get the handles to the window frame that's stored in the figure's ud.
ud = get(hFig,'Userdata');
h = ud.h.design_params.methods;

% Get the current window all possible window choices.
currentWindow = lower(ud.specs.design.window);
windowStrs = lower(get(h.pop.firWin,'String'));
winMethods = windowStrs2fcnnames(windowStrs);

% Determine if should enable window popup.
enableState = determine_Winpop_state(hFig); 

% Update the selection in the Window popupmenu.
win_indx = find(strcmpi(currentWindow,winMethods));
set(h.pop.firWin,'Value',win_indx)

% Enable/Disable the Window popupmenu and label.
setenableprop(h.pop.firWin,enableState,'popupmenu'); % Sets background color.
set(h.pop.winLabel,'Enable',enableState);

%-------------------------------------------------------------------------
function update_winparam_eb(hFig)
% UPDATE_WINPARAM_EB Updates the window parameter edit box.
%
% Input:
%   hFig - Handle to the Filter Design GUI figure.

% Get the handles to the window frame that are stored in the figure's ud.
ud = get(hFig,'Userdata');
h = ud.h.design_params.methods;

currentWindow = lower(ud.specs.design.window);
winparam = ud.specs.design.winparam;

% Determine if window popup is enabled.
enableState = determine_Winpop_state(hFig); 

% Enable/Disable the Window parameter edit box and label.
if strcmp(enableState,'on') & ...
        any(strcmpi(currentWindow,{'kaiser','chebwin'})) & ...
        strcmpi(ud.specs.design.order.calc,'specify order:'),
    winparam_state = 'on';
else
    winparam_state = 'off';
end
setenableprop(h.pop.eb,winparam_state,'popupmenu'); % Sets background color.
set(h.pop.eblabel,'Enable',winparam_state);
set(h.pop.eb,'String',winparam);                   % Set the edit box value.

%-------------------------------------------------------------------------
function updateWindowPopStrs(hFig)
%UPDATEWINDOWPOPSTRS Updates the strings in the window list popupmenu
%                    according to the available design methods for the 
%                    selected filter type.
% Input:
%   hFig - Handle to the Filter Design GUI figure.

% Get figure's ud.
ud = get(hFig,'Userdata');
h = ud.h.design_params.methods;
h_menus = ud.h.menus;

% Poll the menus to determine which Window choices are enabled.
h_winEnabled = findobj(h_menus.fir_window_methods,'Enable','on');
winMethods = removeampersands(get(h_winEnabled,'Label'));

% Window popupmenu.
if isempty(winMethods),
    setenableprop(h.pop.firWin,'off','popupmenu');
else
    % Enable in case it was disabled before
    setenableprop(h.pop.firWin,'on','popupmenu');
    set(h.pop.firWin,'String',winMethods);
end

%-------------------------------------------------------------------------
function enableState = determine_Winpop_state(hFig)
% DETERMINE_WINPOP_STATE Determine if the window popupmenu should be
%                        enabled or disabled depending on whether FIR1
%                        is selected or not.
% Input:
%   hFig - Handle to the Filter Design GUI figure.
% Output:
%   enableState - 'on' or 'off' depending if FIR1 or FIR2 is selected.

% Get the figure's userdata.
ud = get(hFig,'Userdata');

% Get the current design method stored in the userdata (ud) structure.
currentMethod = lower(ud.specs.design.method);

% fir1 & fir2 correspond to FIR Window.
if any(strcmpi(currentMethod,{'fir1','fir2'})),  
    enableState = 'on';
else
    enableState = 'off';
end

%-------------------------------------------------------------------------
function update_filtOrderFrame(hFig)
%UPDATE_FILTORDERFRAME Update the Filter Order Frame.
%
% Input:
%    hFig    - Handle to the Filter Design GUI figure.

% Get the filter order frame handles that are stored in the figure's ud.
ud = get(hFig,'Userdata');
h = ud.h.design_params.filtOrder;

% Get filter type and design method
filtertype = ud.specs.design.type;
method = ud.specs.design.method;

% Determine what uicontrols to set visible depending on type and method
if strcmpi(filtertype,'arbitrarymag') & ...
        any(strcmpi(method,{'iirlpnorm','iirlpnormc'})),
    hndls2turnon = [h.frame h.eb h.lb];
    hndls2turnoff = h.rb;
    update_numden(hFig,hndls2turnon,hndls2turnoff);
else
    hndls2turnoff = [h.eb h.lb];
    hndls2turnon = [h.frame h.rb];
    update_specmin(hFig,hndls2turnon,hndls2turnoff);
end

%-------------------------------------------------------------------------
function update_numden(hFig,hndls2turnon,hndls2turnoff)
%UPDATE_NUMDEN Update the numerator order/denominator order edit boxes in the
%               filter order frame

% Set frame and uicontrols' visibility on.
setFiltOrdFrVis(hndls2turnon,hndls2turnoff);

% Update the numerator and denominator order edit boxes
update_numdenebs(hFig);
%-------------------------------------------------------------------------
function update_specmin(hFig,hndls2turnon,hndls2turnoff)
%UPDATE_SPECMIN Update the specify order/minimum order radio buttons in the
%               filter order frame

% Set frame and uicontrols' visibility on.
setFiltOrdFrVis(hndls2turnon,hndls2turnoff);

% Unselect all radio buttons.
h_rb = hndls2turnon(3:end-1); % Don't include the edit box ui.
set(h_rb,'Value',0);  

% Update the enable state and value of the specify order edit box.
update_specorder_eb(hFig);

% Select appropriate order estimation method.
setOrderCalc(hFig); % Modifies userdata.

% Update the Window frame since the window parameter depends
% order estimation method.
update_windowFrame(hFig);

%-------------------------------------------------------------------------
function setFiltOrdFrVis(hndls2turnon,hndls2turnoff)
% SETFILTORDFRVIS Set the visibility of the uicontrols in the Filter 
%                 Order Frame.
% Inputs:
%   hndls2turnon - Array of handles to uicontrols whose visibility we turn on
%   hndls2turnoff- Array of handles to uicontrols whose visibility we turn off


set(hndls2turnon,'Visible','on');
set(hndls2turnoff,'Visible','off');

%-------------------------------------------------------------------------
function update_numdenebs(hFig)
% UPDATE_NUMDENEBS Update the numerator and denominator order edit boxes
%
% Inputs:
%   hFig - GUI figure handle.

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

% Get the current filter order cell array
currentOrderVal = ud.specs.design.order.value;

% Set the current numerator and denominator orders
set(h.eb(1),'string',currentOrderVal{1});
set(h.eb(2),'string',currentOrderVal{2});

%-------------------------------------------------------------------------
function update_specorder_eb(hFig)
% UPDATE_FILTORDER_EB Updates the visibility and value of the specify 
%                     order edit box.
% Inputs:
%   hFig - GUI figure handle.

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

% Get the current filter order and calculation method from ud.
currentOrderCalc = lower(ud.specs.design.order.calc);
% The specify order value is the first element of the cell array
currentOrderVal = ud.specs.design.order.value{1};

% Set the correct order even if the edit box is grayed out.
set(h.rb(end),'String',currentOrderVal);

% Enable/disable the edit box depending on if specify order was selected.
if strcmp(currentOrderCalc,'specify order:'),
    enableState = 'on';
else  
    enableState = 'off';
end
setenableprop(h.rb(end),enableState,'edit');

%-------------------------------------------------------------------------
function setOrderCalc(hFig)
% SETORDERCALC Select the appropriate radio button depending on the 
%              order calculation method chosen.
% Inputs:
%   hFig - GUI figure handle.

% Get the filter order frame handles that are stored in the figure's ud.
ud = get(hFig,'Userdata');
h = ud.h.design_params.filtOrder;

% Get the current filter order alculation method all possible methods.
currentOrderCalc = lower(ud.specs.design.order.calc);
orderCalcMethods = lower(get(h.rb(1:end-1),'String')); % Don't include edit box

indx = find(strcmpi(currentOrderCalc,orderCalcMethods));

% Determine if current filter type/method combo is supports min order
minorder = isminorder(ud);

if minorder,
    set(h.rb(2),'Enable','on');  % In case it was disabled.
    set(h.rb(indx),'Value',1);
else
    % Gray out the min order radio button if the filter design method
    % doesn't support min order and select the specify order radio button.
    set(h.rb(1),'Value',1);
    setenableprop(h.rb(end),'on','edit');  % Enable edit box.
    set(h.rb(2),'Enable','off');           % Disable minimum order.
    
    % Update the data structure, ud, with new selection.
    ud.specs.design.order.calc = 'Specify order:';
    set(hFig,'Userdata',ud);
end

%-------------------------------------------------------------------------
function minorder = isminorder(ud)
% Determine if current filter type/method combo is supports min order

% Assume minimum order is not available by default
minorder = 0;

switch ud.specs.design.type,
case {'lp','hp','bp','bs'},
    switch ud.specs.design.method,
    case {'cheb1','cheb2','butter','ellip','remez'},
        minorder = 1;
    case 'fir1',
        if strcmpi(ud.specs.design.window,'kaiser'),
            minorder = 1;
        end
    end
end


%-------------------------------------------------------------------------
function currentFiltType = tagStr2type(currentFiltType)
% This function maps the current filter type (stored as a tag) in ud, to 
% a string that can be used for comparison to the labels of the radio buttons.

switch currentFiltType,
case 'lp',
    currentFiltType = 'lowpass';
case 'hp',
    currentFiltType = 'highpass';
case 'bp',
    currentFiltType = 'bandpass';
case 'bs',
    currentFiltType = 'bandstop';
case 'diff',
    currentFiltType = 'differentiator';
case 'hilb',
    currentFiltType = 'hilbert transformer';
case 'matchedimp',
    currentFiltType = 'matched impulse resp.';
case 'multiband',
    currentFiltType = 'multiband';
case 'arbitrarymag',
    currentFiltType = 'arbitrary magnitude';
case 'arbitrarygrp',
    currentFiltType = 'arbitrary group delay';
case 'sincx',
    currentFiltType = 'sinc(x) equalizer';
case 'raised',
    currentFiltType = 'raised-cosine';
case 'sav',
    currentFiltType = 'savitzky-golay';
end

%------------------------------------------------------------------------
function currentMethod = tagStr2method(currentMethod)
% This function maps the current filter method (stored as the tag) in ud, 
% to a string that can be used for comparison to the labels in the popups.

switch currentMethod
case 'cremez',
    currentMethod = 'complex equiripple';
case 'fircls',
    currentMethod = 'constrained ls';
case 'remez',
    currentMethod = 'equiripple';
case 'fir2',
    currentMethod = 'frequency sampling';
case 'firls',
    currentMethod = 'least-squares';
case 'fir1',
    currentMethod = 'window';
case 'iirlpnorm',
    currentMethod = 'Least Pth-norm';
case 'iirlpnormc',
    currentMethod = 'Constrained least Pth-norm';
case 'butter',
    currentMethod = 'butterworth';
case 'cheb1',
    currentMethod = 'chebyshev type i';
case 'cheb2',
    currentMethod = 'chebyshev type ii';
case 'ellip',
    currentMethod = 'elliptic';
case 'maxflat',
    currentMethod = 'maximally flat';
case 'prony',
    currentMethod = 'prony';
case 'stmcb',
    currentMethod = 'steiglitz-mcbride';
case 'yulewalk',
    currentMethod = 'yule-walker';
end

%-------------------------------------------------------------------
function fcnNames = windowStrs2fcnnames(windowStrs)

for k = 1:length(windowStrs)
    switch lower(windowStrs{k})
        
    case 'chebyshev',
        fcn = 'chebwin';
    case 'triangular',
        fcn = 'triang';
    otherwise  % All other windows have a one-to-one correspondence.
        fcn= windowStrs{k};
        
        % case 'kaiser',
        % case 'bartlett',
        % case 'blackman',
        % case 'boxcar',
        % case 'hamming',
        % case 'hann',
        % case 
    end
    fcnNames{k} = fcn;
end

%------------------------------------------------------------------------
% [EOF] update_designparams.m

