function name = dbnames(d,varargin)
% dbnames  List of database entries filtered by name or class.
%
% Syntax
% =======
%
%     LIST = dbnames(D,...)
%
% Input arguments
% ================
%
% * `D` [ struct ] - Input database.
%
% Output arguments
% =================
%
% * `LIST` [ cellstr ] - List of input database entries that pass the name
% or class test.
%
% Options
% ========
%
% * `'nameFilter='` [ char | *`Inf`* ] - Regular expression against which
% the database entry names will be matched.
%
% * `'classFilter='` [ char | *`Inf`* ] - Regular expression against which
% the database entry class names will be matched.
%
% Description
% ============
%
% Example
% ========
%

% -IRIS Toolbox.
% -Copyright (c) 2007-2012 Jaromir Benes.

options = passvalopt('data.dbnames',varargin{:});

%**************************************************************************

% Empty name filter and empty class filter returns empty list.
if isempty(options.namefilter) && isempty(options.classfilter)
   name = {};
   return
end

% Get the database's field names. Infs in both filters return all names.
name = fieldnames(d).';
if isequal(options.namefilter,Inf) && isequal(options.classfilter,Inf)
   return
end
n = length(name);

% Filter the names.
if isequal(options.namefilter,Inf)
   nameTest = true([1,n]);
elseif isempty(options.namefilter)
   nameTest = false([1,n]);
else
   x = regexp(name,options.namefilter,'once');
   nameTest = ~cellfun(@isempty,x);
end
   
% Filter the classes.
if isequal(options.classfilter,Inf)
   classTest = true([1,n]);
elseif isempty(options.classfilter)
   classTest = false([1,n]);
else
   c = cellfun(@class,struct2cell(d),'uniformOutput',false).';
   x = regexp(c,options.classfilter,'once');
   classTest = ~cellfun(@isempty,x);
end

% Return the names tha pass both tests.
name = name(nameTest & classTest);
   
end
