function fcns = designparams_cbs
%DESIGNPARAMS_CBS Handles all the callbacks executed by the uicontrols in the bottom 
%                 portion of fdatool, when the GUI is in the filter design mode.

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

% "Export" the handles to all local functions via a structure.
% The caller will get this, and grab the handles they need.
% This will allow callers to gain direct access to local functions.
fcns.filtType_cbs       = @filtType_cbs;
fcns.filtMethod_cbs     = @filtMethod_cbs;
fcns.methodPopup_cbs    = @methodPopup_cbs;
fcns.winMethPopup_cb    = @winMethPopup_cb;
fcns.winParamEditbox_cb = @winParamEditbox_cb;
fcns.filtOrder_cbs      = @filtOrder_cbs;
fcns.specOrdereb_cb     = @specOrdereb_cb;
fcns.numdenOrdereb_cb   = @numdenOrdereb_cb;

%-------------------------------------------------------------------------
function filtType_cbs(hcbo, eventStruct)
%FILTTYPE_CBS Filter Type radio buttons and popupmenu callbacks.

% Cache figure handle & get the structure stored in the figure's userdata.
hFig = gcbf;
ud = get(hFig,'Userdata');

% Cache the previous filter type stored in the userdata (ud).
prevFiltType = lower(ud.specs.design.type);

% Dertermine the currently selected filter type from the GUI.
currentFiltType = getFilterType(ud.h.design_params.filtTypes.rb,hcbo);

% Return early if same filter type (radio btn or popupmenu) is selected.
if strcmp(prevFiltType,currentFiltType),
    btnStyle = get(gcbo,'Style');
    if strcmpi(btnStyle,'radiobutton'),
        set(gcbo,'Value',1); % Only set the value if it's the Radio button
    end        
    return;
end

% Update the data structure (ud)  w/ new filter type 
ud.specs.design.type = currentFiltType;
set(hFig,'UserData',ud);

set_flagsdirty(hFig); % Set appropriate flags.

% Update the filter type frame, the type menus and any other
% section of the GUI that depends on the filter type.
update_filtertype(hFig);

%-------------------------------------------------------------------------
function currentFiltType = getFilterType(h_rb,hcbo);
% GETFILTERTYPE Dertermine the currently selected filter type from the GUI.
%
% Inputs:
%   h_rb - handles to the filter types radio buttons.
%   hcbo - handle to uicontrol that issued callback.
%
% Output:
%   currentFiltType - currently selected filter type.

% Read the filter types from the GUI.
filtTypes = lower(get(h_rb(1:end-2),'String')); % Common types - radio buttons.
otherFiltTypes = lower(get(h_rb(end),'String'));% "Other" types - popupmenu.

% Get the current filter type by checking the radio buttons and popupmenu.
currentFiltType = lower(get(gcbo,'String'));
if isempty(currentFiltType) | iscell(currentFiltType),  
    % "Other" radio button was selected or a selection was made in the popup.
    currentFiltTypeIndx = get(h_rb(end),'Value'); % popupmenu
    currentFiltType = lower(otherFiltTypes{currentFiltTypeIndx});
end

% The strings stored in ud are based on the tags of the corresponding
% menu items, they are not exactly the same as the radio button
% labels, therefore we must convert the strings to the tags in order
% to compare etc.
currentFiltType = str2tag(currentFiltType);

%-------------------------------------------------------------------------
function filtMethod_cbs(hcbo, eventStruct)
%FILTMETHOD_CBS Filter Design Method radio buttons callbacks.

% Cache handle to the radio button that executed the callback.
h_rb = gcbo;

% Cache figure handle & get the structure stored in the figure's userdata.
hFig = gcbf;
ud = get(hFig,'Userdata');

% Cache the handles to the design method radion buttons and popupmenus.
h.rb = ud.h.design_params.methods.rb;
h.pop = ud.h.design_params.methods.pop;

% Unselect both radio buttons.  This will decrease the time when both
% radio buttons are selected simultaneously.
set([h.rb.iir h.rb.fir],'Value',0);

% Cache the previous filter design method stored in the userdata (ud).
prevMethod = lower(ud.specs.design.method);

% Determine which radio button (or filter class) was selected - IIR/FIR.
currentClass = lower(get(h_rb,'string'));

% Determine which method is selected in the appropriate popupmenu.
switch currentClass
case 'iir',
    method = methPopSelection(h.pop.iir); % Look in IIR popup.
case 'fir',
    method = methPopSelection(h.pop.fir); % Look in FIR popup.
