% GETNODES converts a history object to a nodes structure suitable for plotting as a tree.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DESCRIPTION: GETNODES converts a history object to a nodes structure suitable
%              for plotting as a tree.
%
% CALL:        [n,a, nodes] = getNodes(hist, stop_option);
%
% INPUT:       hist:        hisoty-object
%              stop_option: - 'File'          ignores the history steps
%                                             below load-history step
%                           - 'Repo'          ignores the history steps
%                                             below retrieve-history step
%                           - 'File Repo'     both steps above
%                           -  N              maximun depth
%
% OUTPUT:      n:     A vector of parent pointers
%              a:     Number of nodes
%              nodes: Struct of the nodes
%
% VERSION:     $Id: getNodes.m,v 1.25 2011/02/18 16:48:52 ingo Exp $
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function varargout = getNodes(varargin)

  import utils.const.*

  if nargin == 1
    h           = varargin{1}; % history object
    n           = [];          % init: list of current node values
    pn          = 0;           % init: current node value
    a           = 1;           % init: number of nodes
    nodes       = [];          % init: node structure
    depth       = 0;           % init: current depth of the tree
    stop_option = 'full';      % stop option
  elseif nargin == 2
    h           = varargin{1}; % history object
    n           = [];          % init: list of current node values
    pn          = 0;           % init: current node value
    a           = 1;           % init: number of nodes
    nodes       = [];          % init: node structure
    depth       = 0;           % init: current depth of the tree
    stop_option = varargin{2}; % stop option
  elseif nargin == 7
    %%% Set inputs
    h           = varargin{1}; % history object
    n           = varargin{2}; % list of current node values
    pn          = varargin{3}; % current node value
    a           = varargin{4}; % number of nodes
    nodes       = varargin{5}; % node structure
    depth       = varargin{6}; % current depth of the tree
    stop_option = varargin{7}; % stop option
  else
    error('### Unknown number of inputs')
  end

  max_depth  = 1e20;
  depth_stop = '';
  if isnumeric(stop_option)
    max_depth = stop_option;
  elseif ischar(stop_option)
    depth_stop = stop_option;
  end

  n = [n pn];
  pl = h.plistUsed;
  nodes(a).pn     = pn;
  nodes(a).invars = h.methodInvars;
  nodes(a).n      = a;
  nodes(a).names  = h.methodInfo.mname;
  nodes(a).params = char(pl);
  nodes(a).pl     = pl;
  nodes(a).h      = history(h);
  utils.helper.msg(msg.OPROC1, 'scanning node %03d [%s]', a, char(nodes(a).names));

  if depth == max_depth
    nodes(a).names  = '...';
    nodes(a).params = '';
    nodes(a).invars = {};
  end

  % set the current node value to the number of the child
  pn = a-1;

  ih  = h.inhists;

  % Now decide what to do with my children
  if isa(ih, 'history')
    for i=1:numel(ih)

      if  isa(pl, 'plist') && isparam(pl, 'filename') && ...
          (strcmpi(depth_stop, 'File') || strcmpi(depth_stop, 'File Repo'))
      elseif isa(pl, 'plist') && (isparam(pl, 'conn') || isparam(pl, 'hostname')) && ...
          (strcmpi(depth_stop, 'Repo') || strcmpi(depth_stop, 'File Repo'))
      else
        if depth < max_depth
          a = a + 1;
          [n, a, nodes] = getNodes(ih(i), n, pn+1, a, nodes, depth+1, stop_option);
        end
      end

    end
  end

  % Set outputs
  varargout{1} = n;
  varargout{2} = a;
  varargout{3} = nodes;
end

