% SIMPLIFYYUNITS simplify the 'yunits' property of the ao.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DESCRIPTION: SIMPLIFYYUNITS sets the 'yunits' property of the ao.
%
% CALL:        ao = simplifyYunits(ao)
%              obj = obj.simplifyYunits(pl);
%
% <a href="matlab:utils.helper.displayMethodInfo('ao', 'simplifyYunits')">Parameters Description</a>
%
% VERSION:     $Id: simplifyYunits.m,v 1.20 2011/05/22 22:20:26 mauro Exp $
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function varargout = simplifyYunits(varargin)
  
  % Check if this is a call from a class method
  callerIsMethod = utils.helper.callerIsMethod;

  if callerIsMethod
    as     = varargin{1};
    if nargin == 2
      pls  = varargin{2};
    else
      pls  = plist();
    end
    
  else
    %%% Check if this is a call for parameters
    if utils.helper.isinfocall(varargin{:})
      varargout{1} = getInfo(varargin{3});
      return
    end
    
    import utils.const.*
    utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename);
    
    % Collect input variable names
    in_names = cell(size(varargin));
    for ii = 1:nargin,in_names{ii} = inputname(ii);end
    
    % Collect all AOs
    [as, ao_invars] = utils.helper.collect_objects(varargin(:), 'ao', in_names);
        
    % Apply defaults to plist
    pls = applyDefaults(getDefaultPlist, varargin{:});
  
  end
  
  % Decide on a deep copy or a modify
  bs = copy(as, nargout);

  % check if simplifying the prefixes or not: 'yes'/'no' or true/false or 'true'/'false'     
  prefixes = utils.prog.yes2true(find(pls, 'prefixes'));
  
  % gathering exception list
  exceptions = find(pls, 'exceptions');
  if isempty(exceptions)
    exceptions = cell(0);
  elseif ~iscell(exceptions)
    exceptions = cellstr(exceptions);
  end
  
  % Loop over AOs
  for jj = 1:numel(bs)
    
    % Count the prefix values first before we compute this value to the
    % data because then is the error not so large.
    prfval = 1;
    
    % simplify prefixes first
    if prefixes
      yun = copy(bs(jj).data.yunits, true);
      vals = yun.vals;
      exps = yun.exps;
      
      % Get the different unit-string of the y-axis.
      % Use for this the char-method because this method adds the prefix
      % to the unit.
      strs = {};
      yuns = yun.split();
      for kk = 1:numel(yuns)
        strs{end+1} = char(yuns(kk));
      end
      
      % Run over all y-units parts because it might be that one of the parts is
      % in the exception list.
      for ii = 1:numel(vals)
        str = strs{ii}(2:end-1);
        str = strtok(str, '^');
        if ~(any(ismember(str, exceptions)))
          prfval   = prfval .* prod(vals(ii) .^ exps(ii));
          vals(ii) = 1;
          yun.setVals(vals);
        end
      end
      bs(jj).data.setYunits(yun);
    end
    
    % Multiply the prefix value to the y-data
    bs(jj).data.setY(bs(jj).y .* prfval);
    
    % simplify the units
    bs(jj).data.setYunits(simplify(bs(jj).data.yunits, exceptions));

    if ~callerIsMethod
      bs(jj).addHistory(getInfo('None'), pls, ao_invars(jj), bs(jj).hist);
    end
  end
  
  % Set output
  varargout = utils.helper.setoutputs(nargout, bs);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                               Local Functions                               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%--------------------------------------------------------------------------
% Get Info Object
%--------------------------------------------------------------------------
function ii = getInfo(varargin)
  
  if nargin == 1 && strcmpi(varargin{1}, 'None')
    sets = {};
    pl   = [];
  else
    sets = {'Default'};
    pl   = getDefaultPlist();
  end
  % Build info object
  ii = minfo(mfilename, 'ao', 'ltpda', utils.const.categories.helper, '$Id: simplifyYunits.m,v 1.20 2011/05/22 22:20:26 mauro Exp $', sets, pl);
end

%--------------------------------------------------------------------------
% Get Default Plist
%--------------------------------------------------------------------------
function plout = getDefaultPlist()
  persistent pl;
  if ~exist('pl', 'var') || isempty(pl)
    pl = buildplist();
  end
  plout = pl;  
end

function pl = buildplist()
  pl = plist();
  
  % Prefixes
  p = param({'prefixes', 'also simplify the prefixes and scale the data'}, paramValue.TRUE_FALSE);
  pl.append(p);
  
  % Exceptions
  p = param({'exceptions', 'A string or cell of strings of units which are not simplyfied.'}, ...
    paramValue.EMPTY_STRING);
  pl.append(p);
  
end
