#!/usr/bin/perl

# Convert Datebook.pdb to iCalendar
# Copyleft 2006 Yoshizumi Endo <y-endo@ceres.dti.ne.jp>

use Palm::PDB;
use Palm::Datebook;
use Encode qw/ from_to /;

my $default_clss = "PRIVATE";
my $private_disp = 0;         # you can out put private records.
my $location_delimiter =" ";  # delimiter between summary & location
my $codeset = "utf8";         # output codeset

my $dbfile = "$ENV{HOME}/.jpilot/DatebookDB.pdb";        
my $icsfile ="$ENV{HOME}/.evolution/calendar/local/system/calendar.ics";
# my $icsfile ="/media/iPod/Calendars/calendar.ics";

my $data_server = "evolution-data-server-1.4";

## main

my @wday_s = ( "", "DAILY", "WEEKLY", "MONTHLY", "MONTHLY", "YEARLY" );
my @sday = ( "SU", "MO", "TU", "WE", "TH", "FR", "SA" );

my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) 
    = gmtime(time);
my $gmt = sprintf("%04d%02d%02dT%02d%02d%02dZ", 
	       $year + 1900, $mon +1, $mday, $hour, $min, $sec);

my $pdb = new Palm::PDB;
$pdb->Load($dbfile) || die "Can't open: $dbfile!\n";
my @categories = @{$pdb->{appinfo}{categories}}; # extract each category names

open(ICS, "> $icsfile") || die "Can't open: $icsfile!\n";
select(ICS);

print "BEGIN:VCALENDAR\nVERSION:2.0\n";
print "PRODID:-//Yoshizumi Endo//NONSGML ptodo2ical.pl//EN\n";

my $i=0;

foreach $record (@{$pdb->{records}}) {

    if (!($record->{"attributes"}{"private"} == 1 && $private_disp == 0)) {

	print "BEGIN:VEVENT\n";
	print "UID:ptodo2ical-$gmt-$record->{id}-$ENV{USER}\@$ENV{HOST}\n";
	print "DTSTAMP:$gmt\n";

	# Summary & Location

	my $summary = $record->{description};
	from_to($summary, "shiftjis", $codeset);

	if ($summary eq "") {
	    $summary = "Error: No summary data!";
	}

	$summary =~ s/\n//g;

	my @tmp = split($location_delimiter, $summary);
	$tmp[0] =~ s/ *$//;
	print "SUMMARY:$tmp[0]\n";

	if ($tmp[1] ne "") {
	    print "LOCATION:$tmp[1]\n";
	}

	# Class	

	if ($record->{"attributes"}{"private"} == 1) {
	    $class = "CONFIDENTIAL";
	} else {
	    $class = $default_clss;
	}
	print "CLASS:$class\n";

	# Description

	if ($record->{note} ne  "") {
	    $description = $record->{note};
	    from_to($description, "shiftjis", $codeset);
	    $description =~ s/\n/\\N/g;
	    print "DESCRIPTION:$description\n";
	}

	# Date & Time

	if ($record->{"start_hour"} != 255) {
	    printf ("DTSTART:%04d%02d%02dT%02d%02d%02D\n", 
		    $record->{"year"}, $record->{"month"},$record->{"day"},
		    $record->{"start_hour"}, $record->{"start_minute"});
	    printf ("DTEND:%04d%02d%02dT%02d%02d%02D\n", 
		    $record->{"year"}, $record->{"month"},$record->{"day"},
		    $record->{"end_hour"}, $record->{"end_minute"});
	} else {
	    printf ("DTSTART;VALUE=DATE:%04d%02d%02d\n", 
		    $record->{"year"}, $record->{"month"},$record->{"day"});
	    print "TRANSP:TRANSPARENT\n"
	}

	if ($record->{repeat}{type} != 0) {
	    print "RRULE:FREQ=$wday_s[$record->{repeat}{type}]";

	    # 2: weekly event
	    if ($record->{repeat}{type} == 2) {
		print ";BYDAY=";
		my $comma = 0;

 		for (my $c = 0; $c < 7; $c++) {
 		    if ($record->{repeat}{repeat_days}[$c] ==1) {
 			if ($comma == 1) {
 			    print ",";
 			}
 			print "$sday[$c]"; $comma = 1;
 		    }
		}
	    }
	    
	    # 3: monthly by day
	    if ($record->{repeat}{type} == 3) {
		my $weeknum = $record->{repeat}{weeknum}+1;
		print ";BYDAY=$weeknum$sday[$record->{repeat}{daynum}]";
	    }

	    # 4: monthly by date
	    if ($record->{repeat}{type} == 4) {
		print ";BYMONTHDAY=$record->{'day'}";
	    }

	    # repeat end date
	    if ($record->{repeat}{end_year} != 0) {
		printf (";UNTIL=%04d%02d%02d",  
			$record->{repeat}{end_year},
			$record->{repeat}{end_month}, 
			$record->{repeat}{end_day});
	    }

	    # repeat frequency
	    if ($record->{repeat}{frequency} > 1){
		print ";INTERVAL=$record->{repeat}{frequency}";
	    }
	    print "\n";

	    # exceptions
	    if ( @{$record->{exceptions}} > 0) {
		print "EXDATE;VALUE=DATE:";
		for (my $c = 0; $c < @{$record->{exceptions}}; $c++) {
		    if ($c != 0) {
			print ",";
		    }
		    printf ("%4d%02d%02d", 
			    $record->{exceptions}[$c][2], 
			    $record->{exceptions}[$c][1],
			    $record->{exceptions}[$c][0]);
		}	    
		print "\n";
	    }
	}

	print "END:VEVENT\n";
	$i++;
    }
}

print "END:VCALENDAR\n";

# exec ("killall -HUP $data_server");

