#!/usr/bin/perl -w

# African American Civil Rights Timeline from Wikipedia
# Seminar Information Extraction - WS 2013/2014
# Fraser

use strict;

# Global variables
my %mon2num = qw(jan 1  feb 2  mar 3  apr 4  may 5  jun 6  jul 7  aug 8  sep 9  oct 10   nov 11   dec 12);

my $ONETOKEN = "[^ ]+";
my $ONEORTWODIGITS = "[0-9][0-9]?";
my $OPTIONALSPACE = " ?";
my $WEIRDDASH = "–";

my $year;

while (<STDIN>) {
    chomp;

    # Years are easy to detect
    if (/^<p><b>(\d+)<\/b><\/p>$/) {
	$year = $1;
    }
    # Else if we have a bullet, then we need to parse a record
    elsif (s/^<li>//) {

	die "no year defined yet" unless defined($year);

	my $who = guess_who($_);

	$_ = remove_html($_);

	# Multiple entity with with two months, like March 2 to May 3. Also matches March 2-3
	if (s/^($ONETOKEN) ($ONEORTWODIGITS)$OPTIONALSPACE($WEIRDDASH|-|to)$OPTIONALSPACE($ONETOKEN)? ($ONEORTWODIGITS) ($WEIRDDASH|-)$OPTIONALSPACE//) {
	    my $month1 = $1;
	    my $day1 = $2;

	    my $month2;
	    if (defined($4)) { 
		$month2 = $4;
	    }
	    else {
		$month2 = $month1;
	    }
	    my $day2 = $5;

	    my $datestring1 = sprintf("%04d%02d%02d", $year, convert_month($month1), $day1);
	    print "AACRM", " ", $datestring1, " ", "sdate", " ", $who, " ", $_, " ", "\n";

	    my $datestring2 = sprintf("%04d%02d%02d", $year, convert_month($month2), $day2);
	    print "AACRM", " ", $datestring2, " ", "edate", " ", $who, " ", $_, " ", "\n";
	}
	# Single entity, like March 2 -
	elsif (s/^($ONETOKEN) ($ONEORTWODIGITS)$OPTIONALSPACE($WEIRDDASH|-)$OPTIONALSPACE//) {
	    my $month = $1;
	    my $day = $2;
	    my $datestring = sprintf("%04d%02d%02d", $year, convert_month($month), $day);
	    print "AACRM", " ", $datestring, " ", "date", " ", $who, " ", $_, " ", "\n";
	}
	# Single entity, only month, like March -, also handles Summer -
	elsif (s/^($ONETOKEN|All year)$OPTIONALSPACE($WEIRDDASH|-)$OPTIONALSPACE//) {
	    my $month1 = $1;
	    my $month2 = $month1;
	    if ($month1 eq "Summer") {
		$month1 = "June";
		$month2 = "August";
	    }
	    if ($month1 eq "All year") {
		$month1 = "January";
		$month2 = "December";
	    }

	    my $day1 = 1;
	    # Known bug - not all months have 31 days. This won't hurt us (much).
	    my $day2 = 31;

	    my $datestring1 = sprintf("%04d%02d%02d", $year, convert_month($month1), $day1);
	    print "AACRM", " ", $datestring1, " ", "sdate", " ", $who, " ", $_, " ", "\n";

	    my $datestring2 = sprintf("%04d%02d%02d", $year, convert_month($month2), $day2);
	    print "AACRM", " ", $datestring2, " ", "edate", " ", $who, " ", $_, " ", "\n";
	}
	else {
	    # Bullets that we can't parse are printed to STDERR
	    warn "SKIPPING BULLET: |$_|";
	}
    }
    # If it isn't a bullet, it is not interesting
    else {
	#warn "SKIPPING TEXT: |$_|";
    }
}

# We guess the first entity who has a Wikipedia page. This often works well, but not always
sub guess_who {
    my $line = shift;
    my $who = "UNKNOWN";

    # match starting HREF
    if ($line =~ s/.*?<A .+?>//i) {

	# match ending HREF and delete all following text
	if ($line =~ s/<\/A>.*$//i) {

	    # what is left over is our guess
	    $line =~ s/ /_/g;
	    $who = $line;
	}
    }

    # Annoying span junk...
    if ($who =~ /<span/) {
	$who = "UNKNOWN";
    }
    
    return $who;
}

# Nicely behaved HTML is easy to remove. Don't try this on random web pages, it is too simple.
sub remove_html {
    my $line = shift;
    $line =~ s/<.+?>//g;
    return $line;
}

sub convert_month {
    my $month = shift;
    my $simplemon = lc substr($month, 0, 3);

    die "month $month, reduced to $simplemon, not allowed" unless exists $mon2num{$simplemon};

    return $mon2num{$simplemon};
}
