<?php

#*****************************************************************************
#
# Article.php
#
# Author: 		Wayne Beaton
# Date:			2005-11-07
#
# Description: This file defines the Article class which is used to define,
# and render as html, articles.
#
#****************************************************************************
require_once("events_xml.php");
//require_once("xml_simple.php");

$events_web_root = "/community/events/";
$events_doc_root = $_SERVER['DOCUMENT_ROOT'] . $events_web_root;

function get_events_summary($count = 100) {
	$html = "";
	$events = get_top_events($count);
	foreach ($events as $event) {
		$html .= "<li>";
		if ($event->end_date) {			
			if (same_year($event->start_date, $event->end_date)) {
				if (same_month($event->start_date, $event->end_date)) {
					$html .= date("M", $event->start_date);
					$html .= date(" d", $event->start_date);
					$html .= date("-d", $event->end_date);
				} else {
					$html .= date("M d", $event->start_date);
					$html .= date("-M d", $event->end_date);
				}
			} else {
				$html .= date("M d", $event->start_date);
				$html .= date("-M d", $event->end_date);
			}
		} else {
			 $html .= date("M d", $event->start_date);
		}
		$html .= " <a href=\"$event->link\" target=\"blank\">$event->name</a>";

		$html .= "</li>";
	}
	return $html;
}

/*
 * This script is provided for convenience. It displays the 
 * next $count events that occur after the current date.
 */
function get_events_summary_for_community_page($count = 5) {
	$html = "";
	$events = get_events();
	usort($events, 'sort_events_by_date');
	foreach ($events as $event) {
		/*
		 * If an end date is provided, check to see if
		 * the end date is before the current date. If no
		 * end date is provided, check to see if the
		 * start date is before the current date. If
		 * the condition is true, skip this event and
		 * move on to the next one.
		 */
		if ($event->end_date) {
			if ($event->end_date < strtotime("0")) continue;
		} else
			if ($event->start_date < strtotime("0")) continue;
			
		/*
		 * If we've displayed as many events as we've been
		 * asked to display, bail out.
		 */
		if ($count-- == 0) break;
		
		$html .= "<li>";
		$html .= " <a href=\"$event->link\" target=\"blank\">$event->name</a>, ";
		if ($event->location) 
			$html .= "$event->location ";
		
		$html .= date("d/m/y", $event->start_date);
		if ($event->end_date) {			
			$html .= date("-d/m/y", $event->end_date);
		}
		
		$html .= "</li>";
	}
	return $html;
}

function get_events_as_html($count = 100) {
	$html = "";
	$events = get_top_events($count);
	foreach ($events as $event) {
		if ($count == 0) break;
		$html .= "<li>";
		if ($event->end_date) {			
			if (same_year($event->start_date, $event->end_date)) {
				if (same_month($event->start_date, $event->end_date)) {
					$html .= date("F", $event->start_date);
					$html .= date(" d", $event->start_date);
					$html .= date("-d, Y", $event->end_date);
				} else {
					$html .= date("F d", $event->start_date);
					$html .= date("-F d, Y", $event->end_date);
				}
			} else {
				$html .= date("F d, Y", $event->start_date);
				$html .= date("-F d, Y", $event->end_date);
			}
		} else {
			 $html .= date("F d, Y", $event->start_date);
		}
		$image = '';
		if ($event->image) {
			$root = $GLOBALS['events_web_root'];
			$image="<a href=\"$event->link\"><img src=\"$root$event->image\" align=\"right\"></a>";
		} 
		$html .= " <a href=\"$event->link\">$event->name</a>";
		if (strlen(trim($event->location)) > 0)
			$html .= " ($event->location)";
		if (strlen(trim($event->description)) > 0)
			$html .= "$image$event->description";
		$html .= "</li>";
	}
	return $html;
}

function same_year($a, $b) {
	return date("Y", $a) == date("Y", $b);
}

function same_month($a, $b) {
	return date("F", $a) == date("F", $b);
}

/*
 * This function returns at most the top $count events sorted by
 * date. This is actually a little weirder than that. Every
 * event has a priority. This list of top events includes 
 * first those events with the highest priority (closest to one),
 * and then those with lower priority. Whatever the collection
 * of events, they are sorted in chronological order (most
 * recent first).
 * 
 * Events that have already occurred (i.e. their date is in
 * the past) are not included.
 * 
 * The algorithm is simple: first sort on the priority and take
 * the top $count events from the array. Then resort the results
 * based on date. When sorting on priority, two events with the
 * same priority are sorted by date.
 */
function get_top_events($count) {
	$all_events = get_events();
	usort($all_events, 'sort_events_by_priority');
	$events = array();
	foreach($all_events as $event) {
		if ($count == 0) break;
		if (!is_in_the_past($event)) {
			$events[] = $event;
			$count--;
		}
	}
	usort($events, 'sort_events_by_date');
	
	return $events;
}

/*function & get_events() {
	$events_file = $GLOBALS['events_doc_root'] . "events.xml";
	$events_xml = load_xml_file($events_file);
	//$events_xml->dump();
	$events_xml = $events_xml->event;
	$events = array();
	foreach ($events_xml as $event_xml) {
		$event = new Event();
		$event->priority = $event_xml->priority[0]->text;
		$event->name = $event_xml->name[0]->text;
		$start_date = $event_xml->start_date[0]->text;
		if ($start_date) $event->start_date = strtotime($start_date);
		$end_date = $event_xml->end_date[0]->text;
		if ($end_date) $event->end_date = strtotime($end_date);
		$event->image = $event_xml->image[0]->text;
		$event->link = $event_xml->link[0]->text;
		$event->location = $event_xml->location[0]->text;
		$event->description = $event_xml->description[0]->text;
		array_push($events, $event);
	}
	return $events;
}*/

function is_in_the_past(& $event) {
	if ($event->end_date)
		return $event->end_date < time();
	else 
		return $event->start_date < time();		
}

class Event {
	var $priority;
	var $name;
	var $description;
	var $link;
	var $location;
	var $image;
	var $start_date;
	var $end_date;
}

function sort_events_by_priority($a, $b) {
	$a_priority = $a->priority;
	$b_priority = $b->priority;
	// If the priority is the same, sort by date.
	if ($a_priority == $b_priority)
		return sort_events_by_date($a, $b);
	return $a_priority > $b_priority ? 1 : -1;
}

function sort_events_by_date($a, $b) {
	$a_date = $a->start_date;
	$b_date = $b->start_date;
	if ($a_date == $b_date)
		return 0;
	return $a_date > $b_date ? 1 : -1;
}
?>