#!Perl
# Drop the Apple CD Audio Player file "CD Remote Programs" (probably in
#  your System folder) on me, and I'll output a list (alpha-sorted by
#  title) of the CDs (and their tracks) in the database.
#
# If you don't drop the file on me, I'll look for it anyway in your
#  Preferences folder!
#
# sburke@netadventure.net 1998-03-20

use Mac::Memory;
use Mac::Resources;
use Mac::Files;    # for the FindFolder call

#drop CD Remote Programs on me
$prog = $ARGV[0] || 
   FindFolder(kOnSystemDisk, kPreferencesFolderType)
   . ':CD Remote Programs';
die "$prog doesn't exist\n" unless $prog and -f $prog;

@CDs = get_CDs($prog);

foreach ( sort { lc(${ $a }[0]) cmp lc(${ $b }[0]) } (@CDs) ) {
  #Spit 'em out in alphabetical order of title
  @tracks = @{$_};
  $title = shift(@tracks);

  print join("\n   ", uc($title), @tracks), "\n\n";
}

exit;

#--------------------------------------------------------------------------

sub get_CDs {
  my $SPEC = $_[0];
  my $TYPE = "STR#";
  my @tracks = (); # to be a list of lists

  return undef unless -f $SPEC;
  my $sp =  FSpOpenResFile($SPEC, 1); # 1 = read-only
  die "Nope!  Can't read the resources of $sp" unless defined($sp);

  my $items  = Count1Resources($TYPE);

  foreach $offset ( 1 .. $items ) { # the lazy way to do a for()
    $HANDLE = Get1IndResource($TYPE, $offset);
    push(@tracks, [ &parse_str_list( $HANDLE->get ) ] );
  }
  CloseResFile $sp;
  return @tracks;
}

#--------------------------------------------------------------------------

sub parse_str_list {
  # Input: the contents of a STR# resource.
  # Output:  a list of that resource's contents, in order.
  # (Note that the first element is element #0, in MacPerl style --
  #  even tho Mac practice would be to refer to this as string #1)

  my(@out) = ();
  my $length;
  my $point = 2;
  # Bytes 0 and 1 specify the number of items here.
  # We'll find out anyhoo, so just jump past it and start
  #  at byte 0
  while($point < length( $_[0] )) {
    $length = unpack('C', substr( $_[0] , $point, 1));
    ++$point;
    push(@out, substr( $_[0] , $point, $length));
    $point += $length;
  }
  return @out;
}

#--------------------------------------------------------------------------
__END__
