function addslashes(str) {
	str=str.replace(/\"/g,'\\"');
	return str;
}

function stripslashes(str) {
	str=str.replace(/\\"/g,'"');
	return str;
}

function strpad ( pSource, pToLength, pPadChar )
{
	var s = String(pSource);

	while( s.length < pToLength )
	{
		s = pPadChar + s;
	}

	return s;
}


/**
*   Add an event listener to an object
*   @param      object
*   @param      evt         event
*   @param      func            function
*   @param      capture
*   @return     boolean
*/
function AddEvent(object, evt, func, capture)
{
  if(typeof func != 'function')
  {
	  return false;
  }
  if(object.addEventListener)
  {
	  object.addEventListener(evt, func, capture);
	  return true;
  }
  else if(object.attachEvent)
  {
	  object.attachEvent('on' + evt, func);
	  return true;
  }
  return false;
}

/**
*   Removes an event listener
*   @param      object
*   @param      evt         event
*   @param      func            function
*   @param      capture
*   @return     boolean
*/
function RemoveEvent(object, evt, func, capture)
{
  if(typeof func != 'function')
  {
	  return false;
  }
  if(object.removeEventListener)
  {
	  object.removeEventListener(evt, func, capture);
	  return true;
  }
  else if(object.detachEvent)
  {
	  object.detachEvent('on' + evt, func);
	  return true;
  }
  return false;
}

/**
 * Object KalendarEvent
 *
 * Constructor:
 * ke = new KalendarEvent( time, description, eventId )
*/
function KalendarEvent( pTime, pNumDays, pDescription, pEventId, pEventLocation, pEventCity, pEventState, pEventDisplayLoc, pEventEnrollment, pEventCapacity )
{
	this.time = pTime;
	this.numdays = pNumDays;
	this.description = pDescription;
	this.eventId = pEventId;
	this.location = pEventLocation;
	this.city = ( typeof pEventCity != "undefined" ) ? pEventCity : null;
	this.state = ( typeof pEventState != "undefined" ) ? pEventState : null;
	this.displayloc = ( typeof pEventDisplayLoc != "undefined" ) ? pEventDisplayLoc : null;
	this.enrollment = ( typeof pEventEnrollment != "undefined" ) ? pEventEnrollment : null;
	this.capacity = ( typeof pEventCapacity != "undefined" ) ? pEventCapacity : null;
}

/**
 * Getter for time
*/
KalendarEvent.prototype.getTime = function ( )
{
	var t = "";
	var h = "";
	var m = "";
	var p = "";

	var aTime = this.time.split( ":" );

	if ( aTime[0] == 12 )
	{
		h = aTime[0];
		p = " PM";
	}
	else if ( aTime[0] > 12 )
	{
		h = aTime[0] - 12;
		p = " PM";
	}
	else
	{
		h = aTime[0];
		p = " AM";
	}

	m = aTime[1];

	return h + ":" + m + p;
}

/**
 * Getter for number of days
*/
KalendarEvent.prototype.getNumDays = function ( )
{
	return this.numdays;
}

/**
 * Getter for description.
*/
KalendarEvent.prototype.getDescription = function ( )
{
	return this.description;
}

/**
 * Getter for event id
*/
KalendarEvent.prototype.getEventId = function ( )
{
	return this.eventId;
}

/**
 * Getter for location
*/
KalendarEvent.prototype.getLocation = function ( )
{
	return this.location;
}

/**
 * Getter for City
*/
KalendarEvent.prototype.getCity = function ( )
{
	return this.city;
}

/**
 * Getter for State
*/
KalendarEvent.prototype.getState = function ( )
{
	return this.state;
}

/**
 * Getter for Display Location
*/
KalendarEvent.prototype.getDisplayLoc = function ( )
{
	return this.displayloc;
}

/**
 * Getter for Enrollment Count
*/
KalendarEvent.prototype.getEnrollment = function ( )
{
	return this.enrollment;
}

/**
 * Getter for Capacity
*/
KalendarEvent.prototype.getCapacity = function ( )
{
	return this.capacity;
}

/**
 * Object Kalendar
 *
 * Constructor:
 * k = new Kalendar( [date date], [, array{} options] );
*/
function Kalendar ( pDate, pOptions, pEvents )
{
	// Parameters
	this.kalendarDate = ( typeof pDate == 'undefined' ) ? new Date() : pDate;
	this.kalendarOptions = ( typeof pOptions == 'undefined' ) ? {} : pOptions;
	this.kalendarEvents = ( typeof pEvents == 'undefined' ) ? {} : pEvents;

	// Setup
	this.renderer = this.config( "renderer", false );

	this.monthCodes = [ 6, 2, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 ];
	this.daysInMonth = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];

	if ( this.config( "abbreviatedMonths", false ) )
	{
		this.monthNames = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
						  "Oct", "Nov", "Dec" ];
	}
	else
	{
		this.monthNames = [ "January", "February", "March", "April", "May", "June",
						"July", "August", "September", "October", "November", "December" ];
	}

	this.weekDays = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ];
}

/**
 * Setter for date
*/
Kalendar.prototype.setDate = function ( pDate )
{
	this.kalendarDate = pDate;
}

/**
 * Getter for date
*/
Kalendar.prototype.getDate = function ( )
{
	return this.kalendarDate;
}

/**
 * Event setter
*/
Kalendar.prototype.setEvents = function ( pEvents )
{
	this.kalendarEvents = pEvents;
}

/**
 * Returns an option by key. If the key doesn't exist, returns
 * either false, or the specified default parameter.
 *
 * Usage:
 * c = k.config( string key [, var default ] );
*/
Kalendar.prototype.config = function ( pKey, pDefault )
{
	var returnDefault = ( typeof pDefault == 'undefined' ) ? false : pDefault;

	return ( ( typeof this.kalendarOptions[ pKey ] == 'undefined' )
															? returnDefault
															: this.kalendarOptions[ pKey ]
														);
}

/**
 * Returns the number of days in a month ( Jan = 0 )
 * Accepts a date, otherwise uses the date passed to
 * the constructor. If the month doesn't exist,
 * returns -1;
 *
 * Usage:
 * d = k.getDaysInMonth ( [ date date ] );
*/
Kalendar.prototype.getDaysInMonth = function ( pDate )
{
	var calendarDate = ( typeof pDate == 'undefined' ) ? this.kalendarDate: pDate;

	if ( calendarDate.getMonth() == 1 )
	{
		if ( ( calendarDate.getFullYear() % 4 == 0
			&& calendarDate.getFullYear() % 100 != 0 )
			|| calendarDate.getFullYear() % 400 == 0 )
		{
			return 29;
		}
		else
		{
			return 28;
		}
	}
	else
	{
		return this.daysInMonth[ calendarDate.getMonth() ];
	}
}

/**
 * Returns the day of week that a month begins on. Accepts
 * a date, otherwises uses the date passed to the constructor.
 *
 * Usage:
 * d = k.getFirstDayOfMonth( [ date date ] );
*/
Kalendar.prototype.getFirstDayOfMonth = function ( pDate )
{
	var calendarDate = ( typeof pDate == 'undefined' ) ? this.kalendarDate : pDate;
	var backupDate = calendarDate.getDate();
	var dayNum = 0;

	calendarDate.setDate( 1 );
	dayNum = calendarDate.getDay();

	calendarDate.setDate( backupDate );

	return dayNum;
}

/**
 * Returns the name of the month by month index ( Jan = 0 )
 * If a month index is not provided, it uses the date passed
 * to the constructor.
 * Else returns false
 *
 * Usage:
 * d = k.getMonthName( [ integer monthIndex ] )
*/
Kalendar.prototype.getMonthName = function ( pMonthIndex )
{
	var calendarMonthName = ( typeof pMonthIndex == 'undefined' ) ? this.kalendarDate.getMonth() : pMonthIndex;

	return this.monthNames[ calendarMonthName ];
}

/**
 * Returns the number of weeks in a month. Accepts a date,
 * otherwise uses the date passed to the constructor.
 *
 * Usage:
 * d = k.getWeeksInMonth( [ date date ] );
*/
Kalendar.prototype.getWeeksInMonth = function ( pDate )
{
	var calendarDate = ( typeof pDate == 'undefined' ) ? this.kalendarDate : pDate;

	return ( Math.ceil( this.getFirstDayOfMonth ( calendarDate ) + this.getDaysInMonth( calendarDate ) / 7 ) );
}

