
/* Loads the Google data JavaScript client library */
google.load("gdata", "2.x");

function init() {
  // init the Google data JS client library with an error handler
  google.gdata.client.init(handleGDError);
}

/**
 * Determines the full calendarUrl based upon the calendarAddress
 * argument and calls loadCalendar with the calendarUrl value.
 *
 * @param {string} calendarAddress is the email-style address for the calendar
 */ 
function loadCalendarByAddress(calendarAddress, maxResults, callBackName) {
  var calendarUrl = 'http://www.google.com/calendar/feeds/' +
                    calendarAddress + 
                    '/public/full';
  loadCalendar(calendarUrl, maxResults, callBackName);
}

/**
 * Uses Google data JS client library to retrieve a calendar feed from the specified
 * URL.  The feed is controlled by several query parameters and a callback 
 * function is called to process the feed results.
 *
 * @param {string} calendarUrl is the URL for a public calendar feed
 * @param {int} maxResults is the max number of events to return
 */  
function loadCalendar(calendarUrl, maxResults, callBackName) {
  var service = new 
      google.gdata.calendar.CalendarService('gdata-js-client-samples-simple');
  var query = new google.gdata.calendar.CalendarEventQuery(calendarUrl);
  query.setOrderBy('starttime');
  query.setSortOrder('ascending');
  query.setFutureEvents(true);
  query.setSingleEvents(true);
  query.setMaxResults(maxResults);
  
  service.getEventsFeed(query, callBackName, handleGDError);
}

/**
 * Callback function for the Google data JS client library to call when an error
 * occurs during the retrieval of the feed.  Details available depend partly
 * on the web browser, but this shows a few basic examples. In the case of
 * a privileged environment using ClientLogin authentication, there may also
 * be an e.type attribute in some cases.
 *
 * @param {Error} e is an instance of an Error 
 */
function handleGDError(e) {
  document.getElementById('jsSourceFinal').setAttribute('style', 
      'display:none');
  if (e instanceof Error) {
    /* alert with the error line number, file and message */
    alert('Error at line ' + e.lineNumber +
          ' in ' + e.fileName + '\n' +
          'Message: ' + e.message);
    /* if available, output HTTP error code and status text */
    if (e.cause) {
      var status = e.cause.status;
      var statusText = e.cause.statusText;
      alert('Root cause: HTTP error ' + status + ' with status text of: ' + 
            statusText);
    }
  } else {
    alert(e.toString());
  }
}

/**
 * Callback function for the Google data JS client library to call with a feed 
 * of events retrieved.
 *
 * Creates a definition list of events in a human-readable form.  This list of
 * events is added into a div called 'gevents'.
 *
 * @param {json} feedRoot is the root of the feed, containing all entries 
 */ 
function listEvents(feedRoot) {
  var entries = feedRoot.feed.getEntries();
  var eventDiv = document.getElementById('gevents');
  if (eventDiv.childNodes.length > 0) {
    eventDiv.removeChild(eventDiv.childNodes[0]);
  }	  
  /* create a new definition list */
  var dl = document.createElement('dl');

  /* loop through each event in the feed */
  var len = entries.length;
  for (var i = 0; i < len; i++) {
    var entry = entries[i];
    var title = entry.getTitle().getText();
    var startDateTime = null;
    var times = entry.getTimes();
    if (times.length > 0) {
      startDateTime = times[0].getStartTime();
    }
    var entryLinkHref = null;
    if (entry.getHtmlLink() != null) {
      entryLinkHref = entry.getHtmlLink().getHref();
    }
	
	var date = startDateTime.getDate();
    var dateString = getFriendlyDateString(date);
	if (!startDateTime.isDateOnly()) {
	  dateString += " at " + getCivilianTimeStringFromDate(date);
	}
	var dt = document.createElement('dt');
	dt.appendChild(document.createTextNode(dateString));
	
    var dd = document.createElement('dd');
    /* if we have a link to the event, create an 'a' element */
    if (entryLinkHref != null) {
      entryLink = document.createElement('a');
      entryLink.setAttribute('href', entryLinkHref);
	  entryLink.setAttribute('target', '_new');
      entryLink.appendChild(document.createTextNode(title));
      dd.appendChild(entryLink);
	} else {
	  dd.appendChild(document.createTextNode(title));
    }

    /* append the list item onto the unordered list */
	dl.appendChild(dt);
    dl.appendChild(dd);
  }
  eventDiv.appendChild(dl);
}

/**
 * Callback function for the Google data JS client library to call with a feed 
 * of events retrieved.
 *
 * Creates a definition list of events in a human-readable form.  This list of
 * events is added into a div called 'gevents'.
 *
 * @param {json} feedRoot is the root of the feed, containing all entries 
 */ 
