#!/usr/bin/perl -w

#
# input file: list of period starts,
# every line consists of one entry in the form
# dd. mm. yyyy
#

use strict;
use DateTime;
use Term::ANSIColor;
use Calendar::Simple;

my $period = 5;    # period length in days
my $pregnant = 0;  # pregnancy mode
my $use_periods = 10;

my @moontimes;
my @diffs;
my $avgdif = 0;
my $now = time();
my $last;
my $start;
my $min = $now; 
my $max = 0;

sub pdif {
	my $d = shift;
	return $d / (3600 * 24);
}

while (<>) {
	my @d = split /\. /;
	chomp @d;

	my $dt = DateTime->new(
				year => $d[2],
				month => $d[1],
				day => $d[0],
			);
	push @moontimes, $dt->epoch;
}

$last = $moontimes[-1];
if (($#moontimes - $use_periods) < 1) {
	$start = 0;
} else {
	$start = $#moontimes - $use_periods;
}

my $i;
print $start;
for ($i = $start; $i < $#moontimes ; $i++) {
	my $d = $moontimes[$i + 1] - $moontimes[$i];
	push @diffs, $d;
	$avgdif += $d;
	$min = $d if $min > $d;
	$max = $d if $max < $d;
}
$avgdif /= ($#diffs + 1);


sub
is_blue {
	my $t = shift;
	my $m;

	if ($pregnant) {
		return 0;
	}

	foreach $m (@moontimes) {
		return 1 if ($t >= $m && $t < ($m + $period*24*3600));
	}
	#HACK!!!
	my $i;
	for ($i = 1; $i<= 5; $i++) {
		return 1 if ($t >= ($last + $avgdif * $i)
				&& $t < ($last + $avgdif * $i) 
					+ $period*24*3600);
	}
	return 0;
}

####
my @months = qw(January February March April May June July August
                September October November December);
my $nmon = shift || (localtime)[4] + 1;
my $nyr  = shift || (localtime)[5] + 1900;
my $pmon = ($nmon - 1 < 1) ? 12 : $nmon - 1;
my $nextmon = ($nmon + 1 > 12) ? 1 : $nmon + 1;
my $pmyr = $pmon > $nmon ? $nyr - 1 : $nyr;
my $nmyr = $nextmon < $nmon ? $nyr + 1 : $nyr;
my @month;
my @pad;
my @mon_name;

$month[0] = calendar($pmon, $pmyr, 1);
$month[1] = calendar($nmon, $nyr, 1);
$month[2] = calendar($nextmon, $nmyr, 1);

$mon_name[0] = $months[$pmon - 1];
$mon_name[1] = $months[$nmon - 1];
$mon_name[2] = $months[$nextmon - 1];
$pad[0] = int((20 - length($mon_name[0]." $pmyr")) / 2);
$pad[1] = int((20 - length($mon_name[1]." $nyr")) / 2);
$pad[2] = int((20 - length($mon_name[2]." $nmyr")) / 2);

print ' ' x $pad[0], $mon_name[0]." $nyr ", ' ' x $pad[0], "\t";
print ' ' x $pad[1], $mon_name[1]." $nyr ", ' ' x $pad[1], "\t";
print ' ' x $pad[2], $mon_name[2]." $nyr ", ' ' x $pad[2], "\t";
print "\n";
print "Mo Tu We Th Fr Sa Su\t"x3;
print "\n";

my $len = $#{$month[0]}; 
$len = $#{$month[1]} if $len < $#{$month[1]}; 
$len = $#{$month[2]} if $len < $#{$month[2]}; 
my ($j, $k);

my @yr = ($pmyr, $nyr, $nmyr);
my @mon = ($pmon, $nmon, $nextmon);

for ($i = 0; $i <= $len; $i++) {
	for ($j = 0; $j < 3; $j++) {
		for ($k = 0; $k <= 6 ; $k++) {
			if (defined $month[$j][$i][$k]) {
				my $dt = DateTime->new(
					year => $yr[$j],
					month => $mon[$j],
					day => $month[$j][$i][$k],
				);
				print color 'blue' if (is_blue($dt->epoch));
				printf "%2d ", $month[$j][$i][$k];
				print color 'reset'; 
			} else {
				print "   ";
			}
		}
		print "\t";
	}
	print "\n";
}

if (! $pregnant) {
	printf "Average: %.2f Min: %d Max: %d ", pdif($avgdif), pdif($min), pdif($max);
	printf "Passed: %.2f Left about: %.2f\n", pdif($now - $last), pdif($avgdif - ($now - $last)) ;
} else {
	my $dt = DateTime->from_epoch( epoch => $last );
	print "Start: ".$dt->day.". ".$dt->month.". ".$dt->year."\t";

	$dt = DateTime->from_epoch( epoch => $last + (280*3600*24));
	print "End: ".$dt->day.". ".$dt->month.". ".$dt->year."\t";

	my $week = ($now - $last)/(7*24*3600); 
	$week = sprintf("%.2f", $week);
	print "Passed weeks: $week / 40\n";
}
