<?php

/***************************************************************************
 * wikilog.php, version 0.1.6                                              *
 * This is a calendar display and wikilog macro for the PmWiki engine      *
 * Copyright (c) 2003 John Rankin john.rankin@affinity.co.nz               *
 *                                                                         *
 * To use it, create a GroupHeader page that says [[wikilog]]              *
 * Make sure you press 'Return' at the end of the line, then Save.         *
 * To override the default home page name, write [[wikilog:MagicWord]]     *
 *                                                                         *
 * The calendar display is copied from a free software program             *
 * written by Stephan Uhlmann <su@su2.info>                                *
 ***************************************************************************/
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

// =========================================================================
// Configuration
// =========================================================================

// This configures how weekdays are presented.
// 0 - american style, Sun to Sat
// 1 - european style, Mon to Sun
$calendar_weekstyle=1;

// This configures how dates are presented.
// 0 - american style, 11/17/2002
// 1 - european style, 17.11.2002
$calendar_datestyle=1;

// How many months relative to the current one to start the calendar.
// Can be a negative (going back) or a positive (going ahead) number.
// The value zero (0) starts the calendar with the current month.
$calendar_months_start=0;

// How many months altogether to show on the calendar.
$calendar_months_number=1;

// How many months after we should wrap and start a new row.
$calendar_month_wrap=3;

// Whether or not to display current entries at the bottom of the calendar.
// Enter 'false' to omit the current period's entries.
$display_log_entries=true;

// Whether to display a summary or full calendar on individual entry pages.
// Enter 'false' to include the calendar on every page.
$summary_only=true;

// This is the default home of each collection (Group) of date pages.
$group=FmtPageName('$Group',$pagename);
$wikilog_home_page="{{".$group."}}";

// Allow page names to be all numerics and format Group/yyyymmdd references.
$PageTitlePattern="[A-Z0-9][A-Za-z0-9]*(?:-[A-Za-z0-9]+)*";
$CalendarPattern = "[0-9]{8}";
$WikiDateCreateFmt = 
      "<a class='nonexistent-date' href='\$PageUrl?action=edit'>\$LinkText</a>";
$LinkPatterns[750]["\\b$GroupNamePattern([\\/.])$CalendarPattern"] = 
     'FmtWikiDateLink';

// Whether to display non-existent date entries in the calendar as day or day?
// Enter 'true' to use the wiki '?' convention for non-existent entries
$day_as_wiki=false;

// Set depending on whether you need ThisPage:?logdate= or ThisPage:&logdate=
$UrlConnector = "?";
#$UrlConnector = "&";

// Month and day names in chosen language
$monthnames = array('January','February','March','April','May','June','July','August', 'September','October','November','December'); 

$shortdaynames = array('Sun','Mon','Tue','Wed','Thu','Fri','Sat','Sun');

$longdaynames = 
array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');

$noentries = 'No entries for';
$today  = 'Today';
$below  = 'See below.';
$period = 'period';
/*

You can define different colours for the dates with or without an entry in the
$HTMLHeaderFmt variable. The class attributes for the TD tag are:

calendar-today-entry	: current date and there is an entry
calendar-today-noentry	: current date but there is no entry
calendar-entry		: any other date with an entry
calendar-noentry	: any other date without an entry

The class attribute for date links is:

nonexistent-date	: wikilink without an entry

Example:

*/

$HTMLHeaderFmt .= "<style type = 'text/css'>
div#wikilog {
	margin-top: 10px;
	margin-left: 25px;
	font-size: smaller;
}
td.calendar-today-entry {
	background-color: #ff3333;
	color:            #97694f; 
}
td.calendar-today-noentry { 
	background-color: #ffc3c3;
	color:            #97694f; 
}
td.calendar-entry {
	background-color: #c3ffc3;
	color:            #97694f; 
}
td.calendar-noentry {
	color:            #97694f;
}
a.nonexistent-date  { 
	background: transparent;
	text-decoration: none;
	color: #FF2222;
}
a.nonexistent-date:visited  { 
	background: transparent;
	text-decoration: none;
	color: #FF2222;
}
a.nonexistent-date:hover {
	text-decoration: underline;
	color: #444444;
}
</style>";

// ======================================================================

$logdate = $HTTP_GET_VARS['logdate'];
$DoubleBrackets["/^\\[\\[wikilog(:($WikiWordPattern|$FreeLinkPattern))?\\]\\]$/e"] = 'view_calendar("$2");';