function listEventsForSchedule(feedRoot) {

  var entries = feedRoot.feed.getEntries();
  var eventDiv = document.getElementById('gevents');
  while (eventDiv.childNodes.length > 0) {
    eventDiv.removeChild(eventDiv.firstChild);
  }
  
  /* loop through each event in the feed */
  var len = entries.length;
  var currentMonth = null;
  var monthBoxDiv = null;
  var scheduleHeader = null;
  var scheduleBody = null;
  var h3 = null;
  var ul = null;
  for (var i = 0; i < len; i++) {
    var entry = entries[i];
    var title = entry.getTitle().getText();
	var summary = entry.getContent().getText();
	summary = summary.replace(/[\r\n]+/g, '\n\r');
    var startDateTime = null;
	var times = entry.getTimes();
    if (times.length > 0) {
      startDateTime = times[0].getStartTime();
    }
	var date = startDateTime.getDate();
	var year = date.getFullYear();
	var month = date.getMonth();

    var entryLinkHref = null;
    if (entry.getHtmlLink() != null) {
      entryLinkHref = entry.getHtmlLink().getHref();
    }
	
	// if we changed months, we need a new monthBox div
	if (month != currentMonth) {
	  // create a new monthBox div
      monthBoxDiv = document.createElement('div');
      monthBoxDiv.className = 'monthBox';
      currentMonth = month;
	  h3 = document.createElement('h3');
	  h3.innerHTML = getMonthNameFromDate(date) + ' ' + year;
	  monthBoxDiv.appendChild(h3);
	  //scheduleHeader = document.createElement('div');
	  //scheduleHeader.className = 'scheduleHeader';
      //scheduleBody = document.createElement('div');
	  //scheduleBody.className = 'scheduleBody';
	  ul = document.createElement('ul');
	  // add the to the gevents div
  	  //scheduleHeader.appendChild(scheduleBody);
      //scheduleBody.appendChild(ul);
	  monthBoxDiv.appendChild(ul);
	  eventDiv.appendChild(monthBoxDiv);
	}
	
	// date and time
	var li = document.createElement('li');
	var h4 = document.createElement('h4');
	

    var dateString = getFriendlyDateString(date);
	if (!startDateTime.isDateOnly()) {
	  dateString += " at " + getCivilianTimeStringFromDate(date);
	}
	h4.appendChild(document.createTextNode(dateString));
	var day = document.createElement('strong');
	day.appendChild(document.createTextNode(date.getDate()));
	var moYear = document.createElement('em');
	moYearText = getMonthNameFromDate(date).substring(0,3) + " " + date.getFullYear();
	moYear.appendChild(document.createTextNode(moYearText));
	day.appendChild(moYear);
	h4.appendChild(day);
	
	var h5 = document.createElement('h5');
	// title
    /* if we have a link to the event, create an 'a' element */
    if (entryLinkHref != null) {
      entryLink = document.createElement('a');
      entryLink.setAttribute('href', entryLinkHref);
	  entryLink.setAttribute('target', '_new');
      entryLink.appendChild(document.createTextNode(title));
      h5.appendChild(entryLink);
	} else {
	  h5.appendChild(document.createTextNode(title));
    }
	li.appendChild(h4);
	li.appendChild(h5);
	ul.appendChild(li);
	
	// description
	var p = document.createElement('p');
	p.appendChild(document.createTextNode(summary));
	if (summary.length < 1) { 
	  var height = 65 - $("li:last").height();
	  if (height < 0) {
	    height = 0;
	  }
	  p.setAttribute('style', 'height:' + height + 'px');
	}
	li.appendChild(p);

  }
  
}

/**
 * Creates a friendly date string (e.g., "Tuesday, December 15, 2009") from a date.
 *
 * @param {date} someDate is the date object to get the friendly date from
 * @param {boolean} includeYear specifies whether to include the 4-digit year
 */ 
function getFriendlyDateString(someDate, includeYear) {
	
	// Figure out the friendly day name
	var dateString = getDayNameFromDate(someDate);

	// Figure out the friendly month name
	dateString += ", " + getMonthNameFromDate(someDate);

	// Add the day of the month
	dateString += " " + someDate.getDate()
	
	if (includeYear) {
	  // Add the year
	  dateString += ", " + someDate.getFullYear()
	}
	
	return dateString
}

function getDayNameFromDate(someDate) {
	// This array holds the "friendly" day names
	var dayNames = new Array(7);
	dayNames[0] = "Sunday";
	dayNames[1] = "Monday";
	dayNames[2] = "Tuesday";
	dayNames[3] = "Wednesday";
	dayNames[4] = "Thursday";
	dayNames[5] = "Friday";
	dayNames[6] = "Saturday";
	return dayNames[someDate.getDay()]
}

function getMonthNameFromDate(someDate) {
  	// This array holds the "friendly" month names
	var monthNames = new Array(12);
	monthNames[0] = "January";
	monthNames[1] = "February";
	monthNames[2] = "March";
	monthNames[3] = "April";
	monthNames[4] = "May";
	monthNames[5] = "June";
	monthNames[6] = "July";
	monthNames[7] = "August";
	monthNames[8] = "September";
	monthNames[9] = "October";
	monthNames[10] = "November";
	monthNames[11] = "December";
	return monthNames[someDate.getMonth()]
}

/**
 * Gets the civilian time string (e.g., "6:30 PM") from a date.
 *
 * @param {date} someDate is the date object to get time from
 */ 
function getCivilianTimeStringFromDate(someDate) {
	
	var timeString = null;
	
	// Get the minutes in the hour
	var minutes = someDate.getMinutes();
	if (minutes < 10) {
	  minutes = "0" + minutes;
	}

	// Get the hour value and format accordingly
	var hour = someDate.getHours();
	if (hour == 0) {
	  timeString = (hour + 12) + ":" + minutes + " AM";
	}
	else if (hour < 12) {
	  timeString = hour + ":" + minutes + " AM";
	}
	else if (hour == 12) {
	  timeString = hour + ":" + minutes + " PM";
	}
	else {
	  timeString = (hour - 12) + ":" + minutes + " PM";
	}
	
	return timeString
}