#!/usr/local/bin/perl5
#
# $Id: report.pl,v 1.13 2009/02/01 04:49:12 winter Exp $

use Data::Dumper;
use HTML::Entities;
use Cfg;

sub
strip_html {
	$_ = decode_entities(shift);

	$_ =~ s/\s*\<[^\>]+\>\s*//g;
	$_ =~ s/[\.\!\?\,]+//g;	# errant punctuation
	return $_;
}

sub
extract_number {
	$_ = strip_html(shift);

	if (/=.*[[:digit:]]+/) {
		(undef, $_) = split(/=/)
	}

	if (/([[:digit:]]+)/) {
		$i = int($1);
		if ($i > 0 && $i < 2001) {
			return int($1);
		}
	}
#	if (/one/) {
#		return 1;
#	}
	return undef;
}

sub
detect_comments {
	$_ = shift;

	$_ =~ s/Posted Via AR15\.Com Mobile//g;
	$_ =~ s/<BR>//g;	# hard breaks
	$_ =~ s///g;		# hard returns
	$_ =~ s/\s*<\/*(a|b|font|i|span|div|img)[^\>]*>\s*//g;	# Tags
	$_ =~ s/:\)//g;		# emoticons
	$_ =~ s/\[.*\]//g;	# emoticons
	$_ =~ s/[\.!?,]+//g;	# errant punctuation
	$_ =~ s/\s+$//g;	# trailing whitespace
	$_ =~ s/^\s+//g;	# leading whitespace
	$_ =~ s/one/1/g;

	return grep(/[^[:digit:]]+/, $_) ? 1 : 0;
}

while (<>) {
	chop;
	($page, $post, $pdate, $edate, $poster, $plevel, $message) = split(/\t/);
	next if ($post == 0);	# Skip the OP.

	$number = extract_number($message);
	$comments = detect_comments($message);
	$edited = $edate != 0 ? 1 : 0;

	push @{ $hash{$poster} },
		{
			page => int($page),
			post => int($post),
			level => $plevel,
			post_date => int($pdate),
			edit_date => int($edate),
			edited => $edited,
			comments => $comments,
			message => $message,
			number => $number
		};
	# Record number, if present
	if (defined($number)) {
		push @{ $numbers{ $number } }, $poster;
	}
}

%posts = (
	total		=> 0,
	valid		=> 0,
	dq		=> 0,
	nonumber	=> 0,
	nonteam		=> 0,
	comments	=> 0,
	multiple	=> 0,
	edited		=> 0
);

foreach $poster ( sort {
			$hash{$a}[0]->{page} <=> $hash{$b}[0]->{page}
					     ||
			$hash{$a}[0]->{post} <=> $hash{$b}[0]->{post}
		} keys %hash ) {
	$multiple = 0;
	foreach $post ( @{ $hash{$poster} } ) {
		if ($#{ $hash{$poster} }) {
			if ($post->{message} ne $hash{$poster}[0]->{message}) {
				$post->{multiple} = $#{ $hash{$poster} };
				$multiple++;
			}
		} else {
			$post->{multiple} = 0;
		}

		$posts{total}++;

		# Record stats
# XXX: nonteam
#		$posts{nonteam}++  if $post->{level} eq 'Member';
		$posts{comments}++ if $post->{comments};
		$posts{multiple}++ if $post->{multiple};
		$posts{edited}++   if $post->{edited};
		$posts{nonumber}++ if !defined($post->{number});

#		# Record number, if present
#		if (defined($post->{number})) {
#			push @{ $numbers{ $post->{number} } }, $poster;
#		}

		# Tally valid/dq posts.
# XXX nonteam
#		    $post->{level} ne 'Member' &&
		if (!$post->{comments} &&
		    !$post->{edited} &&
		    !$post->{multiple} &&
		    defined($post->{number})) {
			$posts{valid}++;
		} else {
			$posts{dq}++;
		}
	}
	if ($multiple > 0) {
		$hash{$poster}[0]->{multiple} = $multiple;
	}
}