function view_calendar($homepage)
{
	global $calendar_months_start, $calendar_months_number, $calendar_month_wrap, $display_log_entries;
	global $wikilog_home_page, $summary_only, $pagename, $logdate;

	$r="";
	$d="";
        $group = FmtPageName('$Group',$pagename);
	$title = FmtPageName('$Title',$pagename);
	if ($homepage != '') $wikilog_home_page = $homepage;

	// check to see whether to display a summary only

	if (IsDate($title) && ($summary_only==true)) {
		$r.=adjacent_entries($group, $title) . "\n";
		$r.="<h3>". longdate($title) . "</h3>\n";
		return $r;
	}

	// start configured number of months before/ahead
	$logdate.="16";
	if (IsDate($logdate)) {
		$year = substr($logdate,0,4);
		$month= substr($logdate,4,2);
	} else {
		if (IsDate($title)) {
			$year = substr($title,0,4);
			$month= substr($title,4,2);
		} else {
			$year = date("Y");
			$month= date("m");
		}
	}
	$startingtime = mktime(0,0,0,$month,16,$year);

	// generate the calendar navigation bar

	$currentmonth= date("Y") . date("m");
	$lasttime =$startingtime-$calendar_months_number*2592000;
	$lastmonth= strftime("%Y",$lasttime) . strftime("%m",$lasttime);
	$nexttime =$startingtime+$calendar_months_number*2592000;
	$nextmonth=strftime("%Y",$nexttime) . strftime("%m",$nexttime);

	if ($currentmonth < $lastmonth) {
		$r.=calendar_nav($currentmonth) . " - ";
	}
	$r.=calendar_nav($lastmonth) . " - ";
	$r.=calendar_nav($nextmonth);
	if ($currentmonth > $nextmonth) {
		$r.=" - " . calendar_nav($currentmonth);
	}
	$r.="<p />";

	// generate the calendar

	$r.="<div id='wikilog'><table border='0'><tr>\n";

	$itime=$startingtime+$calendar_months_start*2592000;
	$i=0;

	while ($i<$calendar_months_number)
	{
		$r.="<td valign=\"top\">";
		$r.=calendar_month(strftime("%m",$itime),strftime("%Y",$itime));
		$r.="</td>\n";
		if ($display_log_entries==true) { 
		$d=list_entries(strftime("%m",$itime),strftime("%Y",$itime)).$d;
		}
		// +1 month
		// It's actually 30 days which could break when displaying a lot of months
		// but it should be ok when displaying only one or two years at the same time
		$itime=$itime+2592000;
		$i++;
		if (($i%$calendar_month_wrap==0) && ($i!=12)) $r.="</tr><tr>";
	}

	$r.="</tr></table></div>\n";

	// generate the chrono list

	if ($display_log_entries==true)
	{
		$r.= "<p />" . $wikilog_home_page . ":<ul>\n";
		$r.=$d . "</ul><hr /><p />\n";
	}

	// translate the page title

	if (IsDate($title)) {
		$r.="<h3>". longdate($title) . "</h3>";
	}

	return "$r";
}

function calendar_month($month,$year)
{
	global $pagename, $monthnames, $shortdaynames;
	global $wikilog_home_page, $calendar_weekstyle;

        $group = FmtPageName('$Group',$pagename);
	$prefix = $group . "/" . $year . $month;

	$r="";

	$todays_time=mktime(0,0,0,date("m"),date("d"),date("Y"));
	$last_day_of_month=strftime("%d",mktime(0,0,0,$month+1,0,$year));

	$r.="<table border='2' bordercolor='#abd5d6' cellpadding='3' cellspacing='0'>";

	// header with month and year
	$r.="<tr><td colspan='7' align='center'>". $monthnames[$month-1] . " ". $year . "</td></tr>\n";

	// weekday names
	$r.="<tr>";
	for ($i=$calendar_weekstyle;$i<7+$calendar_weekstyle;$i++)
	{
		$r.="<td align='center'>" . $shortdaynames[$i] . "</td>";
	}
	$r.="</tr>\n";

	$count=0;

	// pre-padding
	$r.="<tr>";
	for ($i=0;$i<(strftime("%w",mktime(0,0,0,$month,1,$year))-$calendar_weekstyle+7)%7;$i++)
	{
		$r.="<td>&nbsp;</td>";
		$count++;
	}

	// days
	for ($i=1;$i<=$last_day_of_month;$i++)
	{

		if ($count%7==0) $r.="</tr>\n<tr>";

		if ($i<10) { $day="0".$i; } else { $day=$i; }
		$entryname= $prefix . $day;
		$r.="<td align='center' class='calendar-";
		if (abs($todays_time - mktime(0,0,0,$month,$i,$year)) < 86400)
		{
			$r.="today-";
		}
		if (PageExists($entryname))
		{
			$r.="entry'>";
			$r.="<b>[[". $entryname . " " . $day . "]]</b>";
		}
		else
		{
			$r.="noentry'>";
			$r.="[[". $entryname . " " . $day . "]]";
		}
		$r.="</td>";

		$count++;

	}

	// post-padding
	while ($count%7!=0)
	{
		$r.="<td>&nbsp;</td>";
		$count++;
	}

	$r.="</tr>\n";

	$r.="</table>\n";

	return $r;
}

