#!/usr/bin/perl -w

use strict;
use warnings;

use Date::Manip;
use Math::Round;

my $datetime; 	# Stores date and time pulled from log
my $entry;			# Stores the log entry for processing
my $action;			# Stores the action for processing (this will be the key to the
								#   hash).
my $time;				# the $datetime converted to UNIX timestamp
my %begin;			# Data structure for storing the beginning of a time frame
my %end;				# Data structure for storing the end of a time frame
my %ind;				# Data structure for storing individual timecards
my %misc;				# Data structure for storing miscellaneous (<0.25hrs) timecards

my ($bc,$ec); # variables for determining if we have a complete set.

while(<>) {
	if(/^\s*$/) {  # If current line is an empty string, skip to next line
		next;
	}
	chomp;
	($datetime,$entry) = split /:\s{1,2}/;
	#print STDERR "$datetime:  $entry\n";
	$time = UnixDate($datetime, "%s");
	#print STDERR "$time:  $entry\n";
	if($entry =~ /^Begin/) {
#print STDERR "DEBUG:  Writing an BEGIN action\n";
#print STDERR "$time:  ";
		$action = $entry;
		$action =~ s/^Begin\s+(.+)\s*/$1/;
		$action =~ s/\s+$//;  # trim off any whitespace at the end
#print STDERR "$action\n";
		push(@{$begin{$action}},$time);
	}
	if($entry =~ /^End/) {
#print STDERR "DEBUG:  Writing an END action\n";
#print STDERR "$time:  ";
		$action = $entry;
		$action =~ s/^End\s+(.+)\s*/$1/;
		$action =~ s/\s+$//;  # trim off any whitespace at the end
#print STDERR "$action\n";
		push(@{$end{$action}},$time);
	}
}

# We're here, begin processing

my $act;
my $gtot = 0;
foreach $act (sort keys %begin) {  # For every activity we started.
	# error checking
	$bc = 0;
	$ec = 0;
	$bc = @{$begin{$act}}; # or die "Activity \"$act\" is incomplete.  Missing Begin.\n";
#print STDERR "$act\n";
	$ec = @{$end{$act}}; # or die "Activity \"$act\" is incomplete.  Missing End.\n";

#print STDERR "DEBUG:  \"$act\" bc=$bc,ec=$ec\n";

	if(($bc - $ec) > 1) {
		# haven't logged more than one closing time
#		print STDERR "Activity \"$act\" is incomplete.  Missing multiple Ends.\n";
		exit 2;
	} elsif($bc > $ec) {  # should be exactly one greater
#		print STDERR "Activity \"$act\" is incomplete.  Missing one End.  Removing last from array.\n";
		pop(@{$begin{$act}});
		# GRATUITOUS USE OF GOTO HERE!
		goto THERE;
		# END GRATUITOUS USE OF GOTO HERE!
	} elsif($ec > $bc) {
		# have missed a begin time
#		print STDERR "Activity \"$act\" is incomplete.  Missing Begin.\n";
		exit 1;
	} else {

THERE:
		my $sum = 0;
		# DOIT
		while(@{$begin{$act}} && @{$end{$act}}) {
			my $beg = shift @{$begin{$act}};
			my $en  = shift @{$end{$act}}; 
			$sum += $en - $beg;
		}
		
		#printf ("\"$act\": %10ds %3.2fhr\n", $sum, ($sum / 3600 >= 0.25)?nearest(0.25, $sum / 3600):$sum / 3600);  
		#printf ("\"$act\":\t\t%10ds\t%3.2fhrs\n", $sum, $sum / 3600);  
		# If sum is greater than fifteen minutes, put it individual list
		# otherwise, put it in
		# 2014-10-02:  Remove miscellaneous, since we will no longer be reporting in
		# fifteen minute increments
		#$sum > 900?$ind{$act}=$sum:$misc{$act}=$sum;
		$ind{$act}=$sum;
		$gtot += $sum;
	}
}

#my $spr;
my $sec;
my $hrs;
my $min;
my $fhrs;
my $ctot = 0;
my $utot = 0;

# DEBUGGING
#foreach $act (sort keys %ind) {
#	print STDERR "Activity:  " . $act . " ";
#	print STDERR "$ind{$act}s " . $ind{$act}/3600 . "hrs ";
#	print STDERR $ind{$act}%3600/60 . "min\n";
#}

format STDOUT =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    @>>>>>>>>>>  @>>>>>>>>>>  @>>>>>>>>>>  @>>>>>>>>>>    
$act, $sec, $hrs, $min, $fhrs
.
foreach $act (sort keys %ind) {
	#$spr = sprintf("%3.2fhrs",nearest(0.25, $ind{$act}/3600));
	$min = sprintf("%dmin",nearest(1, $ind{$act}%3600/60));
	$hrs = sprintf("%dhrs",$ind{$act}/3600);
	$fhrs = sprintf("%.2fhrs",$ind{$act}/3600);
	$sec = "$ind{$act}s";
	write;
 if($act =~ /^\d{8}/) {
		#print STDERR "Got a case\n";
		$ctot += $ind{$act};
	} else {
		#print STDERR "Got a non-case\n";
		$utot += $ind{$act};
	}
# } elsif($changed == 0) {
#			print "\n";
#			printf ("Case total:  %10ds, %3.2fhrs, %3.2fhrs (rounded)\n", $ctot, $ctot / 3600, nearest(0.25, $ctot / 3600));
#			print "\n";
# $changed = 1;
#}
#	else {
#		$min = sprintf("%dmin",nearest(1, $ind{$act}%3600/60));
#		$hrs = sprintf("%dhrs",$ind{$act}/3600);
#		$fhrs = sprintf("%.2fhrs",$ind{$act}/3600);
#		$sec = "$ind{$act}s";
#		write;
#		$utot += $ind{$act};
#	}
}
print "\n";
printf ("Case total:  %10ds, %3.2fhrs, %3.2fhrs (rounded)\n", $ctot, $ctot / 3600, nearest(0.25, $ctot / 3600));
print "\n";
print "\n";
printf ("Unnumbered total:  %10ds, %3.2fhrs, %3.2fhrs (rounded)\n", $utot, $utot / 3600, nearest(0.25, $utot / 3600));
print "\n";
# REMOVED 2014-10-02
#$tot = 0;
#foreach $act (sort keys %misc) {
#	$spr = sprintf("%3.2fhrs", $misc{$act}/3600);
#	$sec = "$misc{$act}s";
#	write;
#	$tot += $misc{$act};
#}
#print "\n";
#printf ("Miscellaneous total:  %10ds, %3.2fhrs, %3.2fhrs (rounded)\n", $tot,$tot / 3600, nearest(0.25, $tot / 3600));
#print "\n";

$gtot = $ctot + $utot;
print "\n"; 
printf "Grand Total: %10ds, %.02fhrs\n", $gtot, $gtot / 3600; 

#my &section_post {
#
#};
