function textlines = struct2str(S,n)
% generate cell array of strings that define structure.
% auxiliary function for writestruct.m
%
% [+GenLib General Purpose Library+] Swiss Plasma Center EPFL Lausanne 2022. All rights reserved.

% F. Felici SPC 2019

if nargin == 1
  n = 6; % default precision
end

textlines = struct2textlines(S,n);

end

function textlines = struct2textlines(S,n)

fields = sort(fieldnames(S));

if numel(fields)==0 % treat case of struct with no fields
  textlines{1} = 'struct()';
  return
end

if numel(S)==1
  textlines{1} = sprintf('struct(...');
  for ifield = 1:numel(fields)
    myfieldname = fields{ifield};
    myfieldval = S.(myfieldname);
    
    % write appropriate set of generating strings depending on type
    if isstruct(myfieldval)
      if numel(myfieldval)==1
        newlines = writeStructString(myfieldname,myfieldval,n);
      else  % array struct
        newlines = structarray2str(myfieldname,myfieldval,n);
      end
    elseif iscell(myfieldval)
      newlines = writeCellString(myfieldname,myfieldval,n);
    else
      if isnumeric(myfieldval) || islogical(myfieldval)
        assert(ismatrix(myfieldval),'3D or higher dimensional arrays not supported')
        datastring = mat2str(myfieldval,n,'class');
      elseif ischar(myfieldval)
        datastring = sprintf('''%s''',myfieldval);
      else
        error('unsupported type')
      end
      newlines{1} = sprintf('''%s'',%s,...',myfieldname,datastring);
    end
    
    % append new text lines for this field
    textlines = [textlines,newlines{:}]; %#ok<AGROW>
    clear newlines
  end
  % correct final string to close structure declaration
  textlines{end} = [textlines{end}(1:end-4),')'];
else
  % this is an array of struct
  textlines = structarray2str(S,n);  
end
end

function newlines = writeStructString(fieldname,fieldval,n)
datastr = struct2str(fieldval,n); % recursive call
% start-end fixes
datastr{1} = sprintf('''%s'',%s',fieldname,datastr{1});
datastr{end} = [datastr{end},',...'];
newlines = datastr;
end

function  newlines = writeCellString(fieldname,fieldval,n)
str = cell2str(fieldval,n);
% start-end fixes
datastr{1} = sprintf('''%s'',{%s}',fieldname,str);
datastr{end} = [datastr{end},',...'];
newlines = datastr;
end

function textlines=structarray2str(myfieldname,structarray,n)
% this is an array of struct
structarraystr = sprintf('struct([...');
[nrow,ncol] = size(structarray);

for irow=1:nrow
  for icol=1:ncol
    mystructstr = struct2str(structarray(irow,icol),n);
    structarraystr = sprintf('%s\n%s\n',structarraystr,mystructstr{1:end});
    if icol==ncol
      % add row separation, structarraystr(1:end-1); % remove the last \n
      structarraystr =  sprintf('%s;',structarraystr(1:end-1));
    else
      structarraystr = sprintf('%s,...',structarraystr(1:end-1));
    end
  end
end

structarraystr = [structarraystr(1:end-1),'])'];
textlines{1} = sprintf('''%s'',%s,...',myfieldname,structarraystr);
end