/**
 * Calls the calendar renderer.
*/
Kalendar.prototype.renderCalendar = function ( )
{
	this.renderer.setKalendar( this );
	return this.renderer.render();
}

Kalendar.prototype.getDayOfWeek = function ( pDate )
{
	var ndate = ( typeof pDate == 'undefined' ) ? this.kalendarDate : pDate;
	var day = ndate.getDay();

	return this.weekDays[day];
}

/**
 * Object KalendarDivRenderer
 * Renders a DIV-marked up calendar. Hope you know your CSS.
*/

function KalendarDivRenderer()
{
	;
}

KalendarDivRenderer.prototype.setKalendar = function ( pKalendar )
{
	this.kalendar = pKalendar;
}

KalendarDivRenderer.prototype.makeTextNode = function ( pClassName, pAppend )
{
	 var d = document.createElement( "SPAN" );
	 d.className = pClassName;

	 if ( typeof pAppend != 'undefined' )
	 {
	 	d.appendChild( pAppend );
	 }

	 return d;
}

KalendarDivRenderer.prototype.makeAnchor = function ( pClassName, pHref, pAppend )
{
	 var d = document.createElement( "A" );
	 d.className = pClassName;
	 d.setAttribute( "href", pHref );

	 if ( typeof pAppend != 'undefined' )
	 {
	 	d.appendChild( pAppend );
	 }

	 return d;
}

KalendarDivRenderer.prototype.makeDiv = function ( pClassName, pAppend )
{
	var d = document.createElement( "DIV" );
	d.className = pClassName;

	if ( typeof pAppend != 'undefined' )
	{
		d.appendChild( pAppend );
	}

	return d;
}

KalendarDivRenderer.prototype.makeEmptyDiv = function ( pClassName )
{
	var d = document.createElement( "DIV" );
	d.className = pClassName;

	d.appendChild( document.createTextNode( " " ) );

	return d;
}

// Renders the calendar.
KalendarDivRenderer.prototype.render = function ( )
{
	var dayCounter			= 0;
	var i					= 0;
	var j					= 0;
	var events				= "";
	var themeClass			= this.kalendar.config( "theme", "default" ); // We're going to ignore themes in this version.
	var evtPath		= this.kalendar.config( "evtPath", "/" );
	var newEventPath = this.kalendar.config( "newEvtPath", "/" );
	var noLink = this.kalendar.config( "noLink", false );
	var todaysDate			= new Date();

	var containerDiv		= "";
	var weekDiv				= "";
	var dayDiv				= "";

	var eventDiv			= "";
	var eventTimeDiv		= "";
	var eventDescDiv		= "";
	var eventLocationDiv	= "";
	var eventDivAnchor		= "";
	
	var notBeforeDate = this.kalendar.config( 'notBefore', 'nodate' );
	var notBefore = new Date();
	notBefore.setHours( 0 ); notBefore.setMinutes( 0 ); notBefore.setSeconds( 0 );

	if ( notBeforeDate != 'nodate' )
	{
		notBeforeDate = notBeforeDate.split('-');
		notBefore.setFullYear(notBeforeDate[0],(notBeforeDate[1]-(-1)),notBeforeDate[2]);
	}
	
	containerDiv = document.createElement( "DIV" );

	// Output the empty cells at the beginning of the month
	weekDiv = this.makeDiv ( "kalendar_week" );

	for ( i = 0; i < this.kalendar.getFirstDayOfMonth(); i++ )
	{
		weekDiv.appendChild( this.makeEmptyDiv ( "kalendar_day" ) );
	}

	// Output the Meat of the Calendar
	dayCounter = this.kalendar.getFirstDayOfMonth() - 1;

	// Iterate Through Each Day
	for( i = 0; i < this.kalendar.getDaysInMonth(); i++ )
	{
		// Keep Track of The Day of the Week
		dayCounter = ( dayCounter + 1 ) % 7;
		dayNumber = (i-(-1)); // <-- JavaScript's ambiguous addition operator

		if ( dayCounter == 0 && weekDiv.childNodes.length > 0 )
		{
			// If we've wrapped around, go ahead and save this week
			// so we can start a new one.
			weekDiv.appendChild( this.makeEmptyDiv( "kalendar_bottom" ) );

			containerDiv.appendChild( weekDiv );

			weekDiv = this.makeDiv( "kalendar_week" );
		}

		// Create a new day and populate the day number.
		var today = new Date();
		var otherday = this.kalendar.kalendarDate;

		var isToday = ( ( today.getDate() == dayNumber ) && ( today.getFullYear() == otherday.getFullYear() ) && ( today.getMonth() == otherday.getMonth() ) ) ? true : false;
		
		thisDay = new Date();
		thisDay.setHours( 0 ); thisDay.setMinutes( 0 ); thisDay.setSeconds( 0 );
		thisDay.setFullYear( this.kalendar.kalendarDate.getFullYear(), ( this.kalendar.kalendarDate.getMonth() ), dayNumber );
		
		if ( thisDay.getTime() < notBefore.getTime() )
		{
			dayDiv = this.makeDiv ( "kalendar_day", this.makeAnchor( "kalendar_past_day_number" + ( (isToday) ? " kalendarToday":"" ), newEventPath + strpad( String(this.kalendar.kalendarDate.getMonth()-(-1)), 2, "0") + strpad( String(dayNumber), 2, "0" ) + String(this.kalendar.kalendarDate.getFullYear()), document.createTextNode( dayNumber ) ) );
		}
		else
		{
			dayDiv = this.makeDiv ( "kalendar_day", this.makeAnchor( "kalendar_day_number" + ( (isToday) ? " kalendarToday":"" ), newEventPath + strpad( String(this.kalendar.kalendarDate.getMonth()-(-1)), 2, "0") + strpad( String(dayNumber), 2, "0" ) + String(this.kalendar.kalendarDate.getFullYear()), document.createTextNode( dayNumber ) ) );
		}

		// Check to see if we have any events for this day...
		if ( typeof this.kalendar.kalendarEvents[dayNumber] != 'undefined' )
		{
			// If we do, then grab them and build an event entry for each one
			events = this.kalendar.kalendarEvents[dayNumber];

			if ( events.length > 1 )
			{
				var evtData = "";

				for( var z = 0; z < events.length; z++ )
				{
					evtData += "{ id: \"" + events[z].getEventId() + "\", name: \"" + addslashes( events[z].getDescription() ) + "\", time: \"" + addslashes( events[z].getTime() ) + "\", numdays: " + events[z].getNumDays() + ", location: \"" + addslashes( events[z].getLocation() ) + "\", city: \"" + addslashes( events[z].getCity() ) + "\", state_cd: \"" + addslashes( events[z].getState() ) + "\" }";
					if ( z < ( events.length - 1 ) )
					{
						evtData += ",";
					}
				}

				eventDivAnchor = this.makeAnchor( "", "#", document.createTextNode( events.length + " Events" ) );
				eventDivAnchor.appendChild( document.createElement( "BR" ) );
				eventDivAnchor.appendChild( document.createTextNode( "Click to view" ) );
				eventDivAnchor.onclick = new Function ( "showEvents( { day: " + dayNumber + ", month: '" + this.kalendar.getMonthName() + "', events: [ " + evtData + " ] } ); return false;" );

				eventDiv = this.makeDiv( "kalendar_multiple_events", eventDivAnchor );

				dayDiv.appendChild( eventDiv );
			}
			else
			{
				eventDiv = this.makeDiv( "kalendar_day_entry" );

				if ( noLink )
				{
					eventDiv.appendChild( this.makeTextNode( "kalendar_day_time", document.createTextNode( events[0].getTime() ) ) );
					if ( events[0].getNumDays() > 1 ) {
						eventDiv.appendChild( this.makeTextNode( "kalendar_day_event", document.createTextNode( events[0].getDescription() + " (" + events[0].getNumDays() + " Days)" ) ) );
					} else {
						eventDiv.appendChild( this.makeTextNode( "kalendar_day_event", document.createTextNode( events[0].getDescription() ) ) );
					}
					eventDiv.appendChild( this.makeTextNode( "kalendar_day_location", document.createTextNode( events[0].getDisplayLoc() ) ) );
				}
				else
				{
					eventDiv.appendChild( this.makeAnchor( "kalendar_day_time", evtPath + events[0].getEventId(), document.createTextNode( events[0].getTime() ) ) );
					if ( events[0].getNumDays() > 1 ) {
						eventDiv.appendChild( this.makeAnchor( "kalendar_day_event", evtPath + events[0].getEventId(), document.createTextNode( events[0].getDescription() + " (" + events[0].getNumDays() + " Days)" ) ) );
					} else {
						eventDiv.appendChild( this.makeAnchor( "kalendar_day_event", evtPath + events[0].getEventId(), document.createTextNode( events[0].getDescription() ) ) );
					}
					eventDiv.appendChild( this.makeAnchor( "kalendar_day_location", evtPath + events[0].getEventId(), document.createTextNode( events[0].getDisplayLoc() ) ) );
				}

				dayDiv.appendChild( eventDiv );
			}
		}

		// Save this day
		weekDiv.appendChild( dayDiv );
	}

	// Pad the empty cells at the end of the month
	for( i = dayCounter+1; i < 7; i++ )
	{
		weekDiv.appendChild( this.makeEmptyDiv( "kalendar_day" ) );
	}

	// Close out the week
	weekDiv.appendChild( this.makeEmptyDiv( "kalendar_bottom" ) );

	containerDiv.appendChild( weekDiv );

	// Done.
	return containerDiv;
}