end
% Convert the popup string to a string that is stored in the userdata.
currentMethod = method2tagStr(method);

% If the same button is selected repeatedly simply select it and return.
if strcmp(prevMethod,currentMethod),
    set(h_rb,'Value',1);
    return;
end

% Update the data structure with the new filter design method, 
% and save it back in the figure's userdata.
ud.specs.design.method = currentMethod;
set(hFig,'UserData',ud);

set_flagsdirty(hFig); % Set appropriate flags.

% Update the filter type frame, the type menus and any other
% section of the GUI that depends on the filter design method.
update_filtermethod(hFig);

%-------------------------------------------------------------------------
function methodPopup_cbs(hcbo, eventStruct)
%METHODPOPUP_CBS Filter Design Method popupmenu buttons callbacks.

% Cache figure and the button handle.
hFig = gcbf;
h_pop = gcbo;

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

% Determine which method was selected in the popupmenu.
methodStr = methPopSelection(h_pop);

% Convert the popup string list to the appropriate string that gets
% stored in the userdata.
method = method2tagStr(lower(methodStr));

% Set the userdata with the current selection.
ud.specs.design.method = method;
set(hFig,'Userdata',ud);

set_flagsdirty(hFig); % Set appropriate flags.

% Update the filter type frame, the type menus and any other
% section of the GUI that depends on the filter design method.
update_filtermethod(hFig);

%-------------------------------------------------------------------------
function winMethPopup_cb(hcbo, eventStruct)
%WINMETHPOPUP_CB Filter Design Window Method popupmenu callback.

% Cache figure and the button handle.
hFig = gcbf;
h_pop = gcbo;

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

% Set the userdata structure with the current selection.
indx = get(h_pop,'Value');
windowStrs = get(h_pop,'String');
fcnName = windowStr2fcnname(windowStrs{indx});
ud.specs.design.window = fcnName;
set(hFig,'Userdata',ud);

set_flagsdirty(hFig); % Set appropriate flags.

% Update the filter type frame, the type menus and any other
% section of the GUI that depends on the filter design method.
update_filtermethod(hFig);

%-------------------------------------------------------------------------
function winParamEditbox_cb(hcbo, eventStruct)
%WINDPARAMEDITBOX_CB Window Parameter edit box callback.

% Cache figure and the edit box handle.
hFig = gcbf;
h_eb = gcbo;

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

% Set the userdata structure with the current selection.
paramVal = get(h_eb,'String');
ud.specs.design.winparam = paramVal;
set(hFig,'UserData',ud);

set_flagsdirty(hFig); % Set appropriate flags.

% Update the "Apply" button.
update_actionbtn('update_enablestate',hFig);

%-------------------------------------------------------------------------
function selectedMethod = methPopSelection(h)
%METHPOPSELECTION Determine the current method selected in the popupmenu.
% 
% Inputs:
%   h - handle to the popupmenu.
% Ouputs:
%   selectedMethod - a character array of 

% Determine which method is selected in the popupmenu.
methodIndx = get(h,'Value');
methods = lower(get(h,'String'));
if ~iscell(methods),  % Only one choice in the popupmenu.
    methods = {methods};
end
selectedMethod = methods{methodIndx};

%-------------------------------------------------------------------------
function currentMethod = method2tagStr(methodStr)
%METHOD2TAGSTR This function maps the current filter method in the popupmenu
%              string to a string that can be used stored in the userdata.
% Inputs:
%   methoStr - the string selected from the popupmenu.
% Outputs:
%    currentMethod - the string representing currently selected method in 
%                    the popupmenu.

switch methodStr
    
    % --- FIR METHODS ---
case 'complex equiripple',
    currentMethod = 'cremez';
case 'constrained ls',
    currentMethod = 'fircls';
case 'eigenfilter',
    currentMethod = 'eigen';
case 'equiripple',
    currentMethod = 'remez';
case 'frequency sampling',
    currentMethod = 'fir2';
case 'least-squares',
    currentMethod = 'firls';
case 'window',
    currentMethod = 'fir1';
    
    % --- IIR METHODS ---
case 'butterworth',
    currentMethod = 'butter';
case 'chebyshev type i',
    currentMethod = 'cheb1';
case 'chebyshev type ii',
    currentMethod = 'cheb2';
case 'constrained least pth-norm'
    currentMethod = 'iirlpnormc';
case 'elliptic',
    currentMethod = 'ellip';
case 'least pth-norm'
    currentMethod = 'iirlpnorm';
