#!/afs/athena/contrib/perl5/p -w

use IO::File;
use strict;

print STDERR "Reading playerlist...\n";

my ($script, $data) =
  split_playerlist(
	read_playerlist('/mit/terror/LaTeX/Central/playerlist.tex') );

print STDERR "Reading apps data...\n";

my ($apps) = read_apps('/mit/terror/Admin/all_apps');

print STDERR "Cross-referencing apps...\n";

my ($filled) = xref_apps($data, $apps);

print STDERR "Writing playerlist...\n";

print_playerlist('/mit/terror/LaTeX/Central/playerlist.new',
		 $script, sort_players($filled));


sub read_playerlist {
  my ($fname) = @_;

  my $IN = new IO::File $fname, 'r'
    or die "Can't open '$fname' for reading: $!\n";
  # paragraph mode
  $IN->input_record_separator('');

  <$IN>;
}

sub split_playerlist {
  my (@chunks) = @_;

  my (@script, @chars);

 CHUNK:
  while (1) {
    # collect fixed header/footer/inner
    my($collect) = '';

    while (@chunks && ($chunks[0] !~ /^\{\w/s)) {
      $collect .= shift(@chunks);
    }
    push(@script, $collect);

    last CHUNK unless @chunks;

    # collect player entries
    my ($nchars) = 0;

    while (@chunks && ($chunks[0] =~ /^\{\w/s)) {
      push(@chars, shift(@chunks));
      $nchars++;
    }
    push(@script, $nchars);

    last CHUNK unless @chunks;
  }

  (\@script, \@chars);
}

sub print_playerlist {
  my ($fname, $script, $data) = @_;

  my $OUT = new IO::File $fname, 'w'
    or die "Can't open '$fname' for writing: $!\n";

 SCRIPT:
  while (1) {
    # fixed text
    $OUT->print(shift @$script);
    last SCRIPT unless @$script;

    # entries
    my $howmany = shift @$script;
    while ($howmany > 0) {
      die "internal error: no data" unless @$data;
      $OUT->print(shift @$data);
      $howmany--;
    }
  }

  die "internal error: extra data" if @$data;
}

sub sort_players {
  my ($entries) = @_;

  my (%index) = map( (player_last_name($_), $_), @$entries );
  [ @index{sort keys %index} ];
}

sub player_last_name {
  my @elem = split /\s+/, player_name(@_);
  local($_) = pop @elem;
  s/^d\'//;
  $_ . join(' ', '', @elem);
}

sub player_name {
  my @parts = split /\s*\&\s*/, $_[0];
  local($_) = $parts[0];
  s/\\.//g;  s/{//g;  s/}//g;  s/\(.*\)//g;  s/^\s+//;  s/\s+$//;
  $_;
}

sub read_apps {
  my ($fname) = @_;

  my $APPS = new IO::File $fname, 'r'
    or die "Can't open '$fname' for reading: $!\n";
  $APPS->input_record_separator("\n");


  my %app;

 PLAYER:
  while (<$APPS>) {
    if (/Name:/) {
      my ($who) = $';
      $who .= $_ while defined ($_ = <$APPS>) and !/Email Address:/i;
      die "internal kaboom" if length($who) > 100;
      $who =~ s/^\s+//;  $who =~ s/\s+$//;  $who =~ s/\s+/ /;
      next PLAYER unless defined $_;

      /Email address:/i;
      my ($email) = $';
      $email .= $_ while defined ($_ = <$APPS>) and !/Phone:/i;
      die "internal kaboom" if length($email) > 100;
      $email =~ s/^\s+//;  $email =~ s/\s+$//;  $email =~ s/\s+/ /;
      next PLAYER unless defined $_;

      /Phone:/i;
      my ($phone) = $';
      $phone .= $_ while defined ($_ = <$APPS>) and !/Address:/i;
      die "internal kaboom" if length($phone) > 100;
      $phone =~ s/^\s+//;  $phone =~ s/\s+$//;  $phone =~ s/\s+/ /;
      next PLAYER unless defined $_;

      /Address:/i;
      my ($addr) = $';
      $addr .= $_ while defined ($_ = <$APPS>) and !/^Hours during/i;
      die "internal kaboom" if length($addr) > 100;
      $addr =~ s/^\s+//;  $addr =~ s/\s+$//;  $addr =~ s/\s+/ /;
      next PLAYER unless defined $_;

      my ($hours) = '';
      $hours = $' if /:/;
      $hours .= $_ while defined ($_ = <$APPS>) and !/^Hours during/i;
      die "internal kaboom" if length($hours) > 100;
      $hours =~ s/^\s+//;  $hours =~ s/\s+$//;  $hours =~ s/\s+/ /;
      next PLAYER unless defined $_;

      my @data = ($email,$phone,$addr,$hours);
      print "$who: @data\n";
    }
  }
}

sub xref_apps { $_[0] }