/**
 * Object KalendarSimpleDivRenderer
 * Renders a DIV-marked up calendar for users. Hope you know your CSS.
*/

function KalendarSimpleDivRenderer()
{
	;
}

KalendarSimpleDivRenderer.prototype.setKalendar = function ( pKalendar )
{
	this.kalendar = pKalendar;
}

KalendarSimpleDivRenderer.prototype.makeTextNode = function ( pClassName, pAppend )
{
	 var d = document.createElement( "SPAN" );
	 d.className = pClassName;

	 if ( typeof pAppend != 'undefined' )
	 {
	 	d.appendChild( pAppend );
	 }

	 return d;
}

KalendarSimpleDivRenderer.prototype.makeAnchor = function ( pClassName, pHref, pAppend )
{
	 var d = document.createElement( "A" );
	 d.className = pClassName;
	 d.setAttribute( "href", pHref );

	 if ( typeof pAppend != 'undefined' )
	 {
	 	d.appendChild( pAppend );
	 }

	 return d;
}

KalendarSimpleDivRenderer.prototype.makeDiv = function ( pClassName, pAppend )
{
	var d = document.createElement( "DIV" );
	d.className = pClassName;

	if ( typeof pAppend != 'undefined' )
	{
		d.appendChild( pAppend );
	}

	return d;
}

KalendarSimpleDivRenderer.prototype.makeEmptyDiv = function ( pClassName )
{
	var d = document.createElement( "DIV" );
	d.className = pClassName;

	d.appendChild( document.createTextNode( " " ) );

	return d;
}

// Renders the calendar.
KalendarSimpleDivRenderer.prototype.render = function ( )
{
	var dayCounter = 0;
	var i = 0;
	var j = 0;
	var events = "";
	var themeClass = this.kalendar.config( "theme", "default" ); // We're going to ignore themes in this version.
	var newEventPath = this.kalendar.config( "newEvtPath", "create.php?date=" );
	var eventName = this.kalendar.config( "eventName", "Event" );
	var eventNamePlural = this.kalendar.config( "eventNamePlural", "Events" );
	var noLink = this.kalendar.config( "noLink", false );
	var todaysDate = new Date();
	var forceLink = this.kalendar.config( "forceLink", false );

	var containerDiv = "";
	var weekDiv = "";
	var dayDiv = "";

	var eventDiv = "";
	var eventTimeDiv = "";
	var eventDescDiv = "";
	var eventLocationDiv = "";
	var eventAnchor = "";

	containerDiv = document.createElement( "DIV" );
	containerDiv.setAttribute('id', 'student_calendar' );

	// Output the empty cells at the beginning of the month

	weekDiv = this.makeDiv ( "kalendar_week" );

	for ( i = 0; i < this.kalendar.getFirstDayOfMonth(); i++ )
	{
		weekDiv.appendChild( this.makeEmptyDiv ( "kalendar_day" ) );
	}

	// Output the Meat of the Calendar
	dayCounter = this.kalendar.getFirstDayOfMonth() - 1;

	// Iterate Through Each Day
	for( i = 0; i < this.kalendar.getDaysInMonth(); i++ )
	{
		// Keep Track of The Day of the Week
		dayCounter = ( dayCounter + 1 ) % 7;
		dayNumber = (i-(-1)); // <-- JavaScript's ambiguous addition operator

		if ( dayCounter == 0 && weekDiv.childNodes.length > 0 )
		{
			// If we've wrapped around, go ahead and save this week
			// so we can start a new one.
			weekDiv.appendChild( this.makeEmptyDiv( "kalendar_bottom" ) );

			containerDiv.appendChild( weekDiv );

			weekDiv = this.makeDiv( "kalendar_week" );
		}

		// Create a new day and populate the day number.
		var today = new Date();
		var otherday = this.kalendar.kalendarDate;

		var isToday = ( ( today.getDate() == dayNumber ) && ( today.getFullYear() == otherday.getFullYear() ) && ( today.getMonth() == otherday.getMonth() ) ) ? true : false;


		dayDiv = this.makeDiv ( "kalendar_day", this.makeDiv( "kalendar_day_number" + ( (isToday) ? " kalendarToday":"" ), document.createTextNode( dayNumber ) ) );

		// Check to see if we have any events for this day...
		if ( typeof this.kalendar.kalendarEvents[dayNumber] != 'undefined' )
		{
			// If we do, then grab them and build an event entry for each one
			events = this.kalendar.kalendarEvents[dayNumber];

			if ( events.length == 1 )
			{
				eventDiv = this.makeDiv( "kalendar_day_entry" );
				eventFull = false;
				if ( ( events[0].getEnrollment() - events[0].getCapacity() ) >= 0 ) eventFull = true;

				if ( eventFull )
				{
					eventDiv.appendChild( this.makeTextNode( "kalendar_day_time", document.createTextNode( "FULL" ) ) );
					if ( events[0].getNumDays() > 1 ) {
						eventDiv.appendChild( this.makeTextNode( "kalendar_day_event", document.createTextNode( events[0].getDescription() + " (" + events[0].getNumDays() + " Days)" ) ) );
					} else {
						eventDiv.appendChild( this.makeTextNode( "kalendar_day_event", document.createTextNode( events[0].getDescription() ) ) );
					}
					eventDiv.appendChild( this.makeTextNode( "kalendar_day_location", document.createTextNode( events[0].getDisplayLoc() ) ) );
				}
				else if ( noLink )
				{
					eventDiv.appendChild( this.makeTextNode( "kalendar_day_time", document.createTextNode( events[0].getTime() ) ) );
					if ( events[0].getNumDays() > 1 ) {
						eventDiv.appendChild( this.makeTextNode( "kalendar_day_event", document.createTextNode( events[0].getDescription() + " (" + events[0].getNumDays() + " Days)" ) ) );
					} else {
						eventDiv.appendChild( this.makeTextNode( "kalendar_day_event", document.createTextNode( events[0].getDescription() ) ) );
					}
					eventDiv.appendChild( this.makeTextNode( "kalendar_day_location", document.createTextNode( events[0].getDisplayLoc() ) ) );
				}
				else
				{
					eventDiv.appendChild( this.makeAnchor( "kalendar_day_time", ( forceLink ? forceLink : newEventPath + events[0].getEventId() ), document.createTextNode( events[0].getTime() ) ) );
					if ( events[0].getNumDays() > 1 ) {
						eventDiv.appendChild( this.makeAnchor( "kalendar_day_event",  ( forceLink ? forceLink : newEventPath + events[0].getEventId() ), document.createTextNode( events[0].getDescription() + " (" + events[0].getNumDays() + " Days)" ) ) );
					} else {
						eventDiv.appendChild( this.makeAnchor( "kalendar_day_event",  ( forceLink ? forceLink : newEventPath + events[0].getEventId() ), document.createTextNode( events[0].getDescription() ) ) );
					}
					eventDiv.appendChild( this.makeAnchor( "kalendar_day_location",  ( forceLink ? forceLink : newEventPath + events[0].getEventId() ), document.createTextNode( events[0].getDisplayLoc() ) ) );
				}

				dayDiv.appendChild( eventDiv );
			}
			else
			{
				var evtData = "";
				for ( var j = 0; j < events.length; j++ )
				{
					evtData += "{ id: '" + events[j].getEventId() + "', name: \"" + addslashes(  events[j].getDescription() ) + "\", time: \"" + addslashes( events[j].getTime() ) + "\", numdays: " + events[j].getNumDays() + ", location: \"" + addslashes( events[j].getLocation() ) + "\", city: \"" + addslashes( events[j].getCity() ) + "\", state_cd: \"" + addslashes( events[j].getState() ) + "\"" + ( noLink ? ", noLink: true" : "" ) + " }";
					if ( j < ( events.length - 1 ) )
					{
						evtData += ",";
					}
				}

				eventDiv = document.createElement( "DIV" );
				eventDiv.className = "student_multipleEvents";

				eventAnchor = document.createElement( "A" );
				eventAnchor.setAttribute( "href", "#" );
				eventAnchor.onclick = new Function ( "showEvents( { day: " + dayNumber + ", month: '" + this.kalendar.getMonthName() + "', events: [ " + evtData + " ] } ); return false;" );
				eventAnchor.appendChild( document.createTextNode( events.length  + " " + eventNamePlural ) );
				eventAnchor.appendChild( document.createElement( "BR" ) );
				eventAnchor.appendChild( document.createTextNode( "Click to View" ) );

				eventDiv.appendChild( eventAnchor );

				dayDiv.appendChild( eventDiv );
			}
		}

		// Save this day
		weekDiv.appendChild( dayDiv );
	}

	// Pad the empty cells at the end of the month
	for( i = dayCounter+1; i < 7; i++ )
	{
		weekDiv.appendChild( this.makeEmptyDiv( "kalendar_day" ) );
	}

	// Close out the week
	weekDiv.appendChild( this.makeEmptyDiv( "kalendar_bottom" ) );

	containerDiv.appendChild( weekDiv );

	// Done.
	return containerDiv;
}

