% PLOT plots a history object as a tree diagram.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DESCRIPTION: PLOT plots a history object as a tree diagram.
%
% NOTE:        Some of the code below is taken from Mathworks's treeplot.m
%
% CALL:        plot (history)
%              plot (history, arg)
%              plot (history, arg, pl)
%              plot (axes_handle, ...)
%
% PARAMETER:   '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
%
% VERSION:     $Id: plot.m,v 1.34 2011/02/18 16:48:52 ingo Exp $
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function varargout = plot(varargin)

  import utils.const.*
  prefs = getappdata(0, 'LTPDApreferences');
  utils.helper.msg(msg.OMNAME, 'running %s/%s', mfilename('class'), mfilename);

  %%% Used call: plot (history, arg)
  if isa(varargin{1}, 'history')

    figure;
    hists = varargin{1};
    curr_axes = axes;
    if nargin >= 2
      varargin = varargin(2:end);
    else
      varargin = {};
    end

    %%% Used call: plot (curr_axes_handle, history, arg)
  elseif ishandle(varargin{1})

    curr_axes = varargin{1};
    axes(curr_axes);
    hists = varargin{2};
    if nargin >= 3
      varargin = varargin(3:end);
    else
      varargin = {};
    end

  else
    error (['### the first input should be a history object or an axes handle' ...
      sprintf(' varargin{1} = [%s]',varargin{1})]);
  end

  %%% collect the parameter and put them into the parameter list
  plot_args = {};
  pl        = plist();
  args      = varargin;

  while ~isempty(args)

    if isa(args{1}, 'plist')
      arg  = args{1};
      pl   = append(pl, arg);
      args = args(2:end);

      % Add the key-values to the parameter list
    elseif length(args) >= 2
      if  ischar(args{1})
        arg = args{1};
        val = args{2};
        pl  = append(pl, param(arg, val));

        plot_args{end+1} = arg;
        plot_args{end+1} = val;
        args = args(3:end);

      else
        error('### the key [%s] is not from the type ''char''', char(args{1}));
      end
    else
      help(mfilename('fullpath'))
      error('### There is no key/value pair left.');
    end

  end

  %%% Combine input plist and default plist
  pl = combine(pl, getDefaultPlist);

  %%% Comes the call from the browser or from the command window
  stop_option = find(pl, 'stop_option');

  %%% Output handles for figures and axes
  hfig = [];
  ax   = [];
  at   = [];

  nhists = length(hists);
  for i=1:nhists

    hist = hists(i);
    % disp(sprintf('--- plotting history %s', hist.name));

    % convert history object to a node list
    [n,a, nodes] = getNodes(hist, stop_option);

    p = [nodes(:).pn];
    [x,y,h]=treelayout(p);
    f = find(p~=0);
    pp = p(f);
    X = [x(f); x(pp); repmat(NaN,size(f))];
    Y = [y(f); y(pp); repmat(NaN,size(f))];
    X = X(:);
    Y = Y(:);

    % figure
    hfig = [hfig gcf];

    % axes objects
    a = plot (curr_axes, X, Y, 'r--', x, y, 'ro');
    % plot (X,Y) --> die linien
    if length(a)>1
      set(a(2), 'MarkerFaceColor', 'r');
      set(a(2), 'MarkerSize', 8);
    end
    args  = plot_args;
    while ~isempty(args)
      prop = args{1};
      val  = args{2};
      args = args(3:end);
      for ii = 1:length(a)
        set(a(ii), prop, val);
      end
    end
    ax = [ax a];

    % text objects
    a    = [];
    for j=1:length(x)
      % node description
      fcnname = getFcnName(nodes(j).names);
      str = ['{\bf\color{blue}' num2str(nodes(j).n) ':}{\bf\color{red}' fcnname '} ' strrep(strrep(char(nodes(j).params), '{', '\{'), '}', '\}')];
      nlstr = getNodeInputs(nodes(j).invars);

      na  = text(x(j), y(j),...
        [utils.prog.wrapstring(strrep(str,'_', '\_'), double(prefs.getDisplayPrefs.getDisplayWrapStrings)) ...
        cellstr(['{\color{magenta} ' strrep(nlstr,'_', '\_') '}'])]);
      set(na, 'HorizontalAlignment', 'center');
      set(na, 'EdgeColor', 'k', 'Fontsize', 10);
      set(na, 'BackgroundColor', 'w');
      set(na, 'Margin', 5);
      a   = [a na];
    end
    at = [at a];

    % xlabel(['height = ' int2str(h)]);
    axis([0 1 0 1]);
    box off;
    axis off;

  end

  % Make outputs
  if nargout > 0
    varargout{1} = hfig;
  end
  if nargout > 1
    varargout{2} = ax;
  end
  if nargout > 2
    varargout{3} = at;
  end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                               Local Functions                               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION:    getFcnName
%
% DESCRIPTION: compute strings to display for function name.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function fcnname = getFcnName(name)

  %   switch name
  %     case 'mtimes'
  %       fcnname = 'x';
  %     case 'times'
  %       fcnname = 'x';
  %     case 'plus'
  %       fcnname = '+';
  %     case 'minus'
  %       fcnname = '-';
  % %     case 'sqrt'
  % %       fcnname = '\surd';
  %     case 'mrdivide'
  %       fcnname = '/';
  %     case 'rdivide'
  %       fcnname = '/';
  %     otherwise
  %       fcnname = char(name);
  %   end

  fcnname = char(name);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION:    getNodeInputs
%
% DESCRIPTION: compute strings to display for inputs to nodes.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function str = getNodeInputs(invars)

  ni = length(invars);
  if ni > 0
    str = char(invars{1});
    for iv=2:ni
      s = char(invars{iv});
      if ~strcmp(s, 'pl')
        str = [str '  ' s];
      end
    end
  else
    str = '';
  end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION:    getDefaultPlist
%
% DESCRIPTION: Returns the default parameter list.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function plo = getDefaultPlist()
  plo = plist('stop_option', 'full');
end