case 'maximally flat',
    currentMethod = 'maxflat';
case 'prony',
    currentMethod = 'prony';
case 'steiglitz-mcbride',
    currentMethod = 'stmcb';
case 'yule-walker',
    currentMethod = 'yulewalk';
otherwise
    return
end

%-------------------------------------------------------------------------
function filtOrder_cbs(hcbo, eventStruct)
%FILTORDER_CBS Filter Order radio buttons callbacks.

% Cache figure handle & get the structure stored in the figure's userdata.
hFig = gcbf;
ud = get(hFig,'Userdata');

% Cache the handles to the filter order radio buttons.
h_rb = ud.h.design_params.filtOrder.rb;

% Cache the previous filter order and calculation method 
% stored in the userdata (ud).
prevFiltOrderCalc = lower(ud.specs.design.order.calc);
% The specify order value is the first element of the cell array
prevFiltOrderVal = ud.specs.design.order.value{1}; 

% Read the filter order calculation methods from the GUI.
currentOrderCalcs = lower(get(h_rb(1:end-1),'String')); % Order calc method - rbs.
currentOrderVal = get(h_rb(end),'String');    % Filter order value - edit box.

% Determine the current filter order calculation method by checking 
% which radio button is selected.
currentOrderCalc = lower(get(gcbo,'String'));
currentOrderVal = get(h_rb(end),'String');

% Assign the old order to current order value if edit box is empty.
if isempty(currentOrderVal),
    currentOrderVal = prevFiltOrderVal;
end

% If the same button is selected repeatedly simply select it and return.
if strcmp(prevFiltOrderCalc,currentOrderCalc),
    set(gcbo,'Value',1);
    return;
end

% Update the userdata (ud) structure with new filter order and 
% calculation method.
ud.specs.design.order.calc = currentOrderCalc;
% Store the current specify order value in the first element of the cell array
ud.specs.design.order.value{1} = currentOrderVal;
set(hFig,'UserData',ud);

set_flagsdirty(hFig); % Set appropriate flags.

% Update the parts (frames, etc.) of the GUI that are effected by 
% a choosing a different filter order estimation method.
update_designparams('update_filtOrderFrame',hFig);
update_specs('update_all',hFig);

% Update analysis area if static response is current analysis.
update_staticresp = 1;
update_analysisframe(hFig,update_staticresp); 

% Update the "Apply" button.
update_actionbtn('update_enablestate',hFig);

%-------------------------------------------------------------------------
function specOrdereb_cb(hcbo, eventStruct)
%SPECORDEREB_CB Specify filter order edit box callback.

hFig = gcbf;
ud = get(hFig,'Userdata');

% Get the value entered in the specify order edit box and save it in UD.
orderVal = get(gcbo,'String');
% Store the specify order value in the first element of the cell array
ud.specs.design.order.value{1} = orderVal;
set(hFig,'UserData',ud);

set_flagsdirty(hFig); % Set appropriate flags.

% Update the "Apply" button.
update_actionbtn('update_enablestate',hFig);

%-------------------------------------------------------------------------
function numdenOrdereb_cb(hcbo, eventStruct)
%NUMDENORDEREB_CB Numerator/denominator order edit boxes callback.

hFig = gcbf;
ud = get(hFig,'Userdata');

% Get the value entered in the specify order edit box and save it in UD.
orderVal = get(ud.h.design_params.filtOrder.eb,'String');
ud.specs.design.order.value = orderVal;
set(hFig,'UserData',ud);

set_flagsdirty(hFig); % Set appropriate flags.

% Update the "Apply" button.
update_actionbtn('update_enablestate',hFig);


%-------------------------------------------------------------------
%                       Utility Functions
%-------------------------------------------------------------------
function fcnName = windowStr2fcnname(windowStr)

windowStr = lower(windowStr);
switch windowStr
case 'chebyshev',
    fcnName = 'chebwin';
case 'triangular',
    fcnName = 'triang';
otherwise  % All other windows have a one-to-one correspondence.
    fcnName = windowStr;

% case 'kaiser',
% case 'bartlett',
% case 'blackman',
% case 'boxcar',
% case 'hamming',
% case 'hann',
% case 
end

%-------------------------------------------------------------------
function currentFiltType = str2tag(currentFiltType)
% This function maps the current filter type from the string of the
% radio button, to the tag stored in ud for the curren type. This 
% can be used for comparison to the labels of the radio buttons.

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

%-------------------------------------------------------------------
% [EOF] designparams_cbs.m