/**
 * Object KalendarSmallRenderer
 * Renders a DIV-marked up small calendar "date picker." Hope you know your CSS.
*/

function KalendarSmallRenderer()
{
	;
}

KalendarSmallRenderer.prototype.setKalendar = function ( pKalendar )
{
	this.kalendar = pKalendar;
}

// Renders the calendar.
KalendarSmallRenderer.prototype.render = function ( )
{
	var dayCounter			= 0;
	var i					= 0;
	var j					= 0;
	var events				= "";
	var themeClass			= this.kalendar.config( "theme", "default" ); // We're going to ignore themes in this version.
	var todaysDate			= new Date();
	
	var thisId;

	var calendarContainer;
	var weekHeaderDiv;
	var calendarBody;
	var calendarFooter;
	var weekDiv;
	var dayDiv;
	var dayAnchor;
	var timeContainer;
	var timeHourSelect;
	var timeHourOption;
	var timeMinuteSelect;
	var timeMinuteOption;
	var timeSuffix;
	var timeSuffixOption;
	var hiddenField;

	var navigator;
	var navigatorAnchor;
	var navigatorBody;
	var navigatorTr;
	var navigatorTd;
	
	var notBeforeDate = this.kalendar.config( 'notBefore', 'nodate' );

	var notBefore = new Date();
	notBefore.setHours( 0 ); notBefore.setMinutes( 0 ); notBefore.setSeconds( 0 );

	if ( notBeforeDate != 'nodate' && typeof notBeforeDate != 'object' )
	{
		notBeforeDate = notBeforeDate.split('-');
		notBefore.setFullYear(notBeforeDate[0],(notBeforeDate[1]-(1)),notBeforeDate[2]);
	}
	
	if ( notBefore.getTime() > todaysDate.getTime() )
	{
		notBefore = todaysDate;
	}

	thisId = this.kalendar.config( "id", "calendar" + this.kalendar.kalendarDate.getDate() + "_" + this.kalendar.kalendarDate.getMonth() + "_" + this.kalendar.kalendarDate.getFullYear() );

	calendarContainer = document.createElement("DIV");
	calendarContainer.className = "smallCalendar";
	calendarContainer.setAttribute( "id", thisId );

	navigator = document.createElement( "TABLE" );
	navigatorBody = document.createElement( "TBODY" );

	navigatorTr = document.createElement( "TR" );
	navigatorTd = document.createElement( "TD" );
	navigatorTd.setAttribute( "width", "10%" );
	navigatorAnchor = document.createElement ( "A" );
	navigatorAnchor.className = "smallCalendarHeader";
	navigatorAnchor.appendChild( document.createTextNode( "<<" ) );
	navigatorAnchor.setAttribute( "href", "#" );
	navigatorAnchor.setAttribute( "alt", "Previous Month" );
	navigatorAnchor.setAttribute( "title", "Previous Month" );
	navigatorAnchor.onclick = function ( ) { loadPreviousMonth(thisId); };
	navigatorTd.appendChild( navigatorAnchor );
	navigatorTr.appendChild( navigatorTd );

	navigatorTd = document.createElement( "TD" );
	navigatorTd.setAttribute( "width", "80%" );
	navigatorTd.setAttribute( "align", "center" );
	navigatorTd.appendChild( document.createTextNode( this.kalendar.getMonthName() + " " + this.kalendar.kalendarDate.getFullYear() ) );
	navigatorTr.appendChild( navigatorTd );

	navigatorTd = document.createElement( "TD" );
	navigatorTd.setAttribute( "width", "10%" );

	navigatorAnchor = document.createElement ( "A" );
	navigatorAnchor.className = "smallCalendarHeader";
	navigatorAnchor.appendChild( document.createTextNode( ">>" ) );
	navigatorAnchor.setAttribute( "href", "#" );
	navigatorAnchor.setAttribute( "alt", "Next Month" );
	navigatorAnchor.setAttribute( "title", "Next Month" );
	navigatorAnchor.onclick = function ( ) { loadNextMonth(thisId); };
	navigatorTd.appendChild( navigatorAnchor );
	navigatorTr.appendChild( navigatorTd );

	navigatorBody.appendChild( navigatorTr );
	navigator.appendChild( navigatorBody );

	calendarContainer.appendChild( navigator );

	weekHeaderDiv = document.createElement( "DIV" );
	weekHeaderDiv.className = "smallCalendarHeaderDiv";

	calendarContainer.appendChild( weekHeaderDiv );

	calendarBody = document.createElement( "DIV" );
	calendarBody.className = "smallCalendarBody";

	weekDiv = document.createElement ( "DIV" );
	weekDiv.className = "smallCalendarWeek";

	for ( i = 0; i < this.kalendar.getFirstDayOfMonth(); i++ )
	{
		dayDiv = document.createElement ( "DIV" );
		dayDiv.className = "smallCalendarDay";
		dayDiv.appendChild( document.createTextNode( " " ) );

		weekDiv.appendChild( dayDiv );
	}

	// Output the Meat of the Calendar
	dayCounter = this.kalendar.getFirstDayOfMonth() - 1;

	for ( i = 0; i < this.kalendar.getDaysInMonth(); i++ )
	{
		// Keep Track of The Day of the Week
		dayCounter = ( dayCounter + 1 ) % 7;
		dayNumber = (i-(-1)); // <-- JavaScript's ambiguous addition operator

		if ( dayCounter == 0 )
		{
			// If we've wrapped around, go ahead and save this week
			// so we can start a new one.
			calendarBody.appendChild ( weekDiv );

			weekDiv = document.createElement( "DIV" );
			weekDiv.className = "smallCalendarWeek";
		}

		dayDiv = document.createElement( "DIV" );
		dayDiv.className = "smallCalendarDay";

		var dayDivId = thisId + "_" + strpad( dayNumber, 2, '0') + strpad( this.kalendar.kalendarDate.getMonth()-(-1), 2, '0') + this.kalendar.kalendarDate.getFullYear();
		dayDiv.setAttribute( "id", dayDivId );

		thisDay = new Date();
		thisDay.setHours( 0 ); thisDay.setMinutes( 0 ); thisDay.setSeconds( 0 );
		thisDay.setFullYear( this.kalendar.kalendarDate.getFullYear(), ( this.kalendar.kalendarDate.getMonth() ), dayNumber );


		dayAnchor = document.createElement( "A" );
		if ( thisDay.getTime() < notBefore.getTime() )
		{
			dayAnchor.className = "smallCalendarPastDayLink";
		}
		else
		{
			dayAnchor.className = "smallCalendarDayLink";
		}
		dayAnchor.setAttribute( "href", "#" );
		dayAnchor.setAttribute( "alt", "Use This Date" );
		dayAnchor.setAttribute( "title", "Use This Date" );
		var thisMonth = this.kalendar.kalendarDate.getMonth();
		var thisYear = this.kalendar.kalendarDate.getFullYear();
		dayAnchor.onclick = new Function( "kalendarSaveDate('" + thisId + "'," + dayNumber + "," + thisMonth + "," + thisYear + "); kalendarProcessDate('" + thisId + "'); return false;" );
		dayAnchor.appendChild( document.createTextNode( dayNumber ) );
		dayDiv.appendChild( dayAnchor );
		weekDiv.appendChild( dayDiv );
	}

	// Pad the empty cells at the end of the month
	for( i = dayCounter+1; i < 7; i++ )
	{
		dayDiv = document.createElement( "DIV" );
		dayDiv.className = "smallCalendarDay";
		dayDiv.appendChild( document.createTextNode( " " ) );

		weekDiv.appendChild( dayDiv );
	}

	calendarBody.appendChild( weekDiv );

	calendarFooter = document.createElement( "DIV" );
	calendarFooter.className = "smallCalendarFooter";

	calendarBody.appendChild( calendarFooter );
	calendarContainer.appendChild( calendarBody );

	timeContainer = document.createElement( "DIV" );
	timeContainer.className = "smallCalendarTime";

	timeLabel = document.createElement( "DIV" );
	timeLabel.className = "smallCalendarTimeLabel";
	timeLabel.appendChild( document.createTextNode( "START TIME:" ) );
	timeContainer.appendChild( timeLabel );

	timeHourSelect = document.createElement( "SELECT" );
	timeHourSelect.setAttribute( "id", thisId + "_hour" );
	timeHourSelect.onchange = function ( ) { kalendarProcessDate(thisId);return false; };

	timeHourOption = document.createElement( "OPTION" );
	timeHourOption.setAttribute( "value", "" );
	timeHourOption.appendChild( document.createTextNode( "" ) );
	timeHourSelect.appendChild( timeHourOption );

	for ( i = 1; i <= 12; i++ )
	{
		timeHourOption = document.createElement( "OPTION" );
		timeHourOption.setAttribute( "value", i );
		timeHourOption.appendChild( document.createTextNode( i ) );
		timeHourSelect.appendChild( timeHourOption );
	}
	timeHourSelect.onchange = function ( ) {
		if ( document.getElementById( thisId + "_minute" ).value == "" ) {
			document.getElementById( thisId + "_minute" ).value = "00";
		}
	};
	timeContainer.appendChild( timeHourSelect );

	timeContainer.appendChild( document.createTextNode( ":" ) );

	timeMinuteSelect = document.createElement( "SELECT" );
	timeMinuteSelect.setAttribute( "id", thisId + "_minute" );
	timeMinuteSelect.onchange = function ( ) { kalendarProcessDate(thisId);return false; };

	timeMinuteOption = document.createElement( "OPTION" );
	timeMinuteOption.setAttribute( "value", "" );
	timeMinuteOption.appendChild( document.createTextNode( "" ) );
	timeMinuteSelect.appendChild( timeMinuteOption );

	timeMinuteOption = document.createElement( "OPTION" );
	timeMinuteOption.setAttribute( "value", '00' );
	timeMinuteOption.appendChild( document.createTextNode( '00' ) );
	timeMinuteSelect.appendChild( timeMinuteOption );

	timeMinuteOption = document.createElement( "OPTION" );
	timeMinuteOption.setAttribute( "value", '15' );
	timeMinuteOption.appendChild( document.createTextNode( '15' ) );
	timeMinuteSelect.appendChild( timeMinuteOption );

	timeMinuteOption = document.createElement( "OPTION" );
	timeMinuteOption.setAttribute( "value", '30' );
	timeMinuteOption.appendChild( document.createTextNode( '30' ) );
	timeMinuteSelect.appendChild( timeMinuteOption );

	timeMinuteOption = document.createElement( "OPTION" );
	timeMinuteOption.setAttribute( "value", '45' );
	timeMinuteOption.appendChild( document.createTextNode( '45' ) );
	timeMinuteSelect.appendChild( timeMinuteOption );

	timeContainer.appendChild( timeMinuteSelect );

	timeSuffix = document.createElement( "SELECT" );
	timeSuffix.setAttribute( "id", thisId + "_suffix" );
	timeSuffix.onchange = function ( ) { kalendarProcessDate(thisId);return false; };

	timeSuffixOption = document.createElement( "OPTION" );
	timeSuffixOption.setAttribute( "value", "" );
	timeSuffixOption.appendChild( document.createTextNode( "" ) );
	timeSuffix.appendChild( timeSuffixOption );

	timeSuffixOption = document.createElement( "OPTION" );
	timeSuffixOption.setAttribute( "value", "AM" );
	timeSuffixOption.appendChild( document.createTextNode( "AM" ) );
	timeSuffix.appendChild( timeSuffixOption );

	timeSuffixOption = document.createElement( "OPTION" );
	timeSuffixOption.setAttribute( "value", "PM" );
	timeSuffixOption.appendChild( document.createTextNode( "PM" ) );
	timeSuffix.appendChild( timeSuffixOption );
	timeContainer.appendChild( timeSuffix );

	calendarContainer.appendChild( timeContainer );

	timeContainer = document.createElement( "DIV" );
	timeContainer.className = "smallCalendarTime";

	timeLabel = document.createElement( "DIV" );
	timeLabel.className = "smallCalendarTimeLabel";
	timeLabel.appendChild( document.createTextNode( "END TIME:" ) );
	timeContainer.appendChild( timeLabel );

	timeHourSelect = document.createElement( "SELECT" );
	timeHourSelect.setAttribute( "id", thisId + "_end_hour" );
	timeHourSelect.onchange = function ( ) {
		if ( document.getElementById( thisId + "_end_minute" ).value == "" ) {
			document.getElementById( thisId + "_end_minute" ).value = "00";
		}
		if ( document.getElementById( thisId + "_suffix" ).value == "PM" ) {
			document.getElementById( thisId + "_end_suffix" ).value = "PM";
		}
		kalendarProcessDate(thisId);return false;
	};

	timeHourOption = document.createElement( "OPTION" );
	timeHourOption.setAttribute( "value", "" );
	timeHourOption.appendChild( document.createTextNode( "" ) );
	timeHourSelect.appendChild( timeHourOption );

	for ( i = 1; i <= 12; i++ )
	{
		timeHourOption = document.createElement( "OPTION" );
		timeHourOption.setAttribute( "value", i );
		timeHourOption.appendChild( document.createTextNode( i ) );
		timeHourSelect.appendChild( timeHourOption );
	}
	timeContainer.appendChild( timeHourSelect );

	timeContainer.appendChild( document.createTextNode( ":" ) );

	timeMinuteSelect = document.createElement( "SELECT" );
	timeMinuteSelect.setAttribute( "id", thisId + "_end_minute" );
	timeMinuteSelect.onchange = function ( ) { kalendarProcessDate(thisId);return false; };

	timeMinuteOption = document.createElement( "OPTION" );
	timeMinuteOption.setAttribute( "value", "" );
	timeMinuteOption.appendChild( document.createTextNode( "" ) );
	timeMinuteSelect.appendChild( timeMinuteOption );

	timeMinuteOption = document.createElement( "OPTION" );
	timeMinuteOption.setAttribute( "value", '00' );
	timeMinuteOption.appendChild( document.createTextNode( '00' ) );
	timeMinuteSelect.appendChild( timeMinuteOption );

	timeMinuteOption = document.createElement( "OPTION" );
	timeMinuteOption.setAttribute( "value", '15' );
	timeMinuteOption.appendChild( document.createTextNode( '15' ) );
	timeMinuteSelect.appendChild( timeMinuteOption );

	timeMinuteOption = document.createElement( "OPTION" );
	timeMinuteOption.setAttribute( "value", '30' );
	timeMinuteOption.appendChild( document.createTextNode( '30' ) );
	timeMinuteSelect.appendChild( timeMinuteOption );

	timeMinuteOption = document.createElement( "OPTION" );
	timeMinuteOption.setAttribute( "value", '45' );
	timeMinuteOption.appendChild( document.createTextNode( '45' ) );
	timeMinuteSelect.appendChild( timeMinuteOption );

	timeContainer.appendChild( timeMinuteSelect );

	timeSuffix = document.createElement( "SELECT" );
	timeSuffix.setAttribute( "id", thisId + "_end_suffix" );
	timeSuffix.onchange = function ( ) { kalendarProcessDate(thisId);return false; };

	timeSuffixOption = document.createElement( "OPTION" );
	timeSuffixOption.setAttribute( "value", "" );
	timeSuffixOption.appendChild( document.createTextNode( "" ) );
	timeSuffix.appendChild( timeSuffixOption );

	timeSuffixOption = document.createElement( "OPTION" );
	timeSuffixOption.setAttribute( "value", "AM" );
	timeSuffixOption.appendChild( document.createTextNode( "AM" ) );
	timeSuffix.appendChild( timeSuffixOption );

	timeSuffixOption = document.createElement( "OPTION" );
	timeSuffixOption.setAttribute( "value", "PM" );
	timeSuffixOption.appendChild( document.createTextNode( "PM" ) );
	timeSuffix.appendChild( timeSuffixOption );

	timeContainer.appendChild( timeSuffix );

	calendarContainer.appendChild( timeContainer );

	hiddenField = document.createElement( "INPUT" );
	hiddenField.setAttribute( "type", "hidden" );
	hiddenField.setAttribute( "id", thisId + "_date" );
	hiddenField.setAttribute( "value", this.kalendar.kalendarDate.getDate() + ";" + (this.kalendar.kalendarDate.getMonth()-(-1)) + ";" + this.kalendar.kalendarDate.getFullYear() );
	calendarContainer.appendChild( hiddenField );

	hiddenField = document.createElement( "INPUT" );
	hiddenField.setAttribute( "type", "hidden" );
	hiddenField.setAttribute( "id", thisId + "_currentMonth" );
	hiddenField.setAttribute( "value", ( this.kalendar.kalendarDate.getMonth() - ( -1 ) ) );
	calendarContainer.appendChild( hiddenField );

	hiddenField = document.createElement( "INPUT" );
	hiddenField.setAttribute( "type", "hidden" );
	hiddenField.setAttribute( "id", thisId + "_currentYear" );
	hiddenField.setAttribute( "value", this.kalendar.kalendarDate.getFullYear() );
	calendarContainer.appendChild( hiddenField );

	return calendarContainer;
}


