%[param] = FCUMRegOptions(varargin)
% This function sets the optional input arguments for the function gam().
% =====
% Input:
% =====
%
% This function allows 3 different ways for input:
%
% 1)   If no input argument is provided, use default values:
%      ex:
%      >> p = FCUMRegOptions()
%
% 2)   Provide the name of the argument following by the value to be assign
%      to this argument. The order of the input argument pairs (argument
%      name, value) does not have to follow the same order of the input
%      order like those defined in fcum(). Any undefined input arguments
%      will be followed the same as the default ones.
%
%      ex:
%      >> p = FCUMRegOptions('ngrid',51, 'bf_maxit',2);
%      means set ngrid = 2, bf_maxit = 2 and everything else
%      will be using the default values
%
% 3)   Provide the argument value directly, but ORDER matters.
%      Any undefined argument values will be set to the default ones.
%
%      ex:
%      >> p = FCUMRegOptions(40,2)
%      means set ngrid1 = 40, npoly = 2 and
%      everything else will be using the default values
%
% ======
% Output: a struct array that contains all user-defined options for gam().
% ======
%
function [param] = FCUMRegOptions(varargin)
% Set default options
param = struct('npoly', 1, 'kernel', 'epan', 'bw', [], ...
    'ls_maxit', 30, 'bf_maxit', 1, 'verbose', 'on', 'ls_tol', 0.01, ...
    'family', [], 'regular', [], 'error', 1, 'ngrid', 51, 'xcov', [], ...
    'FVE_threshold', 0.99, 'xmu', [], 'kn', [], 'maxk', 20, 'PCA', [], ...
    'K', [], 'V', [], 't_V', [], 'model', 'gam', 'newdata', [], 'selection_k', []);
if nargin > 0
    op_names = {'ngrid1', 'npoly', 'kernel', 'bw', 'ls_maxit', ...
        'bf_maxit', 'verbose', 'ls_tol', 'family', 'regular', 'error', ...
        'ngrid', 'xcov', 'FVE_threshold', 'xmu', 'kn', 'maxk', 'PCA', ...
        'K', 'V', 't_V', 'model', 'newdata', 'selection_k'};
    paramLen = length(struct2cell(param));
    if ischar(varargin{1})  % Match and set arguments by names
        if nargin > 2*paramLen
            fprintf(1,'Warning: Too many input arguments!Reset to default values!\n');
        elseif mod(nargin, 2) == 0
            for i = 1:2:nargin
                id = strcmp(varargin{i},op_names);
                if isempty(id)
                    fprintf(1,['Warning: "' varargin{i} '" is an invalid name and it will be ignored! Type showFCUMRegOptionNames() for more details.\n']);
                else
                    param = setVal(param, op_names{id}, varargin{i+1});
                end
            end
        else
            fprintf(1,'Warning:Either option name or its corresponding value is missing!Reset to default values!\n');
        end
    else  % Set arguments directly
        if nargin <= paramLen
            
            for i = 1:nargin
                param = setVal(param, op_names{i}, varargin{i});
            end
        else
            fprintf(1,'Warning: Too many input arguments!Reset to default values!\n');
        end
    end
    
end

end