@histogram = ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
foreach $i ( keys %numbers ) {
	$histogram[ scalar(@{$numbers{"$i"}}) ]++;
}
$histogram[0] = 2000 - scalar(keys %numbers);

if ($posts{total} != 0) {
	$pct_dq = sprintf("%.2f", ($posts{dq} / $posts{total}) * 100.0);
} else {
	$pct_dq = "0";
}
$posters = scalar(keys %hash);
$picked = scalar(keys %numbers);
$t = encode_entities($threadURL);

print <<__EOF__;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
	<title>${title} - Report</title>
	<link rel="stylesheet" type="text/css" href="../contest.css" />
	<!-- <script src="sorttable.js"></script> -->
</head>
<body>
<h2><a href="${t}">${title}</a> - Report</h2>
<!--
<p>
<h2>
Winning number is: <br />
Winning poster is: <br />
</h2>
</p>
<p>
<a href="http://www.ar15.com/forums/topic.html?b=2&f=219&t=XXXXXX">See here for contest thread.</a>
</p>
-->
<p>
Data for last whole page only.<br />
Update checks every 10 minutes.<br />
Last update: \@DATE\@<br />
Last page: \@PAGE\@<br />
<br />
See the raw data <a href="raw-data.html">here</a>.
</p>
<img src="anim.gif" />
<p>
(Hover mouse over table cell to show number.)
</p>
<table class="pick" cellpadding="0" cellspacing="0">
	<tr>
		<th>&nbsp;</th>
__EOF__

for $i (1 .. 10) {
	$t = ($i == 10) ? 0 : $i;
	print "\t\t<th colspan=\"10\">" . $t . "</th>\n";
}

print "\t</tr>\n";
print "\t<tr>\n\t\t<th>0</th>\n";
$nl = 0;
for $i (1 .. 2000) {
	if ($nl) {
		$nl = 0;
		print "\t</tr>\n";
		print "\t<tr>\n\t\t<th>" . ($i - 1) / 100 . "</th>\n";
	}
	$c = scalar(@{$numbers{"$i"}}) || 0;
	if ($c > 5) { $c = 6; }
	print "\t\t<td title=\"$i\" class=\"c$c\">&nbsp;</td>\n";

	if ($i % 100 == 0) { $nl = 1; }
}
print "\t</tr>\n";
print "</table>\n";

print <<__EOF__;
<table class="statistics" cellpadding="0" cellspacing="0">
	<caption>Statistics</caption>
	<tr>
		<th>Count</th>
		<th>Category</th>
	</tr>
	<tr>
		<td class="l">$posts{total}</td>
		<td class="l">total posts.</td>
	</tr>
	<tr>
		<td class="d">$posts{valid}</td>
		<td class="d">valid posts</td>
	</tr>
	<tr>
		<td class="l">$posts{dq}</td>
		<td class="l">disqualified&nbsp;posts&nbsp;(${pct_dq}%)</td>
	</tr>
	<tr>
		<td class="d">$posts{nonumber}</td>
		<td class="d">no number posts</td>
	</tr>
	<tr>
		<td class="l">$posts{nonteam}</td>
		<td class="l">nonteam posts</td>
	</tr>
	<tr>
		<td class="d">$posts{comments}</td>
		<td class="d">commented posts</td>
	</tr>
	<tr>
		<td class="l">$posts{multiple}</td>
		<td class="l">multiple posts</td>
	</tr>
	<tr>
		<td class="d">$posts{edited}</td>
		<td class="d">edited posts</td>
	</tr>
	<tr>
		<td class="l">${posters}</td>
		<td class="l">unique posters.</td>
	</tr>
	<tr>
		<td class="d">${picked}</td>
		<td class="d">Numbers picked</td>
	</tr>
</table>

<table class="histogram" cellpadding="0" cellspacing="0">
	<caption>Histogram</caption>
	<tr>
		<th>Color</th>
		<th>Picks</th>
		<th>Count</th>
	</tr>
