function [physnam, tdatex, rc] = mfs_imp_physical(msg, fid, tdata)

# usage: [physnam, tdatex, rc] = mfs_imp_physical(msg, fid, tdata)
#
# Input  msg       File handle of message file 
#        fid       Input file handle
#        tdata     Translation data
#
# Output physnam   Structure with physical group names
#        tdatex    Translation data
#        rc        Return code: 0 = no errors, 1 = errors found
#
# Fields of the structure physnam:
#
#    physnam.names  Cell array with physical group names
#                   (sorted according to physical group identifiers)
#    physnam.ids    Array with physical group identifiers
#    physnam.dim    Array with physical group dimension
#
# The function reads the physical groups from the input file. For physical
# groups for which no translation data are defined groups of type "ignore"
# are added to the translation data.
#
# -----------------------------------------------------------------------------

  tdatex  = tdata;
  physnam = 0;
  rc      = 0;

# Check arguments

  if (nargin != 3 || nargout != 3)
     print_usage();
  endif

# Header record

  line = fgetl(fid);
  if (! strcmp(line, "$PhysicalNames"))
     fprintf(msg, "*E* $PhysicalNames expected but not found\n");
     rc = 1;
     return;
  endif

# Number of physical groups

  nofnames = fscanf(fid, "%d", 1);

# Physical groups

  ids   = zeros(nofnames, 1);
  dim   = zeros(nofnames, 1);
  names = cell(nofnames, 1);

  for n = 1 : nofnames
      [dim(n), ids(n), name] = fscanf(fid, "%d %d %s", "C");
      names{n} = substr(name, 2, -1); % remove " at beginning and end
  endfor

  [ids, idx] = sort(ids);
  names = names(idx);
  dim   = dim(idx);

# End record

  line = fgetl(fid);
  if (! strcmp(line, "$EndPhysicalNames"))
     fprintf(msg, "*E* $EndPhysicalNames expected but not found\n");
     rc = 1;
     return;
  endif

# Check if all groups in the translation data are contained in the input file

  fields = fieldnames(tdata);
  ixtype = strcmp("type", fields) + strcmp("subtype", fields);
  ixtype = ixtype + strcmp("damping", fields);
  igroup = find(ixtype == 0);
  ngroup = length(igroup);
  groups = fields(igroup);

  if (ngroup > nofnames)
     fprintf(msg, "*E* Number of groups (%2d) exceeds ", ngroup);
     fprintf(msg, "number of physical groups (%2d)\n", nofnames);
     rc = 1;
     return;
  endif
  
  for n = 1 : ngroup
      if (! sum(strcmp(groups{n}, names)))
         fprintf(msg, "*E* Group %s not found in input file\n", groups{n});
         rc = 1;
      endif
  endfor

  if (rc) return; endif

# Build groups with type "ignore" for physical groups without translation data

  ignore = struct("type", "ignore");

  for n = 1 : nofnames
      if (! isfield(tdata, names{n}))
         tdatex = setfield(tdatex, names{n}, ignore);
      endif
  endfor

# Print information on physical groups

  fprintf(msg, "  Physical Group                      Type\n");
  fprintf(msg, "  ------------------------------------------------\n");

  for n = 1 : nofnames
      group = getfield(tdatex, names{n});
      fprintf(msg, "  %-32s    %-s\n", names{n}, group.type);
  endfor

  fprintf(msg, "\n");
  
# Build the output structure

  physnam = struct("names", {names}, "dim", dim, "ids", ids);

endfunction
