% RSTRUCT recursively converts an object into a structure.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% RSTRUCT recursively converts an object into a structure. This is the same
% behaviour as MATLAB's struct(obj) except that it recursively converts all
% sub-objects into structures as well.
%
%   >> s = utils.prog.rstruct(obj)
%
% M Hewitson 02-06-07
%
% $Id: rstruct.m,v 1.14 2011/05/04 05:03:44 mauro Exp $
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function varargout = rstruct(varargin)
  
  s = {};
  n = 1;
  for jj = 1:nargin
    objs = varargin{1};
    for k = 1:numel(objs)
      obj = objs(k);
      if isa(obj, 'ltpda_obj')
        s{n}.class  = class(obj);
        s{n}.tbxver = strtok(getappdata(0, 'ltpda_version'));
        names  = getFieldnames(obj);
        for nn=names
          fname = char(nn);
          if isa(obj.(fname), 'ltpda_obj')
            s{n}.(fname) = utils.prog.rstruct(obj.(fname));
          elseif isobject(obj.(fname))
            s{n}.(fname) = struct(obj.(fname));
          else
            s{n}.(fname) = obj.(fname);
          end
        end
        n = n + 1;
      end
    end
  end
  
  s = [s{:}];
  
  % Reshape the struct to the shape of the input objects
  s = reshape(s, size(objs));
  
  % Set output
  varargout{1} = s;
  
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION:    getFieldnames
%
% DESCRIPTION: Returns the field names which should be stored in a XML file.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fields = getFieldnames(obj)
  meta = eval(['?' class(obj)]);
  metaProp = [meta.Properties{:}];
  props = {metaProp(:).Name};
  propGetAccess = strcmpi({metaProp(:).GetAccess}, 'public');
  propDependent = [metaProp(:).Dependent];
  fields = props(propGetAccess & ~propDependent);
end


