#!/afs/athena/contrib/perl/p -s
# 
# omer.pl: calculate the current day of the omer
# 
# by Jonathan Kamens
# 
# uses the "sdate" program to find the sunset time, and the "hdate"
# program to find Hebrew dates

$SDATE = '/afs/sipb.mit.edu/project/sipb/bin/sdate';
$HDATE = '/afs/sipb.mit.edu/project/sipb/bin/hdate';

@english_months =	  (January, February, March, April, May, June, July, August, September, October, November, December);
@days_in_english_months = (31,      28,       31,    30,    31,  30,   31,   31,     30,        31,      30,       31);

# Ignores leap years, since the Omer should never occur that early.

sub next_day {
    local($day, $month) = @_;

    if ($days_in_months[$month] == $day) {
	$day = 1;
	$month = ($month + 1) % 12;
    }
    else {
	$day++;
    }

    return($day, $month);
}

sub sunset {
    open(SDATE, "$SDATE|") || die;
    while (<SDATE>) {
	if (/^Sunset\s+(..):(..)/) {
	    close(SDATE);
	    return($1, $2);
	}
    }
    close(SDATE);
    die "Couldn't parse output of $SDATE to get sunset time.\n";
}

sub hebrew_date {
    local($day, $month, $year) = @_;
    local($hebrew);
    $month++;
    open(HDATE, "$HDATE $day $month $year|") || die;
    ($hebrew = <HDATE>) || die;
    close(HDATE);
    chop $hebrew;
    $hebrew;
}

sub day_of_omer {
    local($day, $month, $year) = split(' ', $_[0]);

    if ($month eq "Nisan") {
	if ($day > 14) {
	    return($day - 15);
	}
    }
    elsif ($month eq "Iyar") {
	return($day + 15);
    }
    elsif ($month eq "Sivan") {
	if ($day < 6) {
	    return($day + 44);
	}
    }
    undef;
}

sub long_day_of_omer {
    local($num) = @_;
    local($weeks) = int($num / 7);
    local($days) = $num % 7;
    local($week_str, $day_str);

    if ($weeks > 0) {
	if ($weeks == 1) {
	    $week_str = "1 week";
	}
	else {
	    $week_str = "$weeks weeks";
	}
    }

    if ($days > 0) {
	if ($days == 1) {
	    $day_str = "1 day";
	}
	else {
	    $day_str = "$days days";
	}
    }

    if ($week_str && $day_str) {
	"$week_str and $day_str";
    }
    elsif ($week_str) {
	$week_str;
    }
    else {
	$day_str;
    }
}
    
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = 
    localtime(time);
$year += 1900;

($next_day, $next_month) = &next_day($mday, $mon);

($sunset_hour, $sunset_minute) = &sunset();

$hebrew_date = &hebrew_date($mday, $mon, $year);
$next_hebrew_date = &hebrew_date($next_day, $next_month, $year);

$day_of_omer = &day_of_omer($hebrew_date);
$next_day_of_omer = &day_of_omer($next_hebrew_date);

if (! ($day_of_omer || $next_day_of_omer)) {
    die "We're not counting the Omer right now!\n" if (! $quiet);
    exit 0;
}

print "Today is $english_months[$mon] $mday, $year.\n";
printf("Sunset is at %d:%02d local time, ", $sunset_hour, $sunset_minute);

$sunset_difference = 
    ($min + $hour * 60) - ($sunset_minute + $sunset_hour * 60);

if ($sunset_difference > 0) {
    printf("which was %d hour%s and %d minute%s ago.\n",
	   $sunset_difference / 60, 
	   (int($sunset_difference / 60) == 1) ? "" : "s", 
	   $sunset_difference % 60,
	   ($sunset_difference % 60 == 1) ? "" : "s");
}
elsif ($sunset_difference < 0) {
    $sunset_difference *= -1;
    printf("which is in %d hour%s and %d minute%s.\n",
	   $sunset_difference / 60, 
	   (int($sunset_difference / 60) == 1) ? "" : "s", 
	   $sunset_difference % 60,
	   ($sunset_difference % 60 == 1) ? "" : "s");
}
else {
    print "which is the current time.\n";
}

if ($day_of_omer) {
    printf("Before sunset, the Hebrew date is %s, which is day number %d,\n\tcomprising %s of the Omer.\n", 
       $hebrew_date, $day_of_omer, &long_day_of_omer($day_of_omer));
}
else {
    printf("Before sunset, the Hebrew date is %s, which is\nthe second day of Pesach.\n",
	   $hebrew_date);
}

if ($next_day_of_omer) {
    printf("After sunset, the Hebrew date is %s, which is day number %d,\n\tcomprising %s of the Omer.\n",
	   $next_hebrew_date, $next_day_of_omer, &long_day_of_omer($next_day_of_omer));
}
else {
    printf("After sunset, the Hebrew date is %s, which is Shavuot.\n",
	   $next_hebrew_date);
}
