% APPLYDEFAULTS apply the default plist to the input plists
% 
% CALL:
%       plout = applyDefaults(defaultPlist, pl1, pl2, ..., pl3)
%       [plout, pl_unused] = applyDefaults(defaultPlist, pl1, pl2, ..., pl3)
% 
% The default plist is assumed to be the first one.
% 
% The plists are combined and the resulting keys are compared to the keys
% in the default plist. If any key is missing from the default plist a
% warning is issued.
% 
% M Hewitson 04-04-11
% 
% VERSION $Id: applyDefaults.m,v 1.14 2011/08/16 06:05:37 hewitson Exp $
% 

function varargout = applyDefaults(varargin)
  
  inputs = utils.helper.collect_objects(varargin(:), 'plist');
  
  % trivial case
  if numel(inputs) == 1
    varargout{1} = copy(inputs, true);
    return;
  end  
  
  % Get the default plist and copy it because we modify it by setting the
  % user's values
  default = copy(inputs(1), true);
  
  % Get the rest
  pls = inputs(2:end);
  
  % run the user plists through parse to combine and resolve expressions
  userplist = parse(pls, default);
  
  % check keys against default keys
  dkeys = default.getKeys;
  ukeys = userplist.getKeys;
  res = ismember(ukeys, dkeys);
  if ~all(res)
    warning('The following keys were not found in the default plist and will be ignored: %s', sprintf('[%s] ', ukeys{res==0}));
  end
    
  % combine defaults
  [default, unused] = overrideDefaults(userplist, default);
    
  % output the used and unused plists
  varargout{1} = default;
  if nargout >= 2
    varargout{2} = unused;
  end
  
end


function [default, unused] = overrideDefaults(userplist, default)
  
  unused = plist();
  
  for kk = 1:numel(userplist.params)
    
    % which key are we acting on
    key = userplist.params(kk).key;
    
    % get override value from user
    val = userplist.params(kk).val;
    
    % decide what to do based on the presence or not of the parameter in the default plist
    if isparam(default, key)
      % set the parameter value, taking into account it could be itself a plist object
      default.setDefaultForParam(plist('key', key, 'option', val));
    else
      % append the parameter value, to the unused parameters plist
      unused.append(copy(userplist.params(kk), true));
    end
  end
  
end
