#!/usr/bin/perl -w
#
#	web.calendar
#
#	Generate a calendar.
#
#	Generate a calendar which fills a page.  Get the information
#	from a calendar file.
#
#	Generate a page for each month which has an activity.
#
#	Usage:
#	    web.calendar [flags]
#	Flags:
#	    --data datafile
#		This is the name of the calendar data file.  It contains
#		which are of the form:
#		    #		Comment line
#		    Year=1999	Introduces a new year
#		    Month=10	Introduces a new month
#		    1=event	Some event on the specified day.
#		    TBA=event	Some event at an unknown date within the month.
#		The event calendar must be in order.  If not specified, the
#		event calendar's filename is assumed to be "calendar.data".
#		The events may contain HTML, but keep it simple.
#           --start 1998/10
#               This specifies the starting month.  This must be in the
#               format shown.  If unspecified, it starts as early as possible.
#           --end 1999/05
#               This specifies the ending month.  If unspecified, the calendar
#               goes as long as possible.
#	    --bg color
#		This specifies the background color.  This can be anything
#		that HTML allows.  This defaults to no specific color.
#	    --title "some title"
#		This specifies the title of the calendar.
#	    --banner "some message"
#		This is the header text of the calendar.
#	    --html directory
#		This specifies the name of the directory to store
#		the generated files.  By default, they will go into
#		the current directory.
#
#

use strict;
use Time::Local;
use Getopt::Long;

use vars qw(%Activities $EndMonth $EndYear %Months @MonTab @MonTabShort
				%Params $StartMonth $StartYear $Version);

%Params =
    (
    	"data"		=> "calendar.data",
	"start"		=> "0000/01",
	"end"		=> "9999/12",
	"bg"		=> "",
	"title"		=> "Calendar",
	"banner"	=> "Calendar",
	"html"		=> ".",
    );

@MonTab		= ( "", "January", "February", "March", "April",
			"May", "June", "July", "August", "September",
			"October", "November", "December");
@MonTabShort	= ( "", "jan", "feb", "mar", "apr", "may", "jun",
			"jul", "aug", "sep", "oct", "nov", "dec");

$StartYear      = 1000;
$StartMonth     = 1;
$EndYear        = 9999;
$EndMonth       = 12;
$Version	= 'web.calendar v0.11 regan@ao.com';

###
###	Main program
###

    my(@cal, $dom, $dow, $line, $mon, $mon2, $month, $next, $prev,
    		$text, $year, $year2);

#   chdir($ENV{'HOME'});
    GetOptions(\%Params,
    	"data=s", "bg=s", "title=s", "banner=s", "html=s");
    $Params{'bg'} = qq|bgcolor="$Params{'bg'}"| if ($Params{'bg'} ne "");

    # Split the years and month
    ($StartYear, $StartMonth) = split(/[\D]/, $Params{'start'});
    ($EndYear, $EndMonth) = split(/[\D]/, $Params{'end'});

    ReadCalendar($Params{'data'});
    for $month (sort(keys %Months))
    	{
    	print "Handle $month\n";
    	($year, $mon) = split(/\./, $month);

	$year2 = $year;
	$mon2 = $mon - 1;
	if ($mon2 == 0)
	    {
	    $mon2 = 12;
	    $year2--;
	    }
	$prev = "<br>";
	$prev = "<a href=\"$year2.$mon2.html\">Previous</a>"
				if (defined($Months{"$year2.$mon2"}));
	$year2 = $year;
	$mon2 = $mon + 1;
	if ($mon2 == 13)
	    {
	    $mon2 = 1;
	    $year2++;
	    }
	$next = "<br>";
	$next = "<a href=\"$year2.$mon2.html\">Next</a>"
				if (defined($Months{"$year2.$mon2"}));

    	if (!open(WEB, ">$Params{'html'}/$year.$mon.html"))
    	    {
    	    print "Cannot open $Params{'html'}/$year.$mon.html: $!\n";
    	    exit 1;
    	    }

	# Put in month header information
	print WEB << "	EOF";
	    <html>
	    <head>
	    <title>$Params{'title'} for $MonTab[$mon] $year</title>
	    </head>

	    <body $Params{'bg'}>
	    <table border=3 cols=7>
	    <small>
	    <tr><th>$prev</th>
	        <th><h3>$Params{'banner'}</h3></th>
	    	<th colspan=3><center><h1><i>$MonTab[$mon]</i></h1>
							</center></th>
	    	<th><h3>$year</h3></th>
	    	<th>$next</th>
	    <tr><th width=14.285%>Sunday</th>
	    	<th width=14.285%>Monday</th>
	    	<th width=14.285%>Tuesday</th>
	    	<th width=14.285%>Wednesday</th>
	        <th width=14.285%>Thursday</th>
	        <th width=14.285%>Friday</th>
	        <th width=14.285%>Saturday</th></tr>
	EOF

        # Build a calendar
        my(%cal, $time, @tm);
        @tm = (0, 0, 12, 1, $mon - 1, $year - 1900);
        $time = timelocal(@tm) - 86400;
        $line = 0;
        for ($dom = 1; $dom <= 31; $dom++)
            {
            @tm = localtime($time + $dom * 86400);
            next if ($tm[4] != $mon - 1);
            $cal{$line, 10}++;              # Count populated lines
            $cal{$line, $tm[6]} = $dom;     # Fill in based on day of week
            $line++ if ($tm[6] == 6);       # If we fill in Saturday, advance
            }

	# Put in events for each of the days
    	for ($line = 0; $line < 5; $line++)
    	    {
    	    last if (!defined($cal{$line, 10}));
    	    print WEB "<tr valign=top>";
    	    for ($dow = 0; $dow < 7; $dow++)
    	    	{
    	    	print WEB "<td width=14%>";
    	    	$dom = $cal{$line, $dow} || 0;
    	    	if ($dom > 0)
    	    	    {
    	    	    print WEB "<font size=-1>\n";
    	    	    print WEB "<h2>$dom</h2>";
    	    	    $text = $Activities{$year, $mon, $dom} || "";
    	    	    $text =~ s/\n/<br>\n/gm;
    	    	    print WEB $text;
    	    	    }
    	    	print WEB "</td>\n";
    	    	}
    	    }
    	print WEB "</table>\n";
    	close WEB;
    	}
    exit 0;


###
###	ReadCalendar
###
###	Read a calendar file.
###
sub ReadCalendar
    {
    my($fname) = @_;
    my($month, $name, $value, $year);

    if (!open(CAL, "<$fname"))
    	{
    	print "Cannot open $fname\n";
    	exit 1;
    	}

    while (<CAL>)
    	{
    	chomp;
    	next if (/^\s*#/ || /^\s*$/);
    	if (/^([^=]*)=\s*(.*)/)
    	    {
    	    $value = $2;
    	    ($name = $1) =~ s/\s*//;
    	    if ($name eq "Year")
    	    	{
    	    	$year = $value;
    	    	}
	    elsif ($name eq "Month")
	    	{
	    	$month = $value;
	    	$Months{"$year.$month"} = 1;
	    	}
	    elsif ($name =~ /^\d+|TBA$/)
	    	{
	    	$Months{"$year.$month"} = 1;
		if ($name eq "TBA")
		    {
		    $name = "1";
		    $value = "<b>TBA</b> $value";
		    }
		if (($year > $StartYear ||
		    ($year == $StartYear && $month >= $StartMonth)) &&
		    ($year < $EndYear ||
		     ($year == $EndYear && $month <= $EndMonth)))
		    {
		    $Activities{$year, $month, $name} .= "$value\n";
		    }
	    	}
    	    }
	}
    close CAL;
    }
