package MITEvents;
require Exporter;

# Date (repeatable)
#          Normal dates are 2/17/1997
#          Repeating dates are :2/17/1997:4/1/1997:pattern:
#           means that it repeats according to pattern between
#           2/17 and 4/1
#
#         pattern: repeatpattern[;repeatpattern][;repeatpattern]...
#         repeatpattern: monthspec datespec dayspec
#         monthspec: month[,month][,month]...|*
#         month: 1|2|3|4|5|6|7|8|9|10|11|12
#         datespec: date[,date][,date]|*
#         date: 1|2|3|...|30|31
#         dayspec: dayfreq[,dayfreq][,dayfreq]...|*
#         dayfreq: day[.freq]
#         day: 0|1|2|3|4|5|6
#         freq: week[week][week]
#         week: 0|1|2|3|4|5
#
#         *'s are used to say all
#         Usually you want either the monthspec or the datespec to be ?
#         So, patterns and meanings:
#         Pattern                    Meaning
#         * 1 *                      The first of every month
#         * * 2                      Every Tuesday
#         1,2,3 1,15 *               The 1st and 15th of Jan, Feb & Mar
#         1 4 5                      January 4th, if it's a Friday
#         2 * *                      Every day in February
#         * * 1,2,3,4,5              Every weekday
#         * 2 *;9 7 *                The 2nd of every month, and Sep 7th
#         * * 1.1                    The first monday of every month
#         * * 2.1,3.2                The first tuesday and second wednesday
#         1,2,3,4 * 5.13             The first and third Fridays of each
#                                    month from January to April



# Time
# Event Title
# Event Categories
# Sponsor group/person
# Email contact address
# URL
# Location
# Fees
# Intended Audience
# Description/Additional info
# Event ID


@ISA = qw(Exporter);
@EXPORT = qw(loadDB writeDB expireDB eventInFuture eventIsAfter newEvent getEvents printEvent getEvent filterCategory filterOrg);
push(@EXPORT, qw($DATE $TIME $TITLE $CATEGORIES $SPONSOR $EMAIL $URL $LOCATION $FEES $AUDIENCE $ATTIRE $DESCRIPTION $CONFIRMATION $ID));

# Functions
#
# loadDB($databasefile);
# writeDB($databasefile);
# expireDB();
# newEvent(\@event);
# @eventidnumbers = getEvents(\@fromdate, \@todate);
# printEvent($eventidnumber);
#
# events are references to arrays of the form:
#   ($date, $time, $title, $categories, $sponsor, $email, $url,
#	  $location, $fees, $audience, $attire, $description, $confirmation);

$DATE = 0;
$TIME = 1;
$TITLE = 2;
$CATEGORIES = 3;
$SPONSOR = 4;
$EMAIL = 5;
$URL = 6;
$LOCATION = 7;
$FEES = 8;
$AUDIENCE = 9;
$ATTIRE = 10;
$DESCRIPTION = 11;
$CONFIRMATION = 12;
$ID = 13;


my %eventlookup;
my $dbh;

sub loadDB {
    my $dbfile = shift;
    my @db;
    $slash = $/;
    $/ = "";
    open(DB, $dbfile);
    while(<DB>){
	chop;
	my @event = split("", $_);
	push(@db, \@event);
	$maxid = ($maxid>($event[$#event])) ? $maxid:$event[$#event];
	$eventlookup{$event[$#event]} = $#db;
    }
    close(DB);
    $/ = $slash;
    $dbh = \@db;
}

sub writeDB {
    my $dbfile = shift;
    my $e;

    rename($dbfile, "$dbfile.bak");
    open(DB, ">$dbfile");
    foreach $e (@$dbh){
	print DB join("", @$e);
	print DB "";
    }
    close(DB);
}

sub expireDB {
    my @newdb;
    my $e;

    foreach $e (@$dbh){
	if(&eventInFuture($e)){
	    push(@newdb, $e);
	}
    }
    $dbh = \@newdb;
}

sub eventInFuture {
    my $ev = shift;
    my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
	localtime(time);
    $mon++;
    $year += 1900;
    $day = $mday-1;
    &eventIsAfter($ev, $day, $mon, $year);
}

sub eventIsAfter {
    my $ev = shift;
    my ($day, $mon, $year) = @_;
    $edate = ${$ev}[$DATE];
if(substr($edate, 0, 1) eq ":"){ # 
    ($garbage, $start, $stop, $pattern) = split(":", $edate);
    $usedate = $stop;
}
else{
    $usedate = $edate;
}

($emon, $eday, $eyear) = split("/", $usedate);

if($year < $eyear){
	return 1;
}

if($year == $eyear){
	if($emon > $mon){
		return 1;
}	
    if($mon == $emon){
	if(($day) <= $eday){
	    return 1;
	}
    }
}
return 0;
}

sub eventIsOn {
    my $ev = shift;
    my ($day, $mon, $year) = @_;
    $edate = ${$ev}[$DATE];
if(substr($edate, 0, 1) eq ":"){ # 
    ($garbage, $start, $stop, $pattern) = split(":", $edate);
    $usedate = $stop;
}
else{
    $usedate = $edate;
}

($emon, $eday, $eyear) = split("/", $usedate);
return 1 if (($emon == $mon) && ($eday == $day) && ($eyear==$year));
return 0;
}

sub newEvent {
    my $eventh = shift;
    my @event = @$eventh;
    $maxid++;
    push(@event, $maxid);
    
    push(@$dbh, \@event);
    $eventlookup{$maxid} = $#$dbh;
#    my ($dbh, $date, $time, $title, $categories, $sponsor, $email, $url, 
#	$location, $fees, $audience, $description) = @_;
    return $dbh;
}

sub getEvent {
	my $eid = shift;

	return ${$dbh}[$eventlookup{$eid}];
}

sub filterCategory {
    my($cats, @eids) = @_;
    my @ret;
    my %in;

    @cats = split(//, $cats);
    foreach $ei (@eids) {
	$e = ${$dbh}[$eventlookup{$ei}];
        foreach $cat (@cats){
	    if(${$e}[$CATEGORIES] =~ /$cat/){
              push(@ret, $ei) unless $in{$ei};
	      $in{$ei}=1;
            }
        }
    }
    return @ret;
}

sub filterOrg {
    my($org, @eids) = @_;
    my @ret;

    foreach $ei (@eids) {
	$e = ${$dbh}[$eventlookup{$ei}];
        if(${$e}[$SPONSOR] =~ /$org/i){
           push(@ret, $ei);
        }
    }    

    return @ret;
}

sub getEvents {
    my $from = shift;
    my $to = shift;
    my @eids;

    ($fday, $fmon, $fyear) = @$from;
    ($tday, $tmon, $tyear) = @$to;

    foreach $e (@$dbh){
	if((&eventIsAfter($e, $fday, $fmon, $fyear) &&
	   !&eventIsAfter($e, $tday, $tmon, $tyear)) || 
	&eventIsOn($e, $tday, $tmon, $tyear)){
	    if(substr(${$e}[$CONFIRMATION], 0, 1) eq "y"){
		push(@eids,  ${$e}[$#$e]);
	}
	}
    }
return @eids;
}

sub printEvent {
    my $evnum = shift;

    $event = ${$dbh}[$eventlookup{$evnum}];
    ($date, $time, $title, $categories, $sponsor, $contact, $url,
     $location, $fees, $audience, $attire, $description, $confirmation,
	$id) = @$event;


print("$title ($date $time) [$categories]\n");
print("$location ($fees) $audience\n");
print("$url <$contact> $sponsor\n");
print("---------------------------------\n$description\n");
}
1;