// Public Event Handlers

function kalendarHighLightDates ( pCalId )
{
	var dateStamp = document.getElementById( pCalId + "_date" ).value;
	dateStamp = dateStamp.split(";");

	var hlDays = document.getElementsByClassName("smallCalendarDayHighlight");
	for ( var i=0; i < hlDays.length; i++ )
	{
		document.getElementById( hlDays[i].id ).className = "smallCalendarDay";
	}

	var hlDate = pCalId + "_" + strpad( dateStamp[0], 2, '0' ) + strpad( dateStamp[1], 2, '0' ) + dateStamp[2];
	if ( document.getElementById( hlDate ) )
	{
		document.getElementById( hlDate ).className = 'smallCalendarDayHighlight';
	}
}

function kalendarSaveDate ( pCalId, pDay, pMonth, pYear )
{
	document.getElementById( pCalId + "_date" ).value = pDay + ";" + (pMonth-(-1)) + ";" + pYear;
}

function kalendarEventDateAdd ( pCalId, pStorageId )
{
	var dateStamp = document.getElementById( pCalId + "_date" ).value;
	dateStamp = dateStamp.split(";");

	var date_hour = document.getElementById( pCalId + "_hour" ).value;
	var date_minute = document.getElementById( pCalId + "_minute" ).value;
	var date_suffix = document.getElementById( pCalId + "_suffix" ).value;
	var date_end_hour = document.getElementById( pCalId + "_end_hour" ).value;
	var date_end_minute = document.getElementById( pCalId + "_end_minute" ).value;
	var date_end_suffix = document.getElementById( pCalId + "_end_suffix" ).value;

	var date_hour_24 = date_hour-0;
	if ( (date_suffix == "PM") && (date_hour_24 < 12) ) date_hour_24 += 12;
	var date_end_hour_24 = date_end_hour-0;
	if ( (date_end_suffix == "PM") && (date_end_hour_24 < 12) ) date_end_hour_24 += 12;

	if ( ! ( date_hour && date_minute && date_suffix &&
	         date_end_hour && date_end_minute && date_end_suffix ) )
	{
		alert ("Enter a valid start and end time");
		return false;
	}

	if ( date_end_hour_24 <= date_hour_24 )
	{
		if ( date_end_minute <= date_minute )
		{
			if ( ( date_end_hour_24 == date_hour_24) && (date_end_minute == date_minute ) )
			{
				if ( ! confirm ("Are you sure that you want the starting and ending times to be the same?") )
				{
					return false;
				}
			} else {
				alert ("The ending time must be greater than the starting time");
				return false;
			}
		}
	}

	var newEventDate = new Array();
	newEventDate = {  "year":dateStamp[2],
	                  "month":dateStamp[1],
	                  "day": dateStamp[0],
	                  "hour": date_hour,
	                  "minute": date_minute,
	                  "suffix": date_suffix,
	                  "end_hour": date_end_hour,
	                  "end_minute": date_end_minute,
	                  "end_suffix": date_end_suffix };

	var currEventDates = document.getElementById( pStorageId ).value;
	if ( currEventDates != "" )
	{
		currEventDates = currEventDates.evalJSON();
	}
	if ( ! Object.isArray(currEventDates) )
	{
		currEventDates = new Array();
	}

	var eventDates = new Array();
	var newYMD = newEventDate.year+strpad( newEventDate.month, 2, '0' )+strpad( newEventDate.day, 2, '0' );
	var newEventDateAdded = false;
	for ( var i=0; i < currEventDates.length; i++ )
	{
		var thisYMD = currEventDates[i].year+strpad( currEventDates[i].month, 2, '0' )+strpad( currEventDates[i].day, 2, '0' );
		if ( newYMD == thisYMD )
		{
			newEventDateAdded = true;
			eventDates.push(newEventDate);
		}
		else if ( ! newEventDateAdded && ( newYMD < thisYMD ) )
		{
			newEventDateAdded = true;
			eventDates.push(newEventDate);
			eventDates.push(currEventDates[i]);
		}
		else
		{
			eventDates.push(currEventDates[i]);
		}
	}
	if ( ! newEventDateAdded )
	{
		eventDates.push(newEventDate);
	}

	for ( var i=0; i < eventDates.length; i++ )
	{
		eventDate = new Date(eventDates[i].year, strpad( eventDates[i].month-1, 2, '0' ), strpad( eventDates[i].day, 2, '0' ));
		if (sDate == undefined){
			var sDate = eventDate;
		}
		if (eDate == undefined){
			var eDate = eventDate;
		}

		if (eventDate<sDate){
			sDate = eventDate;
		}
		if (eventDate>eDate){
			eDate = eventDate;
		}
	}
	$('event_start_date').value = sDate.getFullYear()+'-'+(1*sDate.getMonth()+1)+'-'+sDate.getDate();
	$('event_end_date').value = eDate.getFullYear()+'-'+(1*eDate.getMonth()+1)+'-'+eDate.getDate();

	var eventDates_json = Object.toJSON( eventDates );
	document.getElementById( pStorageId ).value = eventDates_json;

	updateOptions(true);
	kalendarEventDateDisplay ( pCalId, pStorageId );
}

