function [] = struct_disp(mystrct)
% display structure hierarchy iteratively.
% ngalbraith, 2011/10/04 (mod 2011/10/20)
% loosely based upon structstruct, which is available from
% the Matlab file exchange, and was contributed by Andres
% (aj.indirect@gmail.com)
%
% Modified to display contents of singletons, 1d arrays,
%    and strings
% Notes
%    the array display may be a problem for some structures!
%    contents of cells are not displayed, just the cell size
%  Bugs!
% does not get size of substructures right, 
%   e.g.  meta.data.cond(2) looks like cond  [1x1] struct
% USAGE:
% struct_disp(mystrct)
%   displays the structure and MOST contents of mystruct
%
% Recursive function 'structstruct.m' accepts a single input of any class.
% For non-structure input, structstruct displays the class and size of the
% input and then exits.  For structure input, structstruct displays the
% fields and sub-fields of the input in an ASCII graphical printout in the
% command window.  The order of structure fields is preserved.
%
% OUTPUT (sample):
% > struct_disp(meta)
% meta:  [1x1] struct
%   |--site: Stratus
%   |--deployment: 11
%   |--start_year: 2011
%   |--instrument:  [1x1] struct
%   |  |--model: ASIMet logger CF
%   |  |--SN: 14
%   |  |--manufacturer: WHOI-UOP and Star Engineering

dbg=1;
sname=inputname(1) ;   % usually works, not today (2013/9/27 running on cougar)
%sname=varname(mystrct); does not work
if dbg==1, fprintf('displaying %s\n',sname);
end
if nargin() < 1
    fprintf('usage: struct_disp(structure_name)');
else
    % Figure the type and class of the input
    whosout = whos('mystrct');
    sizes =  whosout.size;
    
    sizestr = [int2str(sizes(1)),'x',int2str(sizes(2))];
    endstr = [':  [' sizestr '] ' whosout.class];
    
    % Print out the properties of the input variable
    disp(' ');
    disp([ inputname(1)  ' '  endstr ]);
    
    % Check if mystrct is a structure, then call the recursive function
     if isstruct(mystrct)   
        recursor(mystrct,0,'');
    end
%     if isstruct(mystrct)
%         % don't print out too many if struct array is very long
%         nstrs=length(mystrct);
%         if dbg==1, fprintf('nstrs %d min %d \n',nstrs, min(nstrs,5)); end
%         for nsn=1:min(nstrs,5)  
%             if dbg ==1, fprintf('%d: ',nsn); end
%             mystrN=mystrct(nsn);
%             recursor(mystrN,0,'');
%         end
%         if nstrs > 5
%             disp('...');
%         end
%     else
%         disp('not a struct');
%     end
end
% Print out a blank line
disp(' ');

end

function recursor(mystrct,level,recstr)
%  mod 201110 nrg
%  if this is not a struct, not an array, print contents
%  instead of size/class, unless it's too big
% 2013/09 you need to handle cells, also
% struct arrays - for struct arrays need to recurse x times
recstr = [recstr '  |'];
fnames = fieldnames(mystrct);
for idx = 1:length(fnames)
    %% Print out the current fieldname
    % Take out the i'th field
    tmpstruct = mystrct.(fnames{idx});
    
    % Figure the type and class of the current field
    whosout = whos('tmpstruct');
    sizes = whosout.size;
    % disp([ 'class: ' whosout.class])
    % handle display of small objects
    issmall= 0;
    if sizes(1) == 1 || sizes(2) == 1
        issmall = 1;
        % added check on long arrays here 2011/10/20
        if sizes(1) > 120 || sizes(2) > 120
            issmall = 0;
        end
    end
    %     if ~ischar(tmpstruct)
    %         if sizes(1) > 3 || sizes(2) > 3
    %            issmall = 0;
    %         end
    %     end
    
    if ~isstruct(tmpstruct) && length(sizes) == 2 && issmall == 1
        try
            endstr=  [ ': ' num2str(tmpstruct) ];
            %           for qq=1:length(tmpstruct)
            %               endstr=[ endstr ' ' num2str(tmpstruct(qq)) ' ' ];
            %           end
        catch 
            sizestr = [int2str(sizes(1)),'x',int2str(sizes(2))];
            endstr = [':  [' sizestr '] ' whosout.class];
        end
    else
        sizestr = [int2str(sizes(1)),'x',int2str(sizes(2))];
        endstr = [':  [' sizestr '] ' whosout.class];
    end
    
    % Create the strings
    % 201110 dont make last field any diff

    str = [recstr '--' fnames{idx} endstr];
 
    
    % Print the output string to the command line
    disp(str);
    
    %% Determine if each field is a struct
    
    % Check if the i'th field of mystrct is a struct
    if isstruct(tmpstruct) % If tmpstruct is a struct, recursive function call
        recursor(tmpstruct,level+1,recstr); % Call self
    end
    
end

end






% fmtstr='';
% for jj=1:lev
%     fmtstr=[fmtstr '\t'];
% end
% fno=fieldnames(mystrct);
% for ii=1:length(fno)
%     fn=fno{ii};
%     myfmtstr=[fmtstr '%s: '];
%     fprintf(myfmtstr,fn);
%     cmd=['fld  =  mystrct.' fn ';' ];
%     eval (cmd);
%     if isstruct(fld )
%         mylev=lev+1;
%         struct_disp(fld,mylev)
%     else
%
%         [m,n]=size(fld);
%         if m == 1 || n == 1
%             fmtstr=[fmtstr ' %s\n'];
%
%         else
%             % array, just print size
%             fld = sprintf('[%d x %d]', m,n);
%             fmtstr=[fmtstr '% %s\n'];
%         end
%         % did you know that num2str doesn't mess up input strings???
%         fprintf(fmtstr, num2str(fld));
%     end
% end