function list_entries($month, $year)
{
	global $pagename, $wikilog_home_page, $monthnames, $today, $noentries, $below;

	$r="";
        $group = FmtPageName('$Group',$pagename);
	$title = FmtPageName('$Title',$pagename);
	$prefix = $group . "/" . $year . $month;

	$todays_time=mktime(0,0,0,date("m"),date("d"),date("Y"));
	$last_day_of_month=strftime("%d",mktime(0,0,0,$month+1,0,$year));

	for ($i=1;$i<=$last_day_of_month;$i++)
	{

		if ($i<10) { $day="0".$i; } else { $day=$i; }
		$entrydate = $year . $month . $day;
		$entryname= $prefix . $day;
		if (PageExists($entryname))
		{
			$line="<li>[[". $entryname . " ";
		if (abs($todays_time - mktime(0,0,0,$month,$i,$year)) < 86400)
				{ $line.=$today;
			} else {
				$line.=shortdate($year,$month,$day);
			}
			$line.="]]: ";
			if ($entrydate == $title) {
				$firstpara = "<b>$below</b>";
			} else {
				$snippet = ReadPage($entryname);
				$snippet['text'] .= "\n";
   $firstpara = substr($snippet['text'], 0, strpos($snippet['text'], "\n"));
   $firstpara = preg_replace("/^[#*!:]+\s*/","",$firstpara);
			}
			$line.=$firstpara . "</li>\n";
			$r=$line . $r;
		}

	}
	if ($r == "") {
		$r = "<li>$noentries ".$monthnames[$month-1]." $year.</li>\n";
	}

	return $r;
}

function IsDate($title) {
	if (is_numeric($title) && strlen($title) == 8) {
		$year = substr($title,0,4);
		$month= substr($title,4,2);
		$day  = substr($title,6,2);
		return checkdate($month, $day, $year);
	} else {
		return false;
	}
}

function longdate($title) {
	global $calendar_datestyle, $monthnames, $longdaynames;

	$year = substr($title,0,4);
	$month= substr($title,4,2);
	$day  = substr($title,6,2);
	if ($day[0] == "0") { $day = $day[1]; }
	$longmonth = $monthnames[$month-1];
	if ($calendar_datestyle == 0) {
		$r=", $longmonth $day, ";
	} else {
		$r=", $day $longmonth ";
	}
	$dayname=$longdaynames[strftime("%w",mktime(0,0,0,$month,$day,$year))];
	return "$dayname$r$year";
}

function calendar_nav($yearmo) {
	global $calendar_months_number, $UrlConnector, $monthnames, $period;

	$year = substr($yearmo,0,4);
	$r = "[[ThisPage:" . $UrlConnector . "logdate=";
	$r.= $yearmo . " ";
	$r.= $monthnames[substr($yearmo,4,2)-1];
	$r.= " " . $year;
	if ($calendar_months_number == 1 ) {
		$r.= "]]";
	} else {
		$r.= " $period]]";
	}
	return $r;
}

function adjacent_entries($group, $title) {
	global $wikilog_home_page;

	$year =substr($title,0,4);
	$month=substr($title,4,2);
	$day  =substr($title,6,2);
	$prefix = $group . "/" . $year . $month;
	$last_day_of_month=strftime("%d",mktime(0,0,0,$month+1,0,$year));
	$prev="";
	for ($i=1;$i<$day;$i++) {
		if ($i<10) { $prevday="0".$i; } else { $prevday=$i; }
		$entryname = $prefix . $prevday;
		if (PageExists($entryname)) {
			$prev = "&laquo; [[" . $entryname . " ";
			$prev.= shortdate($year,$month,$prevday) . "]] | ";
		}
	}
	$next="";
	for ($i=$last_day_of_month;$i>$day;$i--) {
		if ($i<10) { $nextday="0".$i; } else { $nextday=$i; }
		$entryname = $prefix . $nextday;
		if (PageExists($entryname)) {
			$next = " | [[" . $entryname . " ";
			$next.= shortdate($year,$month,$nextday) . "]] &raquo;";
		}
	}
	return $prev . $wikilog_home_page . $next;
	
}

function shortdate($year, $month, $day) {
	global $calendar_datestyle;

	if ($calendar_datestyle==0) {
		return "$month/$day/$year";
	}
	return "$day.$month.$year";
}

function FmtWikiDateLink($pat,$ref,$btext,$out=NULL,$pname=NULL) {
  global $WikiPageCreateFmt,$WikiDateCreateFmt,$day_as_wiki;
  if ($day_as_wiki==true) return FmtWikiLink($pat,$ref,$btext,$out,$pname);
  $hold = $WikiPageCreateFmt;
  $WikiPageCreateFmt = $WikiDateCreateFmt;
  $r = FmtWikiLink($pat,$ref,$btext,$out,$pname);
  $WikiPageCreateFmt = $hold;
  return $r;
}

?>