#!/usr/local/bin/perl --

##########################################################################
##
##   inndelay.pl: Delay between post and reception of usenet articles. 
##
##  version: 1.0.0
##  Date: 04-03-97
##  Copyright (c) 1997, Fabien TASSIN (tassin@eerie.fr).
##
##########################################################################
##
## ABSOLUTELY NO WARRANTY WITH THIS PACKAGE. USE IT AT YOUR OWN RISKS.
##
## Usage: send a part of your history file to inndelay.pl
##
##        tail -10000 /var/news/etc/history | inndelay.pl
##     or
##        inndelay.pl history_extract
##
## This will produce a GIF file (see $out below)
##
## Notes : You need the Perl graphic library GD.pm (1.14 or more)
##         GD is available on all good CPAN ftp sites :
##             [CPAN_DIR]/authors/id/LDS/GD-1.14.tar.gz
##           or directly to :
##             http://www-genome.wi.mit.edu/pub/software/WWW/GD.html
##
## Report : please report bugs directly to the author.
##          Be sure your are using the latest version of this script.
##          (check ftp://ftp.eerie.fr/pub/usenet/inndelay/)
##
##########################################################################

# Name of the graph
$out = "./inndelay.gif";

###############################################
## THERE'S NOTHING TO CHANGE AFTER THIS LINE ##
###############################################
 
$version = "1.0.0";

BEGIN
{
  eval "use GD;";
  $::HAVE_GD = ($@ eq "");
};
 
unless ($HAVE_GD)
{
  printf STDERR <<EOF;
ERROR: can't make graph.
 
You need the Perl graphic library GD.pm (1.14 or more)
GD is available on all CPAN mirrors, e.g.:
    ftp://ftp.eerie.fr/pub/perl/CPAN/authors/id/LDS/GD-1.14.tar.gz
or directly to :
    http://www-genome.wi.mit.edu/pub/software/WWW/GD.html
EOF
  #'
  exit (1);
}

# Size of the graph
($xmax, $ymax) = (640, 240);

$prec = 0.01;
while (<>)
{
  $max++;
  unless (/^<[^>]+>\s+(\d+)\~.*[^\~]+\~(\d+)\s+\S+/)
  {
    $cancel++;
    next;
  }
  $d = $1 - $2;
  if ($d < 0)
  {
    $future++;
    next;
  }
  if (($d == 0) || (/\scontrol/))
  {
    $cancel++;
    next;
  }

  $done++;
  $l = sprintf "%.2f", log ($d) / log (10); # look at $prec
  $ll{$l}++;

  # if ($k == 5)
  # {
  #   print "\n";
  #   $k = 0;
  # }
  # $k++;
  # printf "%8d (%4.2f)", $d, $l;
}

# print "\n";
# printf "Posted in the future: %10d %7.1f%%\n", $future, $future / $max * 100;
# printf "Cancelled or Expired: %10d %7.1f%%\n", $cancel, $cancel / $max * 100;
# printf "Processed:            %10d %7.1f%%\n", $done, $done / $max * 100;
# printf "Total:                %10d articles\n", $max;

# $k = 0;
$min_x = 1000;
$max_x = 0;
$max_y = 0;
foreach $v (sort (keys (%ll)))
{
  $min_x = $v if ($min_x > $v);
  $max_x = $v if ($max_x < $v);
  $max_y = $ll{"$v"} if ($max_y < $ll{"$v"});

  # if ($k == 4)
  # {
  #   print "\n";
  #   $k = 0;
  # }
  # $k++;
  # printf "%s => %3d   ", &trans($v), $ll{"$v"};

}
$c = sprintf "%.1f%%", $max_y / $done * 100;

($ml, $mr, $mt, $mb) = (gdSmallFont->width * length ("$c") + 12, 30,
			gdSmallFont->height * 2 + 12, 40);

$image = new GD::Image ($xmax, $ymax);

$white = $image->colorAllocate (255, 255, 255);
$black = $image->colorAllocate (  0,   0,   0);
$blue  = $image->colorAllocate (  0,   0, 255);

