    var calColor = '#000000';
    var displayNumber = 5;
    var events = new Array();
    var eventsDiv;

    function loadCal(div) {
      var url = "http://www.google.com/calendar/feeds/case.edu_gupalc7urm7b82taup5h7vge9s%40group.calendar.google.com/public/full?alt=json-in-script&callback=insertAgenda&orderby=starttime&singleevents=true&sortorder=ascending&futureevents=true";
      eventsDiv = document.getElementById(div);
      var head = document.getElementsByTagName('head')[0];
      var script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = url;
      head.appendChild(script);
    }

    function expandEvent(i) {
      document.getElementById('eventdivtable' + i).style.display = (document.getElementById('eventdivtable' + i).style.display=='block'?'none':'block');
    }

    /**
     * Converts an xs:date or xs:dateTime formatted string into the local timezone
     * and outputs a human-readable form of this date or date/time.
     *
     * @param {string} gCalTime is the xs:date or xs:dateTime formatted string
     * @return {string} is the human-readable date or date/time string
     */
    function formatGCalTime(gCalTime) {
      // text for regex matches
      var remtxt = gCalTime;

      function consume(retxt) {
        var match = remtxt.match(new RegExp('^' + retxt));
        if (match) {
          remtxt = remtxt.substring(match[0].length);
          return match[0];
        }
        return '';
      }

      // minutes of correction between gCalTime and GMT
      var totalCorrMins = 0;

      var year = consume('\\d{4}');
      consume('-?');
      var month = consume('\\d{2}');
      consume('-?');
      var dateMonth = consume('\\d{2}');
      var timeOrNot = consume('T');

      // if a DATE-TIME was matched in the regex
      if (timeOrNot == 'T') {
        var hours = consume('\\d{2}');
        consume(':?');
        var mins = consume('\\d{2}');
        consume('(:\\d{2})?(\\.\\d{3})?');
        var zuluOrNot = consume('Z');

        // if time from server is not already in GMT, calculate offset
        if (zuluOrNot != 'Z') {
          var corrPlusMinus = consume('[\\+\\-]');
          if (corrPlusMinus != '') {
            var corrHours = consume('\\d{2}');
            consume(':?');
            var corrMins = consume('\\d{2}');
            totalCorrMins = (corrPlusMinus=='-' ? 1 : -1) *
                (Number(corrHours) * 60 +
    	    (corrMins=='' ? 0 : Number(corrMins)));
          }
        }

        // get time since epoch and apply correction, if necessary
        // relies upon Date object to convert the GMT time to the local
        // timezone
        var originalDateEpoch = Date.UTC(year, month - 1, dateMonth, hours, mins);
        var gmtDateEpoch = originalDateEpoch + totalCorrMins * 1000 * 60;
        var ld = new Date(gmtDateEpoch);

        // date is originally in YYYY-MM-DD format
        // time is originally in a 24-hour format
        // this converts it to MM/DD hh:mm (AM|PM)
        dateString = ld.getFullYear() + '/' + ((ld.getMonth()<9)?('0' + (ld.getMonth()+1)):(ld.getMonth() + 1)) + '/' + ((ld.getDate()<10)?('0' + ld.getDate()):(ld.getDate()));
        dateString += ' ' + ((ld.getHours()<10)?('0' + ld.getHours()):(ld.getHours())) + ':' + ((ld.getMinutes()<10)?('0' + ld.getMinutes()):(ld.getMinutes()));
      } else {
        // if only a DATE was matched
        dateString =  year + '/' +month + '/' + dateMonth;
      }
      return dateString;
    }

    function gCalTimeToDate(gCalTime) {
      // text for regex matches
      var remtxt = gCalTime;
      var ld;

      function consume(retxt) {
        var match = remtxt.match(new RegExp('^' + retxt));
        if (match) {
          remtxt = remtxt.substring(match[0].length);
          return match[0];
        }
        return '';
      }

      // minutes of correction between gCalTime and GMT
      var totalCorrMins = 0;

      var year = consume('\\d{4}');
      consume('-?');
      var month = consume('\\d{2}');
      consume('-?');
      var dateMonth = consume('\\d{2}');
      var timeOrNot = consume('T');

      // if a DATE-TIME was matched in the regex
      if (timeOrNot == 'T') {
        var hours = consume('\\d{2}');
        consume(':?');
        var mins = consume('\\d{2}');
        consume('(:\\d{2})?(\\.\\d{3})?');
        var zuluOrNot = consume('Z');

        // if time from server is not already in GMT, calculate offset
        if (zuluOrNot != 'Z') {
          var corrPlusMinus = consume('[\\+\\-]');
          if (corrPlusMinus != '') {
            var corrHours = consume('\\d{2}');
            consume(':?');
            var corrMins = consume('\\d{2}');
            totalCorrMins = (corrPlusMinus=='-' ? 1 : -1) *
                (Number(corrHours) * 60 +
    	    (corrMins=='' ? 0 : Number(corrMins)));
          }
        }

        // get time since epoch and apply correction, if necessary
        // relies upon Date object to convert the GMT time to the local
        // timezone
        var originalDateEpoch = Date.UTC(year, month - 1, dateMonth, hours, mins);
        var gmtDateEpoch = originalDateEpoch + totalCorrMins * 1000 * 60;
        ld = new Date(gmtDateEpoch);
      } else {
        ld = new Date(year, month-1, dateMonth);
      }
      return ld;
    }

    /**
     * Creates an unordered list of events in a human-readable form
     *
     * @param {json} root is the root JSON-formatted content from GData
     * @param {string} divId is the div in which the events are added
     */
    function listEvents(root) {
      var feed = root.feed;
      var calTitle = feed.title.$t;
      var calId = feed.id.$t;
      var calLink = "";

      for (var linkcnt = 0; linkcnt < feed.link.length; linkcnt++) {
        if (feed.link[linkcnt]['type'] == 'text/html' && feed.link[linkcnt]['rel'] == 'alternate') {
          calLink = feed.link[linkcnt]['href'];
        }
      }

      // create a new unordered list
      // loop through each event in the feed
      for (var i = 0; i < feed.entry.length; i++) {
        var entry = feed.entry[i];
        var title = entry.title.$t;
        var start = entry['gd$when'][0].startTime;
        var end = entry['gd$when'][0].endTime;
        var entryLinkHref = "";
        // get the URL to link to the event
        for (var linki = 0; linki < entry['link'].length; linki++) {
          if (entry['link'][linki]['type'] == 'text/html' && entry['link'][linki]['rel'] == 'alternate') {
            entryLinkHref = entry['link'][linki]['href'];
          }
        }
        var content = entry.content.$t;
        var where = entry['gd$where'][0].valueString;
        var dateStart = gCalTimeToDate(start);
        var dateEnd = gCalTimeToDate(end);

        var tempArray = [dateStart, dateEnd, title, calTitle, calColor, entryLinkHref, content, where, calLink];
        while((tempArray[0])<(tempArray[1])) {
          events.push(tempArray);
          tempArray = [new Date(tempArray[0].getFullYear(), tempArray[0].getMonth(), (tempArray[0].getDate()+1)), tempArray[1], tempArray[2], tempArray[3], tempArray[4], tempArray[5], tempArray[6], tempArray[7], tempArray[8]];
        }

      }
      if (events.length != null && events.length >0) {

        events.sort(function (a,b) {
          return a[0] - b[0];
        });
        displayCal();
      }
    }

    function displayCal() {
      var html = "";
      var dateString = '';
      for (var i=0, rowcnt=0; i<events.length && i<displayNumber; i++, rowcnt++) {
        // if we have a link to the event, create an 'a' element
        var isAllDay = 0;
        var tempDateString = events[i][0].toLocaleDateString();
        var dateDisplay = (events[i][0].getMonth()+1) + "/" + events[i][0].getDate() + "/" + (events[i][0].getFullYear());

        if (tempDateString != dateString) {
          dateString = tempDateString;
          rowcnt = 0;
        }

        if ((events[i][0].getHours() == 0) && (events[i][0].getMinutes() == 0) && (events[i][1].getHours() == 0) && (events[i][1].getMinutes() == 0)) {
          isAllDay = 1;
        }
        html += '<li>\n';
        html += '<a href="javascript: expandEvent(' + i + ');">\n';
        html += '<span class="date">' + dateDisplay + '</span>\n';
        html += ' - \n';
        html += events[i][2] + '\n';
        html += '</a>\n';

        var eventStartTime = "";
        var eventEndTime = "";
        eventStartTime = ((events[i][0].getHours()<=12)?(events[i][0].getHours()):(events[i][0].getHours()-12)) +':' + ((events[i][0].getMinutes()<10)?('0' + events[i][0].getMinutes()):(events[i][0].getMinutes())) + ' ' + ((events[i][0].getHours()<=12)?'AM':'PM');
        eventEndTime = ((events[i][1].getHours()<=12)?(events[i][1].getHours()):(events[i][1].getHours()-12)) +':' + ((events[i][1].getMinutes()<10)?('0' + events[i][1].getMinutes()):(events[i][1].getMinutes())) + ' ' + ((events[i][1].getHours()<=12)?'AM':'PM');

        html += '<div id="eventdivtable' + i + '" class="event_expand" style="display: none;">';
        html += '<table style="width: 100%;">'
        if (events[i][0] && events[i][0]!='') {
          html += '<tr>'
          html += '<td class="event_expand_heading">Start:</td><td class="event_expand_text">' + events[i][0].toDateString() + ' ' + eventStartTime + '</td>';
          html += '</tr>';
        }
        if (events[i][1] && events[i][1]!='') {
          html += '<tr>'
          html += '<td class="event_expand_heading">End:</td><td class="event_expand_text">' + events[i][1].toDateString() + ' ' + eventEndTime + '</td>';
          html += '</tr>';
        }
        if (events[i][7] && events[i][7]!='') {
          html += '<tr>'
          html += '<td class="event_expand_heading">Where:</td><td class="event_expand_text">' + events[i][7] + '</td>';
          html += '</tr>';
        }
        if (events[i][6] && events[i][6]!='') {
          //html += '<tr>'
          //html += '<td class="event_expand_heading">Details:</td><td class="event_expand_text">\n' + events[i][6] + '\n</td>';
          //html += '</tr>';
        }
        if (events[i][3] && events[i][3]!='') {
          //html += '<tr>'
          //html += '<td class="event_expand_heading">From:</td><td class="event_expand_text"><a href="' + events[i][8] + '" target="_blank">' + events[i][3] + '</a></td>';
          //html += '</tr>';
        }
        if (events[i][5] && events[i][5]!='') {
          html += '<tr>'
          html += '<td colspan="2" style="text-align: right;"><a href="' + events[i][5] + '" target="_blank">More Details</a></td>';
          html += '</tr>';
        }
        html += '</table>'
        html += '</div>';
        html += '</li>';
      }
      eventsDiv.innerHTML = html;
    }

    /**
     * Callback function for the GData json-in-script call
     * Inserts the supplied list of events into a div of a pre-defined name
     *
     * @param {json} root is the JSON-formatted content from GData
     */
    function insertAgenda(root) {
      listEvents(root);
    }