function kalendarEventDateRemove ( pCalId, pStorageId, pDate )
{
	var currEventDates = document.getElementById( pStorageId ).value;
	if ( currEventDates != "" )
	{
		currEventDates = currEventDates.evalJSON();
	}
	if ( ! Object.isArray(currEventDates) )
	{
		currEventDates = new Array();
	}

	var eventDates = new Array();
	for ( var i=0; i < currEventDates.length; i++ )
	{
		if ( pDate != (currEventDates[i].year+currEventDates[i].month+currEventDates[i].day) )
		{
			eventDates.push(currEventDates[i]);
		}
	}

	for ( var i=0; i < eventDates.length; i++ )
	{
		eventDate = new Date(eventDates[i].year, strpad( eventDates[i].month-1, 2, '0' ), strpad( eventDates[i].day, 2, '0' ));
		if (sDate == undefined){
			var sDate = eventDate;
		}
		if (eDate == undefined){
			var eDate = eventDate;
		}

		if (eventDate<sDate){
			sDate = eventDate;
		}
		if (eventDate>eDate){
			eDate = eventDate;
		}
	}
	$('event_start_date').value = sDate.getFullYear()+'-'+(1*sDate.getMonth()+1)+'-'+sDate.getDate();
	$('event_end_date').value = eDate.getFullYear()+'-'+(1*eDate.getMonth()+1)+'-'+eDate.getDate();

	var eventDates_json = Object.toJSON( eventDates );
	document.getElementById( pStorageId ).value = eventDates_json;

	updateOptions(true);
	kalendarEventDateDisplay ( pCalId, pStorageId );
}