__EOF__

for $i ( 0 .. $#histogram ) {
	$c = ($i % 2) ? "d" : "l";
	$t = ($i > 5) ? 6 : $i;

print <<__EOF__;
	<tr>
		<td class="c${t}">&nbsp;</td>
		<td class="$c">$i</td>
		<td class="$c">$histogram[$i]</td>
	</tr>
__EOF__
}

print <<__EOF__;
</table>

<table class="DQnonumber" cellpadding="0" cellspacing="0">
	<caption>$posts{nonumber} Posts with no or invalid number</caption>
	<tr>
		<th>Poster</th>
		<th>Page</th>
		<th>Post</th>
		<th>Membership</th>
		<th>Message</th>
	</tr>
__EOF__

$i = 1;
foreach $poster ( sort {
			$hash{$a}[0]->{page} <=> $hash{$b}[0]->{page}
					     ||
			$hash{$a}[0]->{post} <=> $hash{$b}[0]->{post}
		} keys %hash ) {

	foreach $post ( @{ $hash{$poster} } ) {
		next if (defined($post->{number}));

		$c = ($i++ % 2) ? "l" : "d";
		$t = encode_entities($post->{message}) || "&nbsp;";
	
print <<__EOF__;
	<tr>
		<td class="$c">$poster</td>
		<td class="$c">$post->{page}</td>
		<td class="$c">$post->{post}</td>
		<td class="$c">$post->{level}</td>
		<td class="$c">$t</td>
	</tr>
__EOF__
	}
}

print <<__EOF__;
</table>
<table class="DQnonteam" cellpadding="0" cellspacing="0">
	<caption>$posts{nonteam} Non Team Member posts</caption>
	<tr>
		<th>Poster</th>
		<th>Page</th>
		<th>Post</th>
		<th>Number</th>
		<th>Membership</th>
	</tr>
__EOF__

$i = 1;
foreach $poster ( sort {
			$hash{$a}[0]->{page} <=> $hash{$b}[0]->{page}
					     ||
			$hash{$a}[0]->{post} <=> $hash{$b}[0]->{post}
		} keys %hash ) {

	foreach $post ( @{ $hash{$poster} } ) {
		next;	# XXX nonteam
		next if $post->{level} ne 'Member';

		$c = ($i++ % 2) ? "l" : "d";
		$n = $post->{number} || "&nbsp;";
	
print <<__EOF__;
	<tr>
		<td class="$c">$poster</td>
		<td class="$c">$post->{page}</td>
		<td class="$c">$post->{post}</td>
		<td class="$c">$n</td>
		<td class="$c">$post->{level}</td>
	</tr>
__EOF__
	}
}

print <<__EOF__;
</table>

<table class="DQcomments" cellpadding="0" cellspacing="0">
	<caption>${posts{comments}} Posts containing more than a number</caption>
	<tr>
		<th>Poster</th>
		<th>Page</th>
		<th>Post</th>
		<th>Membership</th>
		<th>Number</th>
		<th>Message</th>
		<th>Raw text</th>
	</tr>
__EOF__

$i = 1;
foreach $poster ( sort {
			$hash{$a}[0]->{page} <=> $hash{$b}[0]->{page}
					     ||
			$hash{$a}[0]->{post} <=> $hash{$b}[0]->{post}
		} keys %hash ) {

	foreach $post ( @{ $hash{$poster} } ) {
		next if !$post->{comments};

		$c = ($i++ % 2) ? "l" : "d";
		$n = $post->{number} || "&nbsp;";
		$rt = encode_entities($post->{message}) || "&nbsp;";
		$t = $post->{message} || "&nbsp;";
print <<__EOF__;
	<tr>
		<td class="$c">$poster</td>
		<td class="$c">$post->{page}</td>
		<td class="$c">$post->{post}</td>
		<td class="$c">$post->{level}</td>
		<td class="$c">$n</td>
		<td class="$c">$t</td>
		<td class="$c">$rt</td>
	</tr>
__EOF__
	}
}

