#!/usr/local/bin/perl

# mscan -- Monthly schedule scanner.  by nom@csce.kyushu-u.ac.jp
#
# $Id: mscan,v 1.2 1995/12/01 14:25:20 nom Exp nom $
#
# 1. mscan [+ScheduleFolder] [-schedule] [-today] [-squeeze] [-nonum]
#
# 2. mscan [same as scan ... ]

#
# Global variables.
#
$width = 80;
$swidth = $width - 27;
$rootFolder = "schedule";
$SCAN="/usr/local/bin/mh/scan";
@WEEK = ('(Sun)', ' Mon ', ' Tue ', ' Wed ', ' Thu ', ' Fri ', ' Sat ');

#
# set options.
#
foreach (@ARGV){
    if (/^-squeeze$/){
	$squeezeFLG = $scheduleFLG = 1;

    }elsif (/^-today$/){
	($sec, $min, $hour, $day, $mon, $year) = localtime(time);
	$mon++;
	$todayFLG = sprintf("%02d/%02d", $mon, $day);
	$scheduleFLG = 1;

    }elsif (/^\+$rootFolder/){
	$scFolder = $_;	$scheduleFLG = 1;

    }elsif (/^-nonum$/){
	$nonumFLG = $scheduleFLG = 1;

    }elsif (/^-schedule$/){
	$scheduleFLG = 1;

    }elsif (/^[0-9]+$/){
	$width = $_;
	$swidth = $width -27;
    }else {
#	$unknownFLG = 1;
    }
}

if ($unknownFLG && $scheduleFLG){
    die "Usage: mscan [+ScheduleFolder] [-schedule]".
	"[-today] [-squeeze] [-nonum]\n".
	"       mscan [same as scan ... ]\n";
}

if (!$scFolder){
    ($sec, $min, $hour, $day, $mon, $year) = localtime(time);
    $mon++;
    $scFolder = sprintf("+$rootFolder/%02d/%02d", $year, $mon);
}

#
# if argument doesn't have '+schddule/...' nor '-month', scan normally.
#
exec ("$SCAN", @ARGV) if (!$scheduleFLG);

#
# scan monthly schedule and  set to @scItems.
#
$msgFMT  = "%(msg)";
$dateFMT = "%02(mon{x-sc-date})/%02(mday{x-sc-date})";
$hourFMT = "%02(hour{x-sc-date}):%02(min{x-sc-date})";
$headFMT = "%<{x-sc-subject}%$swidth(hdecode{x-sc-subject})%?{body}%{body}%>";

open(SCAN, "$SCAN $scFolder -format '$msgFMT $dateFMT $hourFMT $headFMT' |");

while(<SCAN>)
{
    ($msg, $date, $time, $item) = split(/ +/, $_, 4);
    $scItems{$date} .= "$time\n$msg\n$item$;";
}

#
# format output.
#
($year, $mon) = ($scFolder =~ m!\+$rootFolder/([0-9][0-9])/([0-9][0-9])!);
$firstWeek = &dayOfWeek($mon, 1, $year + 1900);

foreach $day (1 .. &daysOfMonth($mon, $year + 1900)) {
    $date = sprintf("%02d/%02d", $mon, $day);
    $week = $WEEK[($day -1 + $firstWeek) % 7];
    next if ($todayFLG && $date ne $todayFLG);

    if ($scItems{$date}){
	@items = sort(split("$;", $scItems{$date}));

	foreach (@items){
	    ($time, $msg, $item) = split(/\n+/);
	    $output  = sprintf("%4d  | ", $msg) if (!$nonumFLG);
	    $output .= sprintf("%s %s %s %s", 
			       $date, $week, $time, $item);
#	    print substr($output, 0, $width) . "\n";
	    print $output . "\n"; $output = "";
	    $week = " " x length($week);
	    $date = " " x length($date);
	}
    } else {
	if (!$squeezeFLG && !$todayFLG){
	    $output  = sprintf("%4d  | ", 0) if (!$nonumFLG);
#	    printf("       | ") if (!$nonumFLG);
	    $output .= sprintf("%s %s", $date, $week);
#	    print substr($output, 0, $width) . "\n";
	    print $output . "\n"; $output = "";
	}
    }
}

##
## Sub routines.
##

# isLeapYear(int year) -- check if leap year
#
# year:
#    ex. 1994
# return: 
#    1 ... leap year
#    0 ... not leap year
#
sub isLeapYear
{
    local ($year) = @_;

    return 1 if ($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0;
    return 0;
}

# dayOfYear(int mon, int day, int year) -- Nth day of the year.
#
# mon, day, year:
#    ex. 7, 1, 1994
# return:
#    182 ... 7, 1, 1994 is the 182nd day of the year.
#
sub dayOfYear
{
    local ($mon, $day, $year) = @_;
    local ($a);

    if (&isLeapYear($year) && $mon > 2) {
	$a = 1;
    } else {
	$a = 0;
    }

    ($day + ($mon - 1) * 31
     - (0, 0, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7)[$mon - 1]
     + $a);
}

# int daysOfMonth(int mon, int year) -- days of the month.
#
# mon, year:
#    ex. 2, 1992
# return:
#    29 ... 1992 is leap year.
sub daysOfMonth
{
    local ($mon, $year) = @_;

    (31, 28 + &isLeapYear($year), 31, 30, 31, 30,
     31, 31, 30, 31, 30, 31)[$mon - 1];
}

# int dayOfWeek(int mon, int day, int year) -- day of week as a number.
#
# mon, day, year:
#    ex. 7, 1, 1994
# return:
#    5 (Fri) ... 7, 1, 1994 is Friday (0:Sun, 1:Mon, ... , 6:Sat)
#
sub dayOfWeek
{
    local ($mon, $day, $year) = @_;

    (&dayOfYear($mon, $day, $year) + ($year -1) * 365 
     + int(($year - 1) / 4)
     - int(($year - 1) / 100)
     + int(($year - 1) / 400)) % 7;
}

