% ADDHISTORYSTEP Adds a history step of a non LTPDA method to  object with history.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DESCRIPTION: Adds a history step of a non LTPDA method to  object with
%              history.
%
% CALL:        obj = addHistoryStep(obj, minfo, h_pl, ver, var_name, inhists, ...);
%
% INPUT:       obj:      Object with histry like AOs, SSMs, MFIRs, MIIRs, ...
%              h_pl:     Plist which should go into the history.
%              ver:      cvs version of the user defined method. Only
%                        necessary if no minfo is passed in.
%              minfo:    Information object of the function. If not defined
%                        this method will take the following:
%                        minfo(CALLED_METHOD, 'none', '', 'User defined', ver, {'Default'}, h_pl);
%              var_name: Cell-array with the variable manes of the object(s)
%              inhists:  History objects which should be add to the input
%                        object. e.g. [a.hist b.hist]
%
% REMARK:      Don't use this method inside a sub function
%
% VERSION:     $Id: addHistoryStep.m,v 1.9 2011/03/25 13:32:09 ingo Exp $
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function varargout = addHistoryStep(varargin)
  
  % Get the calling method name from the
  stack    = dbstack();
  
  if numel(stack) < 2
    error('### Please use this method only inside a method');
  end
  
  mthdName = stack(2).name;
  
  % Collect objects
  objs     = utils.helper.collect_objects(varargin(:), '');
  pls      = utils.helper.collect_objects(varargin(:), 'plist');
  mi       = utils.helper.collect_objects(varargin(:), 'minfo');
  ver      = utils.helper.collect_objects(varargin(:), 'char');
  invars   = utils.helper.collect_objects(varargin(:), 'cell');
  in_hists = utils.helper.collect_objects(varargin(:), 'history');
  
  % Check that the input objects are objects with history
  if ~isa(objs, 'ltpda_uoh')
    error('### The input objects must be derived from the ltpda_uoh class like ao, ssm, mfir, ...');
  end
  
  % If the user doesn't pass in an minfo object then create a default one.
  if isempty(mi)
    if isempty(ver)
      ver = 'No version';
    end
    if ~isempty(pls)
      pls.combine();
    end
    mi = minfo(mthdName, 'none', '', utils.const.categories.user, ver, {'Default'}, pls);
  end
  
  % Modify plist object
  if ~isempty(pls)
    % Make sure that we have only one PLIST
    pls.combine();
    
    % 1. replace ltpda_uoh in pls with their history
    % 2. empty the description field of a parameter ('desc')
    % 3. remove the options
    for jj=1:pls.nparams
      p = pls.params(jj);
      if isa(p.getVal, 'ltpda_uoh')
        p.setVal([p.getVal.hist]);
      end
      p.setDesc('');
      p.setVal(p.getVal);
    end
  end
  % Remove Password from the history-plist
  if isa(pls, 'plist') && pls.isparam('password')
    pls.remove('password');
  end
  % Remove Username from the history-plist
  if isa(pls, 'plist') && pls.isparam('username')
    pls.remove('username');
  end
  
  % Remove the 'sets' and the corresponding 'plists' from the minfo
  % object. They are not important for the history step.
  mi.clearSets();
  
  % Add history to all objects
  for ii = 1:numel(objs)
    pause(0.001)
    t0 = time();
    
    % set UUID
    uuid = char(java.util.UUID.randomUUID);
    objs(ii).setUUID(uuid);

    % Create new history object
    h = history(t0.utc_epoch_milli, mi, pls, invars, uuid, in_hists);
    h.setObjectClass(class(objs(ii)));

    % Set the new history
    objs(ii).setHist(h);
    
  end
  
  % Prepare output
  varargout{1} = objs;
end




