function addslashes(str) {
  if (str == undefined) {
    return '';
  }
  if (str.length > 0) {
    str=str.replace(/\"/g,'\\"');
  }
  return str;
}

function stripslashes(str) {
  if (str == undefined) {
    return '';
  }
  if (str.length > 0) {
    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, pEventWaitList, pEventSchedule )
{
  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;
  this.waitlist = ( typeof pEventWaitList != "undefined" ) ? pEventWaitList : null;
  this.schedule = ( typeof pEventSchedule != "undefined" ) ? pEventSchedule : 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;
}

/**
 * Getter for Wait List
*/
KalendarEvent.prototype.getWaitList = function ( )
{
  return this.waitlist;
}

/**
 * Getter for Schedule
*/
KalendarEvent.prototype.getSchedule = function ( )
{
  return this.schedule;
}


/**
 * 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 ( noLink )
        {
          if ( ( events[0].getEnrollment() - events[0].getCapacity() ) >= 0 )
          {
            if ( events[0].getWaitList() == 'On' )
            {
              eventDiv.appendChild( this.makeTextNode( "kalendar_day_time", document.createTextNode( "WAIT" ) ) );
            }
            else
            {
              eventDiv.appendChild( this.makeTextNode( "kalendar_day_time", document.createTextNode( "FULL" ) ) );
            }
          }
          else
          {
            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
        {
          if ( ( events[0].getEnrollment() - events[0].getCapacity() ) >= 0 )
          {
            if ( events[0].getWaitList() == 'On' )
            {
              eventDiv.appendChild( this.makeTextNode( "kalendar_day_time", document.createTextNode( "WAIT" ) ) );
            }
            else
            {
              eventDiv.appendChild( this.makeTextNode( "kalendar_day_time", document.createTextNode( "FULL" ) ) );
            }
          }
          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++ )
        {
          var eventFull = false;
          if ( ( events[j].getEnrollment() - events[j].getCapacity() ) >= 0 ) eventFull = true;
          var waitList = (events[j].getWaitList())? ' wait_list: "' + events[j].getWaitList() + '", ': '';
          var fullEvent = ( ( events[j].getEnrollment() - events[j].getCapacity() ) >= 0 )? ' full_event: true, ': ' full_event: false, ';

          evtData += "{ id: '" + events[j].getEventId() + "', name: \"" + addslashes(  events[j].getDescription() ) + "\", time: \"" + addslashes( events[j].getTime() ) + "\", numdays: " + events[j].getNumDays() + ", location: \"" + addslashes( events[j].getLocation() ) + "\", " + waitList + fullEvent + "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:" ) );
  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:" ) );
  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 += "<span class=\"event-date\">" + dateStamp + ' - ' + timeStamp + ' to ' + timeStamp_end + "</span>";
    document.getElementById( pCalId + "_display" ).innerHTML += "<span class=\"event-date-separator\" style=\"color:gray;padding:0 5px 0 5px;\">|</span>";
    document.getElementById( pCalId + "_display" ).innerHTML += "<a class=\"event-date-remove\" 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] );
  var timeStamp = '';
  var timeStamp_end = '';
  if (
  (document.getElementById( pCalId + "_hour" ).value != '') &&
  (document.getElementById( pCalId + "_minute" ).value != '') &&
  (document.getElementById( pCalId + "_suffix" ).value != '')) {
    timeStamp = document.getElementById( pCalId + "_hour" ).value + ":" + document.getElementById( pCalId + "_minute" ).value + " " + document.getElementById( pCalId + "_suffix" ).value;
  }
  if (
  (document.getElementById( pCalId + "_end_hour" ).value != '') &&
  (document.getElementById( pCalId + "_end_minute" ).value != '') &&
  (document.getElementById( pCalId + "_end_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, dateStamp + " " + timeStamp_end, 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;
        var seats_available = events[j].getCapacity() - events[j].getEnrollment();
        if (seats_available < 0) seats_available = 0;

        if ( noLink )
        {
          if ( ( events[j].getEnrollment() - events[j].getCapacity() ) >= 0 )
          {
            if ( events[j].getWaitList() == 'On' )
            {
              kalendarEntryTime.appendChild( document.createTextNode( "WAIT" ) );
            }
            else
            {
              kalendarEntryTime.appendChild( document.createTextNode( "FULL" ) );
            }
          }
          else
          {
            kalendarEntryTime.appendChild( document.createTextNode( events[j].getTime() ) );
            kalendarEntryTime.appendChild( document.createElement( "BR" ) );
            kalendarEntryTime.appendChild( document.createTextNode( seats_available + ' Seats' ) );
          }
        }
        else
        {
          kalendarAnchor = document.createElement( "A" );
          kalendarAnchor.setAttribute( "href", ( forceLink ? forceLink : evtPath + events[j].getEventId() ) );
          if ( ( events[j].getEnrollment() - events[j].getCapacity() ) >= 0 )
          {
            if ( events[j].getWaitList() == 'On' )
            {
              kalendarAnchor.appendChild( document.createTextNode( "WAIT" ) );
            }
            else
            {
              kalendarAnchor.appendChild( document.createTextNode( "FULL" ) );
            }
          }
          else
          {
            kalendarAnchor.appendChild( document.createTextNode( events[j].getTime() ) );
            kalendarAnchor.appendChild( document.createElement( "BR" ) );
            kalendarAnchor.appendChild( document.createTextNode( seats_available + ' Seats' ) );
          }
          kalendarEntryTime.appendChild( kalendarAnchor );
        }

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

        kalendarEntryLoc = document.createElement( "DIV" );
        kalendarEntryLoc.className = "kalendarListLoc";
        if ( 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;
}