function kalendarEventDateCheck ( pStorageId )
{
	var eventDates = document.getElementById( pStorageId ).value;
	if ( eventDates != "" )
	{
		eventDates = eventDates.evalJSON();
	}
	if ( ! Object.isArray(eventDates) || (eventDates.length == 0) )
	{
		alert("Please set the date and time");
		return false;
	}
	return true;
}

function kalendarEventDateDisplay ( pCalId, pStorageId )
{
	var dateStamp = document.getElementById( pCalId + "_date" ).value;
	dateStamp = dateStamp.split(";");
	var date = new Date( strpad( dateStamp[1], 2, '0' ) + "/" + strpad( dateStamp[0], 2, '0' ) + "/" + dateStamp[2] );

	var months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];

	timeStamp = document.getElementById( pCalId + "_hour" ).value + ":" + document.getElementById( pCalId + "_minute" ).value + " " + document.getElementById( pCalId + "_suffix" ).value;
	timeStamp_end = document.getElementById( pCalId + "_end_hour" ).value + ":" + document.getElementById( pCalId + "_end_minute" ).value + " " + document.getElementById( pCalId + "_end_suffix" ).value;

	var eventDates = document.getElementById( pStorageId ).value;
	if ( eventDates != "" )
	{
		eventDates = eventDates.evalJSON();
	}
	if ( ! Object.isArray(eventDates) )
	{
		eventDates = new Array();
	}

	document.getElementById( pCalId + "_display" ).innerHTML = "";
	for ( var i=0; i < eventDates.length; i++ )
	{
		var dateYMD = eventDates[i].year + eventDates[i].month + eventDates[i].day;
		var dateStamp = eventDates[i].month + '/' + eventDates[i].day + '/' + eventDates[i].year;
		var timeStamp = eventDates[i].hour + ':' + eventDates[i].minute + ' ' + eventDates[i].suffix;
		var timeStamp_end = eventDates[i].end_hour + ':' + eventDates[i].end_minute + ' ' + eventDates[i].end_suffix;

		document.getElementById( pCalId + "_display" ).innerHTML += "<div>";
		document.getElementById( pCalId + "_display" ).innerHTML += dateStamp + ' - ' + timeStamp + ' to ' + timeStamp_end + "</a></div>";
		document.getElementById( pCalId + "_display" ).innerHTML += "<span style=\"color:gray;padding:0 5px 0 5px;\">|</span>";
		document.getElementById( pCalId + "_display" ).innerHTML += "<a href=\"#\" onclick=\"kalendarEventDateRemove('datePicker', 'event_schedule', '" + dateYMD + "');\">Remove</a>";
		document.getElementById( pCalId + "_display" ).innerHTML += "</div>";
	}

	if ( eventDates.length == 0 )
	{
		document.getElementById( pCalId + "_display" ).innerHTML += "<div>";
		document.getElementById( pCalId + "_display" ).innerHTML += "<span style=\"font-style:italic;color:red;\">None - Use the \"Add Event Date\" button</span>";
		document.getElementById( pCalId + "_display" ).innerHTML += "</div>";
	}
}

function kalendarProcessDate ( pCalId )
{
	var dateStamp = document.getElementById( pCalId + "_date" ).value;
	var months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
	var weekDays = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ];

	dateStamp = dateStamp.split(";");

	var date = new Date( strpad( dateStamp[1], 2, '0' ) + "/" + strpad( dateStamp[0], 2, '0' ) + "/" + dateStamp[2] );

	timeStamp = document.getElementById( pCalId + "_hour" ).value + ":" + document.getElementById( pCalId + "_minute" ).value + " " + document.getElementById( pCalId + "_suffix" ).value;
	timeStamp_end = document.getElementById( pCalId + "_end_hour" ).value + ":" + document.getElementById( pCalId + "_end_minute" ).value + " " + document.getElementById( pCalId + "_end_suffix" ).value;

	dateStamp = months[date.getMonth()] + " " + date.getDate() + ", " + date.getFullYear();

	var location = document.getElementById('location_id').value;
	var exclude_ids = ( document.getElementById('event_id') != null ) ? document.getElementById('event_id').value : null;

	kalendarHighLightDates( pCalId );
	check_for_overlap( location, dateStamp + " " + timeStamp, exclude_ids );
}

function loadNextMonth ( pCalId )
{
	var cal = document.getElementById( pCalId );

	var currentDate = document.getElementById(pCalId + "_date").value;
	var currentMonth = document.getElementById( pCalId + "_currentMonth" ).value;
	var currentYear = document.getElementById( pCalId + "_currentYear" ).value;

	if ( currentMonth == 12 )
	{
		var newMonth = 1;
		var newYear = ++currentYear;
	}
	else
	{
		var newMonth = ++currentMonth;
		var newYear = currentYear;
	}

	var d = new Date( strpad( newMonth, 2, '0' ) + "/01/" + newYear );

	cal.parentNode.removeChild( cal.parentNode.firstChild );

	var k = new Kalendar( d, { renderer: new KalendarSmallRenderer(), id: 'datePicker' } );

	var calendar = k.renderCalendar();

	document.getElementById('datetime_container').appendChild( calendar );

	document.getElementById( pCalId + '_date').value = currentDate;
	kalendarHighLightDates( pCalId );
}

function loadPreviousMonth ( pCalId )
{
	var cal = document.getElementById( pCalId );

	var currentDate = document.getElementById(pCalId + "_date").value;
	var currentMonth = document.getElementById( pCalId + "_currentMonth" ).value;
	var currentYear = document.getElementById( pCalId + "_currentYear" ).value;

	if ( currentMonth == 1 )
	{
		var newMonth = 12;
		var newYear = --currentYear;
	}
	else
	{
		var newMonth = --currentMonth;
		var newYear = currentYear;
	}

	var d = new Date( strpad( newMonth, 2, '0' ) + "/01/" + newYear );

	cal.parentNode.removeChild( cal.parentNode.firstChild );

	var k = new Kalendar( d, { renderer: new KalendarSmallRenderer(), id: 'datePicker' } );

	var calendar = k.renderCalendar();

	document.getElementById('datetime_container').appendChild( calendar );

	document.getElementById( pCalId + '_date').value = currentDate;
	kalendarHighLightDates( pCalId );
}

/**
 * Object KalendarListRenderer
 * Renders a DIV-marked up small calendar "date picker." Hope you know your CSS.
*/

function KalendarListRenderer()
{
	;
}

KalendarListRenderer.prototype.setKalendar = function ( pKalendar )
{
	this.kalendar = pKalendar;
}

