#!/usr/bin/perl

# arma@mit.edu
# Distributed under GPL
# alpha version

$blatant = 0;

srand(time ^ $$);

$ops = join(' ', @ARGV);

print "* Type your zephyr now, end with '.' or ^D\n";

# while they're typing, do a prelim read of the zsigs file

  $/ = "\n\n"; # zsig separator
 
  open(ZSIGS, "$ENV{'HOME'}/.zsigs") || die("No ~/.zsigs file");
  while(<ZSIGS>){
     $_ = substr($_,0,length($_)-5);
     foreach $word (split(' ')) {
        $word =~ s/\W//g; # nuke the non-alphanumeric characters
        $zsig_wordfreq{lc($word)}++;
     }
  }
  close(ZSIGS);

  $/ = "\n";

#while(($w,$num) = each %zsig_wordfreq) {
#  print "Zsig Freq of '$w' is $num.\n" if ($num>10);
#}

# end of prelim zsig file read, start reading their stdin

while(<STDIN>) {
  chomp;
  last if ($_ eq '.');
  push(@zephyr, $_) unless /^;;/;
  if (/^;;;/) {
     
     next;
  }
  foreach $word (split(' ')) {
     $word =~ s/\W//g; # nuke the non-alphanumeric characters
     $weight = &calc_weight($word);
     $zep_num{lc($word)} += $weight if ($weight);
  }
}

print "* Done reading, reading zsigs\n";

($our_zephyr, $our_weight) =
    &read_zsigs(); # creates @zsig_num, @zsig_list based on weights
$our_zephyr =~ s/\'/\'\\\'\'/g;

print "* Zsig picked:\n";

if ($blatant) {

  foreach $w (keys %zep_num) {
    $our_zephyr =~ s/(?i)\b$w\b/\U$w\E/g;
  }

  print $our_zephyr;

  $our_zephyr .= " ($our_weight)";

} else {

  $result_zephyr = $our_zephyr;

  foreach $w (keys %zep_num) {
    $result_zephyr =~ s/(?i)\b$w\b/\U$w\E/g;
  }

  print $result_zephyr;
}

print "\n* writing zephyr (weight $our_weight)\n";

open(ZEPHYR, "|zwrite -n -s '$our_zephyr' $ops");

foreach $line (@zephyr) {
  print ZEPHYR "$line\n";
}

close ZEPHYR;

#while(($w,$num) = each %zep_num) {
#  debug "Freq of '$w' is $num.\n";
#}

# creates @zsig_num, @zsig_list based on weights
sub read_zsigs {
  my ($weight);
  my ($totalweight);
  my ($word); # no pun intended
  my (@words);
  my ($zsig);

  $/ = "\n---\n"; # zsig separator

  open(ZSIGS, "$ENV{'HOME'}/.zsigs") || die("No ~/.zsigs file");
  while(<ZSIGS>){
     $_ = substr($_,0,length($_)-5);
     # check if this zsig is too long
     if ($0 eq "/usr/local/bin/zrs") { # drop it if it's too long
        next if (tr/\n/\n/ > 2); # more than 2 lines
     }
     # now calculate the weight of this zsig
     $weight = 0;
     @words = split(' ');
     foreach $word (@words) {
        $lcword = lc($word);
        $lcword =~ s/\W//g; # nuke the non-alphanumeric characters
        $weight += $zep_num{$lcword} 
                 * &calc_weight($word)
                 / scalar(@words)
                 / $zsig_wordfreq{$lcword}
           if defined $zep_num{$lcword};
     }
     if ($weight != 0) {
       $total_weight += $weight;
       push(@zsig_list, $_);
       push(@zsig_num, $weight);
       debug("Weight for zsig:\n$_\nis: $weight\n");
     }
  }

  $/ = "\n"; # set the separator back to normal
  
  if (!$total_weight) {
      $y = 0;
      open(SIGS, "/home/$ENV{'USER'}/.zsigs")|| open(SIGS, "/mit/$ENV{'USER'}/.zsigs")||  die("No ~/.zsigs file");
      
      while(<SIGS>){
	  if($_ eq "---\n")
	  { $y++; }
	  else
	  { $sig[$y] .= $_; }
      }
      $x = rand($y-1);
      return($sig[$x]);
  }
  # actually pick a zsig
while ($j++ < 50) {
  $i = 0;
  $partial_weight = 0;
  $which = rand($total_weight);
  while($which > $partial_weight) {
    $partial_weight += $zsig_num[$i++];
  }
  $i--;
  last if ($zsig_num[$i]/$total_weight > .01*(50-$j));
    # aim for high correlation
  
}

  print "* Total weight $total_weight, of " . scalar(@zsig_list) . "\n";
#  return($zsig_list[$i], $zsig_num[$i]);
  return($zsig_list[$i], $zsig_num[$i]/$total_weight);

}

sub calc_weight {
  my ($word) = @_; #
  my ($lcword) = lc($word);
  my ($weight) = 100;
 
  $lcword =~ s/\W//g; # nuke the non-alphanumeric characters
  $weight += 150 if ($word ne $lcword);
 
  $weight *= length($word);
 
  return($weight);
 
}

sub debug {

  print "$_" if $opt_v;

}