print <<__EOF__;
</table>

<table class="DQmultiple" cellpadding="0" cellspacing="0">
	<caption>${posts{multiple}} Multiple posts</caption>
	<tr>
		<th>Poster</th>
		<th>Page</th>
		<th>Post</th>
		<th>Number</th>
		<th>Membership</th>
	</tr>
__EOF__

$i = 1;
foreach $poster ( sort {
			$hash{$a}[0]->{page} <=> $hash{$b}[0]->{page}
					     ||
			$hash{$a}[0]->{post} <=> $hash{$b}[0]->{post}
		} keys %hash ) {

	next if !$hash{$poster}[0]->{multiple};

	foreach $post ( @{ $hash{$poster} } ) {
		$c = ($i++ % 2) ? "l" : "d";
		$n = $post->{number} || "&nbsp;";

print <<__EOF__;
	<tr>
		<td class="$c">$poster</td>
		<td class="$c">$post->{page}</td>
		<td class="$c">$post->{post}</td>
		<td class="$c">$n</td>
		<td class="$c">$post->{level}</td>
	</tr>
__EOF__
	}
}

print <<__EOF__;
</table>

<table class="DQedited" cellpadding="0" cellspacing="0">
	<caption>${posts{edited}} Edited posts</caption>
	<tr>
		<th>Poster</th>
		<th>Page</th>
		<th>Post</th>
		<th>Number</th>
		<th>Membership</th>
	</tr>
__EOF__

$i = 1;
foreach $poster ( sort {
			$hash{$a}[0]->{page} <=> $hash{$b}[0]->{page}
					     ||
			$hash{$a}[0]->{post} <=> $hash{$b}[0]->{post}
		} keys %hash ) {

	foreach $post ( @{ $hash{$poster} } ) {
		next if !$post->{edited};

		$c = ($i++ % 2) ? "l" : "d";
		$n = $post->{number} || "&nbsp;";

print <<__EOF__;
	<tr>
		<td class="$c">$poster</td>
		<td class="$c">$post->{page}</td>
		<td class="$c">$post->{post}</td>
		<td class="$c">$n</td>
		<td class="$c">$post->{level}</td>
	</tr>
__EOF__
	}
}

print <<__EOF__;
</table>

<table class="entries" cellpadding="0" cellspacing="0">
	<caption>$posts{valid} Entries</caption>
	<tr>
		<th>Number</th>
		<th>Picks</th>
		<th>Posters (valid, <span class="DQmultipleText">multiple</span>, <span class="DQeditedText">edited</span>, <span class="DQcommentText">comments</span>, <span class="DQnonteamText">non-team</span>)</th>
	</tr>
__EOF__

for $i ( 1 .. 2000 ) {
	$c = ($i % 2) ? "l" : "d";
	$n = scalar(@{$numbers{"$i"}}) || 0;
	undef @list;
	foreach $poster ( @{ $numbers{"$i"} } ) {
		$_ = $hash{$poster}[0];
		if ($_->{multiple}) {
			push @list, "<span class=\"DQmultipleText\">$poster</span>";
			$n--;
# XXX nonteam
#		} elsif ($_->{level} eq 'Member') {
#			push @list, "<span class=\"DQnonteamText\">$poster</span>";
#			$n--;
		} elsif ($_->{edited}) {
			push @list, "<span class=\"DQeditedText\">$poster</span>";
			$n--;
		} elsif ($_->{comments}) {
			push @list, "<span class=\"DQcommentText\">$poster</span>";
			$n--;
		} else {
			push @list, $poster;
		}
	}
	$t = join(', ', @list) || "&nbsp;";

print <<__EOF__;
	<tr>
		<td class="$c">$i</td>
		<td class="$c">$n</td>
		<td class="$c">$t</td>
	</tr>
__EOF__
}

print <<__EOF__;
</table>
</body>
</html>
__EOF__
