function data=mphgetmethods(node, varargin)
% MPHGETMETHODS  Get information about methods
%
% m = mphgetmethods(node) returns names of the methods that can be called
% on a node. Some of the unimportant methods names are removed from the 
% returned list by default (e.g. 'wait').
%
% m = mphgetmethods(node, options...) uses the options that are specified.
%
% m is a cell array where the first column contains the method name and the
% second column contains the value for methods that can be called without
% argument and which return simple data types (Strings and numbers).
%
% Options:
% filter         {'off'} | 'on'   Filter methods away that do not return
%                                 simple data types
% showall        {'off'} | 'on'   Show all methods (e.g. also 'wait')
% fullmethodcall {'off'} | 'on'   Add a third column with the full
%                                 argument list for the method.
%
% Example:
% m = mphgetmethods(model.sol('sol1'))
%
% See also: mphgetproperties, mphgetmodel

% Set default properties
props = {'filter','off',...
    'showall', 'off', ...
    'fullmethodcall', 'off'};

% Update properties with the input argument
prop = proputil(props, varargin);

showallm = {'isactive' 'wait' 'dom' 'equals' 'hashCode' 'getClass'};

if nargin<2
    arg = 0;
end
if nargin<3
    showall = 0;
end

data = {};
met = methods(node, '-full');

t = 1;
for i=1:length(met)
    m0 = regexp(met{i}, ' (.*)(\(.*\))', 'tokens', 'once');
    if length(m0)==0
        continue
    end
    if ~strcmp(prop.showall, 'on') && any(strcmp(m0{1}, showallm))
        continue
    end
    funcname = strrep([m0{1} m0{2}], 'java.lang.', '');
    
    data{t,1} = funcname;
    
    if strcmp(prop.fullmethodcall, 'on')
        data{t,3} = met{i};
    end
    
    m = regexp(met{i}, '[^ ]*(String|String\[\]|boolean|int|int\[\]|double|float) ([a-zA-Z0-9]+)\(\)', 'tokens', 'once');
    if length(m)
        type = m{1};
        fcn = m{2};
        
        try
            val = node.(fcn);
            switch type
                case 'String'
                    data{t,2} = char(val);
                case 'String[]'
                    data{t,2} = join(cell(val), ' ');
                case 'boolean'
                    data{t,2} = int32(val);
                case 'int[]'
                    data{t,2} = num2str(val);
                otherwise
                    data{t,2} = val;
            end
            t = t+1;
        catch err
        end
    else
        if strcmp(prop.filter, 'off')
            data{t,1} = funcname;
            t = t+1;
        end
    end
end


% ---
function txt=join(c, sep, repnum)
% Join elements together using a separator
%
% txt=join(c, sep, repnum)
%
% Example:
% join({'a' 'b' 'c'}, ', ')
% join([1 4 7], ' - ')
%
% join('a', '\t', 3)
% join({'a' 'b' 'c'}, ', ', 2)
% join(4:8, ';', 4)

error(nargchk(1,3,nargin))

if nargin==1
    sep = ',';
end

if nargin==3
    if ischar(c)
        c = repmat({c}, repnum, 1);
    elseif iscell(c) | isnumeric(c)
        c = repmat(c(:), repnum, 1);
    end
end

if isnumeric(c)
    txt = num2str(c(1));
    for i=2:length(c)
        txt = [txt sep num2str(c(i))];
    end
else
    txt = c{1};
    for i=2:length(c)
        txt = [txt sep c{i}];
    end
end

% Copyright 2010-2011 COMSOL