$s = "Delay between post and reception";
$image->string (gdMediumBoldFont,
		($xmax - length ($s) * gdMediumBoldFont->width) / 2,
		$ymax - gdMediumBoldFont->height - 5, $s, $black);
$image->string (gdSmallFont, $ml, 5, 
		sprintf ("Number of articles: %10d", $max), $black);
$image->string (gdSmallFont, $ml, 7 + gdSmallFont->height, 
		sprintf ("Processed:          %10d (%.1f%%)",
		$done, $done / $max * 100), $black);
$image->string (gdSmallFont, $xmax / 2, 5, 
		sprintf ("Posted in the future: %10d (%.1f%%)",
			 $future, $future / $max * 100), $black);
$image->string (gdSmallFont, $xmax / 2, 7 + gdSmallFont->height, 
		sprintf ("Cancelled or Expired: %10d (%.1f%%)",
                $cancel, $cancel / $max * 100), $black);
$image->rectangle ($ml, $mt, $xmax - $mr, $ymax - $mb, $black);
$image->line ($ml - 3, $ymax - $mb, $ml, $ymax - $mb, $black);
$image->string (gdSmallFont, $ml - length ("0%") * gdSmallFont->width - 5,
		$ymax - $mb - gdSmallFont->height / 2, "0%", $black);
$image->line ($ml - 3, $mt, $ml, $mt, $black);
for ($i = 1; $i < 4; $i++)
{
  $image->dashedLine ($ml - 3, $mt + ($ymax - $mt - $mb) * $i / 4,
		      $xmax - $mr, $mt + ($ymax - $mt - $mb) * $i / 4, $black);

}
$image->string (gdSmallFont, $ml - length ("$c") * gdSmallFont->width - 5,
		$mt - gdSmallFont->height / 2, "$c", $black);

$rx = ($xmax - $mr - $ml) / ($max_x - $min_x + $prec);
$ry = ($ymax - $mt - $mb) / $max_y;
$i = 0;
foreach $v (sort (keys (%ll)))
{
  $image->filledRectangle ($ml + ($v - $min_x) * $rx,
			   $ymax - $mb - $ll{$v} * $ry,
			   $ml + ($v - $min_x + $prec) * $rx,
			   $ymax - $mb,
			   $blue);
}

# Graduations
@a = (1, 3, 7, 15, 30,		# seconds
      60, 180, 420, 900, 1800,	# minutes
      3600, 10800, 43200,	# hours
      86400, 259200, 864000);	# days

# Labels
@b = ("1s", "3s", "7s", "15s", "30s",
      "1mn", "3mn", "7mn", "15mn", "30mn",
      "1h", "3h", "12h",
      "1day", "3days", "10days");

for ($i = 0; $i <= $#a; $i++)
{
  $v = $a[$i];
  next if (log ($v) / log (10) < $min_x);
  next if (log ($v) / log (10) > $max_x);
  $image->line ($ml + (log ($v) / log (10) - $min_x) * $rx, $ymax - $mb,
		$ml + (log ($v) / log (10) - $min_x) * $rx, $ymax - $mb + 5,
		$black);
  $image->string (gdSmallFont, $ml + (log ($v) / log (10) - $min_x) * $rx
		  - length ("$b[$i]") * gdSmallFont->width / 2,
		  $ymax - $mb + 7, $b[$i], $black);
}
open (IMG, "> $out") || die "can open \"$out\": $!\n";
print IMG $image->gif;
close (IMG);

sub trans
{
  my $s = shift;

  $s = 10 ** $s;
  my $t = sprintf "%d", $s / 3600 / 24;
  $s -= $t * 3600 * 24;
  my $date .= $t . "+";
  $t = sprintf "%d", $s / 3600;
  $s -= $t * 3600;
  $date .= sprintf ("%02d", $t) . ":";
  $t = sprintf "%d", $s / 60;
  $s -= $t * 60;
  $date .= sprintf ("%02d", $t) . ":" . sprintf ("%02d", $s);
  return $date;
}