function fieldInfo = dbffieldinfo(S)
%DBFFIELDINFO Construct default DBF field info structure array from geostruct.
%
%   FIELDINFO = DBFFFIELDINFO(S) analyzes a geographic data structure S and
%   constructs a default fieldinfo structure suitable for use with SHAPEWRITE,
%   where it controls the layout of the DBF file. If a custom DBF layout is
%   needed or desired, you can use the output of DBFFIELDINFO as a starting
%   point and modify it before calling SHAPEWRITE.  If S has no attribute
%   fields, then FIELDINFO will be empty.

%   Copyright 2003-2004 The MathWorks, Inc.  
%   $Revision: 1.1.8.1 $  $Date: 2004/12/18 07:46:21 $

% Determine what types of fields to write for each attribute.
attributeNames = fields(S);
[t1,fIndex,t2] = setxor(attributeNames,{'Geometry','BoundingBox','X','Y','Lat','Lon'});
attributeNames = attributeNames(sort(fIndex));

% Return empty if there are no attributes
if isempty(attributeNames)
    fieldInfo = [];
end

% Keep it simple for now: Support only types 'N' and 'C'
% and assume blindly that all features are consistent with the
% first in terms of MATLAB storage classes.
for k = 1:numel(attributeNames)
    dataClass = class(S(1).(attributeNames{k}));
    switch(dataClass)
        
        case 'double'
            fieldType = 'N';
            v = [S.(attributeNames{k})];
            if all(v == 0)
                numRightOfDecimal = 0;
                fieldLength = 2;
            else
                numLeftOfDecimal = ceil(log10(max(abs(v))));
                if all(v == floor(v))
                    numRightOfDecimal = 0;
                    fieldLength = 1 + numLeftOfDecimal;
                else
                    numRightOfDecimal = 6;  % Hard-code for now
                    fieldLength = 1 + numLeftOfDecimal + 1 + numRightOfDecimal;
                end
            end
            if numRightOfDecimal == 0
                fmt = sprintf('%s%dd','%',fieldLength);
            else
                fmt = sprintf('%s%d.%df','%',fieldLength,numRightOfDecimal);
            end
                
        case 'char'
            fieldType = 'C';
            v = char({S.(attributeNames{k})});
            minCharFieldLength = 2;
            fieldLength = max(size(v,2), minCharFieldLength);
            numRightOfDecimal = 0;
            fmt = sprintf('%s%ds','%-',fieldLength);
            
        otherwise
            wid = sprintf('%s:%s:unsupportedDataClass',getcomp,mfilename);
            msg = sprintf('Omitting unsupported data class: %s',dataClass);
            warning(wid,msg);
            continue;
    end
    
    fieldInfo(k).AttributeName = attributeNames{k};
    fieldInfo(k).FieldName = attributeNames{k};
    fieldInfo(k).FieldType = fieldType;
    fieldInfo(k).FieldLength = fieldLength;
    fieldInfo(k).FieldDecimalCount = numRightOfDecimal;
    fieldInfo(k).Format = fmt;
end
