$(document).ready(function(){
  displayGoogleCalendarEvents('aopa.australia@gmail.com', 5);
});

function displayGoogleCalendarEvents(account, count) {
	$.getJSON("http://www.google.com/calendar/feeds/"+account+"/public/full?futureevents=true&orderby=starttime&sortorder=a&alt=json-in-script&callback=?",
	  function(json){
      listEvents(json, "google-calendar-events", count);
    }
  );
}

/**
 * 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, divId, count) {
  var feed = root.feed;
  var events = document.getElementById(divId);
 
  if (events.childNodes.length > 0) {
    events.removeChild(events.childNodes[0]);
  }	  
 
  // create a new unordered list
  var ul = document.createElement('ul');
 
  // loop through each event in the feed
  for (var i = 0; (i < feed.entry.length && i < count); 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 where = entry['gd$where'][0].valueString;
    var entry_content = entry.content.$t;
 
    // 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') {
        var entryLinkHref = entry['link'][linki]['href'];
      }
    }
 
    var startDate = parseGCalTime(start);
    var isTime = (start.match('T') ? true : false);
    var startDateString = "";
    if (isTime) {
	    startDateString = startDate.format("D, M j h:iA");
    } else {
	    startDateString = startDate.format("D, M j");
    }

    var endDate = parseGCalTime(end);
    var isTime = (end.match('T') ? true : false);
    var endDateString = "";
    if (isTime) {
	    endDateString = endDate.format("D, M j h:iA");
    } else {
	    endDateString = endDate.format("D, M j");
    }

    calIcon = calendarIcon(startDate);

    var li = document.createElement('li');

    var eventWrapper = document.createElement('div');
    eventWrapper.setAttribute("class", "clearfix");

    var eventDescription = document.createElement('div');
    eventDescription.setAttribute("class", "event-description");
    entryLink = document.createElement('a');
    entryLink.setAttribute('class', 'show-event-full-description');
    entryLink.setAttribute('href', entryLinkHref);
    entryLink.setAttribute('rel', "#event-"+i);
    entryLink.appendChild(document.createTextNode(title));
    eventDescription.appendChild(entryLink);
    var eventLocation = document.createElement("p");
    eventLocation.appendChild(document.createTextNode(where + ' - ' + startDateString));
    eventDescription.appendChild(eventLocation);

    eventWrapper.appendChild(calIcon);
    eventWrapper.appendChild(eventDescription);
    li.appendChild(eventWrapper);

    // full description
    var eventFullDescription = document.createElement('div');
    eventFullDescription.setAttribute("id", "event-"+i);
    eventFullDescription.setAttribute("class", "event-overlay");

    var eventFullDescriptionWrapper =  document.createElement("div");
    eventFullDescriptionWrapper.setAttribute("class", "event-wrapper");

    var eventTitle = document.createElement("h2");
    eventTitle.appendChild(document.createTextNode(title));
    eventFullDescriptionWrapper.appendChild(eventTitle);

    var section =  document.createElement("div");
    section.setAttribute("class", "section");
    var h3 = document.createElement("h3");
    h3.appendChild(document.createTextNode("When"));
    section.appendChild(h3);
    section.appendChild(document.createTextNode(startDateString + " - " + endDateString));
    eventFullDescriptionWrapper.appendChild(section);

    var section =  document.createElement("div");
    section.setAttribute("class", "section");
    var h3 = document.createElement("h3");
    h3.appendChild(document.createTextNode("Where"));
    section.appendChild(h3);
    section.appendChild(document.createTextNode(where));
    eventFullDescriptionWrapper.appendChild(section);

    var h3 = document.createElement("h3");
    h3.appendChild(document.createTextNode("Description"));
    eventFullDescriptionWrapper.appendChild(h3);

    eventFullDescriptionWrapper.appendChild(document.createTextNode(entry_content));
    eventFullDescription.appendChild(eventFullDescriptionWrapper);
    li.appendChild(eventFullDescription);

    // append the list item onto the unordered list
    ul.appendChild(li);
  }
  events.appendChild(ul);
  $("#"+divId).append("<script>$('.show-event-full-description').overlay({mask: '#000', effect: 'apple'});</script>");
}

function calendarIcon(date) {
  month = document.createElement("div");
  month.setAttribute("class", "month");
  month.appendChild(document.createTextNode(date.format("M")));
  day = document.createElement("div");
  day.setAttribute("class", "date");
  day.appendChild(document.createTextNode(date.getDate()));
  cal = document.createElement("div");
  cal.setAttribute("class", "cal-icon");
  cal.appendChild(month);
  cal.appendChild(day);
  return cal;
}

/**
 * Converts an xs:date or xs:dateTime formatted string into Date object in local timezone
 *
 * @param {string} gCalTime is the xs:date or xs:dateTime formatted string
 * @return {Date} is the date object
 */
function parseGCalTime(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;
    return new Date(gmtDateEpoch);
  } else {
	  return new Date(year, month-1, dateMonth)
  }
}