// Renders the calendar.
KalendarListRenderer.prototype.render = function ( )
{
	var daysInMonth = this.kalendar.getDaysInMonth();
	var evtPath = this.kalendar.config( "evtPath", "/" );
	var newEventPath = this.kalendar.config( "newEvtPath", "/" );
	var noLink = this.kalendar.config( "noLink", false );
	var kalendarKontainer = "";
	var kalendarHeader = "";
	var kalendarEntryDesc = "";
	var kalendarEntryTime = "";
	var kalendarEntryLoc = "";
	var kalendarEntryContainer = "";
	var kalendarEntryClearer = "";
	var kalendarCreateEvent = "";
	var kalendarAnchor = "";

	kalendarKontainer = document.createElement( "DIV" );

	for ( var i = 0; i <= daysInMonth; i++ )
	{
		if ( typeof this.kalendar.kalendarEvents[i] != 'undefined' )
		{
			kalendarHeader = document.createElement( "H3" );
			kalendarHeader.appendChild( document.createTextNode( this.kalendar.getDayOfWeek(new Date(this.kalendar.getMonthName() + " " + i + ", " + this.kalendar.kalendarDate.getFullYear())) + ", " + this.kalendar.getMonthName() + " " + i ) );

			kalendarKontainer.appendChild( kalendarHeader );
			events = this.kalendar.kalendarEvents[i];

			for ( var j = 0; j < events.length; j++ )
			{
				kalendarEntryContainer = document.createElement( "DIV" );
				kalendarEntryContainer.className = "kalendarListContainer";

				kalendarEntryTime = document.createElement( "DIV" );
				kalendarEntryTime.className = "kalendarListTime";
				if ( noLink )
				{
					kalendarEntryTime.appendChild( document.createTextNode( events[j].getTime() ) );
				}
				else
				{
					kalendarAnchor = document.createElement( "A" );
					kalendarAnchor.setAttribute( "href", evtPath + events[j].getEventId() );
					kalendarAnchor.appendChild( document.createTextNode( events[j].getTime() ) );
					kalendarEntryTime.appendChild( kalendarAnchor );
				}

				kalendarEntryDesc = document.createElement( "DIV" );
				kalendarEntryDesc.className = "kalendarListDesc";
				if ( noLink )
				{
					if ( events[j].getNumDays() > 1 ) {
					kalendarEntryDesc.appendChild( document.createTextNode( events[j].getDescription() + " (" + events[j].getNumDays() + " Days)" ) );
					} else {
					kalendarEntryDesc.appendChild( document.createTextNode( events[j].getDescription() ) );
					}
				}
				else
				{
					kalendarAnchor = document.createElement( "A" );
					kalendarAnchor.setAttribute( "href", evtPath + events[j].getEventId() );
					if ( events[j].getNumDays() > 1 ) {
						kalendarAnchor.appendChild( document.createTextNode( events[j].getDescription() + " (" + events[j].getNumDays() + " Days)" ) );
					} else {
						kalendarAnchor.appendChild( document.createTextNode( events[j].getDescription() ) );
					}
					kalendarEntryDesc.appendChild( kalendarAnchor );
				}


				kalendarEntryLoc = document.createElement( "DIV" );
				kalendarEntryLoc.className = "kalendarListLoc";
				if ( noLink )
				{
					kalendarEntryLoc.appendChild( document.createTextNode( events[j].getLocation() ) );
				}
				else
				{
					kalendarAnchor = document.createElement( "A" );
					kalendarAnchor.setAttribute( "href", evtPath + events[j].getEventId() );
					kalendarAnchor.appendChild( document.createTextNode( events[j].getLocation() ) );
					kalendarEntryLoc.appendChild( kalendarAnchor );
				}

				kalendarEntryClearer = document.createElement( "DIV" );
				kalendarEntryClearer.className = "clearer";
				kalendarEntryClearer.appendChild( document.createTextNode( " " ) );

				kalendarEntryContainer.appendChild( kalendarEntryTime );
				kalendarEntryContainer.appendChild( kalendarEntryDesc );
				kalendarEntryContainer.appendChild( kalendarEntryLoc );
				kalendarEntryContainer.appendChild( kalendarEntryClearer );

				kalendarKontainer.appendChild( kalendarEntryContainer );
			}

			kalendarCreateEvent = document.createElement( "A" );
			kalendarCreateEvent.className = "calendarListNewEventLink";
			kalendarCreateEvent.setAttribute( "href", newEventPath + ( strpad( this.kalendar.kalendarDate.getMonth()-(-1), 2, '0') ) + strpad( i, 2, '0' ) + this.kalendar.kalendarDate.getFullYear() );
			kalendarCreateEvent.appendChild( document.createTextNode( "Add Event" ) );

			kalendarKontainer.appendChild( kalendarCreateEvent );

		}
	}

	return kalendarKontainer;
}

function KalendarSimpleListRenderer()
{
	;
}

KalendarSimpleListRenderer.prototype.setKalendar = function ( pKalendar )
{
	this.kalendar = pKalendar;
}

// Renders the calendar.
KalendarSimpleListRenderer.prototype.render = function ( )
{
	var daysInMonth = this.kalendar.getDaysInMonth();
	var evtPath = this.kalendar.config( "newEvtPath", "/" );
	var forceLink = this.kalendar.config( "forceLink", false );
	var noLink = this.kalendar.config( "noLink", false );
	var kalendarKontainer = "";
	var kalendarHeader = "";
	var kalendarEntryDesc = "";
	var kalendarEntryTime = "";
	var kalendarEntryLoc = "";
	var kalendarEntryContainer = "";
	var kalendarEntryClearer = "";
	var kalendarCreateEvent = "";
	var kalendarAnchor = "";

	kalendarKontainer = document.createElement( "DIV" );
	kalendarKontainer.setAttribute( "id", "student_calendar" );

	for ( var i = 0; i <= daysInMonth; i++ )
	{
		if ( typeof this.kalendar.kalendarEvents[i] != 'undefined' )
		{
			kalendarHeader = document.createElement( "H3" );
			kalendarHeader.appendChild( document.createTextNode( this.kalendar.getDayOfWeek(new Date(this.kalendar.getMonthName() + " " + i + ", " + this.kalendar.kalendarDate.getFullYear())) + ", " + this.kalendar.getMonthName() + " " + i ) );

			kalendarKontainer.appendChild( kalendarHeader );
			events = this.kalendar.kalendarEvents[i];

			for ( var j = 0; j < events.length; j++ )
			{
				kalendarEntryContainer = document.createElement( "DIV" );
				kalendarEntryContainer.className = "kalendarListContainer";

				kalendarEntryTime = document.createElement( "DIV" );
				kalendarEntryTime.className = "kalendarListTime";

				eventFull = false;
				if ( ( events[j].getEnrollment() - events[j].getCapacity() ) >= 0 ) eventFull = true;

				if ( eventFull )
				{
					kalendarEntryTime.appendChild( document.createTextNode( "FULL" ) );
				}
				else if ( noLink )
				{
					kalendarEntryTime.appendChild( document.createTextNode( events[j].getTime() ) );
				}
				else
				{
					kalendarAnchor = document.createElement( "A" );
					kalendarAnchor.setAttribute( "href", ( forceLink ? forceLink : evtPath + events[j].getEventId() ) );
					kalendarAnchor.appendChild( document.createTextNode( events[j].getTime() ) );
					kalendarEntryTime.appendChild( kalendarAnchor );
				}

				kalendarEntryDesc = document.createElement( "DIV" );
				kalendarEntryDesc.className = "kalendarListDesc";
				if ( eventFull || noLink )
				{
					if ( events[j].getNumDays() > 1 ) {
					kalendarEntryDesc.appendChild( document.createTextNode( events[j].getDescription() + " (" + events[j].getNumDays() + " Days)" ) );
					} else {
					kalendarEntryDesc.appendChild( document.createTextNode( events[j].getDescription() ) );
					}
				}
				else
				{
					kalendarAnchor = document.createElement( "A" );
					kalendarAnchor.setAttribute( "href", ( forceLink ? forceLink : evtPath + events[j].getEventId() ) );
					if ( events[j].getNumDays() > 1 ) {
						kalendarAnchor.appendChild( document.createTextNode( events[j].getDescription() + " (" + events[j].getNumDays() + " Days)" ) );
					} else {
						kalendarAnchor.appendChild( document.createTextNode( events[j].getDescription() ) );
					}
					kalendarEntryDesc.appendChild( kalendarAnchor );
				}

				kalendarEntryLoc = document.createElement( "DIV" );
				kalendarEntryLoc.className = "kalendarListLoc";
				if ( eventFull || noLink )
				{
					kalendarEntryLoc.appendChild( document.createTextNode( events[j].getLocation() ) );
					kalendarEntryLoc.appendChild( document.createElement( "BR" ) );
					kalendarEntryLoc.appendChild( document.createTextNode( events[j].getCity() + ", " + events[j].getState() ) );
				}
				else
				{
					kalendarAnchor = document.createElement( "A" );
					kalendarAnchor.setAttribute( "href", ( forceLink ? forceLink : evtPath + events[j].getEventId() ) );
					kalendarAnchor.appendChild( document.createTextNode( events[j].getLocation() ) );
					kalendarEntryLoc.appendChild( kalendarAnchor );
					kalendarEntryLoc.appendChild( document.createElement( "BR" ) );
					kalendarAnchor = document.createElement( "A" );
					kalendarAnchor.setAttribute( "href", ( forceLink ? forceLink : evtPath + events[j].getEventId() ) );
					kalendarAnchor.appendChild( document.createTextNode( events[j].getCity() + ", " + events[j].getState() ) );
					kalendarEntryLoc.appendChild( kalendarAnchor );
				}

				kalendarEntryClearer = document.createElement( "DIV" );
				kalendarEntryClearer.className = "clearer";
				kalendarEntryClearer.appendChild( document.createTextNode( " " ) );

				kalendarEntryContainer.appendChild( kalendarEntryTime );
				kalendarEntryContainer.appendChild( kalendarEntryDesc );
				kalendarEntryContainer.appendChild( kalendarEntryLoc );
				kalendarEntryContainer.appendChild( kalendarEntryClearer );

				kalendarKontainer.appendChild( kalendarEntryContainer );
			}
		}
	}

	return kalendarKontainer;
}
