% UTP_SMODEL_SETVALUES a set of UTPs for the smodel/setValues method
%
% M Hewitson 06-08-08
%
% $Id: utp_smodel_setValues.m,v 1.1 2011/04/06 19:15:48 ingo Exp $
%

% <MethodDescription>
%
% The setValues method of the smodel class sets the values property.
%
% </MethodDescription>

function results = utp_smodel_setValues(varargin)
  
  % Check the inputs
  if nargin == 0
    
    % Some keywords
    cl      = 'smodel';
    mthd    = 'setValues';
    prop    = 'values';
    
    disp('******************************************************');
    disp(['****  Running UTPs for ' cl '/' mthd]);
    disp('******************************************************');
    
    % Test objects
    s1 = smodel('a1*x1 + a2*x2 + a3*x3');
    s1.setParams({'a1', 'a2', 'a3'});
    s1.setName();
    
    s2 = smodel('a1*x1 + a2*x2');
    s2.setParams({'a1', 'a2'});
    s2.setName();
    
    s3 = smodel('a1*x1');
    s3.setParams('a1');
    s3.setName();
    
    sv = [s1, s2, s1];
    sm = [s1, s2, s1; s1, s2, s1];
    
    % Exception list for the UTPs:
    [ple1,ple2,ple3,ple4,ple5,ple6] = get_test_ples();
    
    % The setter method have different possibilities to set a property
    val1 =  111;               % obj.setValues(val1)
    val2 = [11 22];            % obj.setValues(val2)
    val3 = [1 2 3];            % obj.setValues(val3)
    val4 = plist(prop, val1);  % obj.setValues(plist('values', val1)
    
    % Run the general tests
    results(1)  = utp_genericSet_minfo(mthd, s1, prop, @algoTests_minfo);
    results(2)  = utp_genericAnyShape(mthd, sv, val2, @algoTests);
    results(3)  = utp_genericAnyShape(mthd, sm, val2, @algoTests);
    results(4)  = utp_genericList(mthd, s1, s2, s3, val1, @algoTests);
    results(5) = utp_genericList(mthd, s1, sv, s3, val3, @algoTests);
    results(6) = utp_genericHistory(mthd, s1, val3, ple2);
    results(7) = utp_genericModify(mthd, s1, val3, @algoTests, ple1);
    results(8) = utp_genericOutput(mthd, s2, s2, val2, @algoTests, ple2);
    
    disp('Done.');
    disp('******************************************************');
    
  elseif nargin == 1 % Check for UTP functions
    if strcmp(varargin{1}, 'isutp')
      results = 1;
    else
      results = 0;
    end
  else
    error('### Incorrect inputs')
  end
  
  % Check that the default value un the PLIST
  function atest = algoTests_minfo(defVal)
    atest = true;
    % Check default value for the key 'values'
    if ~isequal(defVal, {}), atest = false; end
  end
  
  % Check that the property have the correct value
  function atest = algoTests(in, out, idx, varargin)
    atest = true;
    value = varargin;
    % Check that the input and output objects are the same except the
    % property 'values' and the history
    ple = plist('EXCEPTIONS', {'created', 'proctime', 'UUID', 'hist', prop});
    if numel(value{1}) == numel(in(idx).params)
      if ~eq(in(idx), out(idx), ple), atest = false; end
      if ~eq(in(idx).hist, out(idx).hist.inhists), atest = false; end
      % Check that the parameter gets the correct value.
      if isa(value{1}, 'plist') && value{1}.nparams == 1 && value{1}.isparam(prop)
        % The value was set with a plist.
        values = processValues([], value{1}.find(prop));
        if ~isequal(out(idx).(prop), values), atest = false; end
      else
        if iscell(value{1}), value = value{1}; end
        if numel(value) == numel(out)
          if ~isequal(out(idx).(prop), num2cell(value{idx})), atest = false; end
        else
          if ~isequal(out(idx).(prop), num2cell(value{1})), atest = false; end
        end
      end
    end
  end
  
  function values = processValues(values, val)
    switch class(val)
      case 'char'
        values = [values unit(val)];
      case 'unit'
        values = [values reshape(val, 1, [])];
      case 'cell'
        for ii=1:numel(val)
          values = processValues(values, val{ii});
        end
      case 'plist'
        if length(val) == 1 && isa(val, 'plist') && isparam(val, prop)
          vals = find(val, prop);
          values = processValues(values, vals);
        end
    end
  end
  
end
