/* 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);
  // load the code.google.com developer calendar
  loadDeveloperCalendar();
}

/**
 * Loads the Google Developers Event Calendar
 */
function loadDeveloperCalendar() {
  loadCalendarByAddress('web@communityhope.org');
}

/**
 * Adds a leading zero to a single-digit number.  Used for displaying dates.
 */
function padNumber(num) {
  if (num <= 9) {
    return "0" + num;
  }
  return num;
}

/**
 * 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) {
  var calendarUrl = 'https://www.google.com/calendar/feeds/' +
                    calendarAddress + 
                    '/public/full';
  loadCalendar(calendarUrl);
}

/**
 * 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
 */  
function loadCalendar(calendarUrl) {
  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(10);

  service.getEventsFeed(query, listEvents, 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 an unordered list of events in a human-readable form.  This list of
 * events is added into a div called 'events'.  The title for the calendar is
 * placed in a div called 'calendarTitle'
 *
 * @param {json} feedRoot is the root of the feed, containing all entries 
 */ 
function listEvents(feedRoot) {
  var entries = feedRoot.feed.getEntries();
  var eventDiv = document.getElementById('calendar');
  
  /* create a new unordered list */
  //var ul = document.createElement('ul');
  
  /* set the calendarTitle div with the name of the calendar */
  //document.getElementById('calendarTitle').innerHTML =  "Calendar: " + feedRoot.feed.title.$t;
  
  /* loop through each event in the feed */
  //var len = entries.length;
  
  //for (var i = 0; i < len; i++) {
	for (var i = 0; i < 4; i++) {  // We only want to display the next 4 entries
		var entry = entries[i];
		var title = entry.getTitle().getText();
		var startDateTime = null;
		var startJSDate = null;
		var startDateString = null;
		var endDateTime = null;
		var endJSDate = null;
		var endDateString = null;
		var times = entry.getTimes();
		
		startDateString = getStartDate(entry);
		endDateString = getEndDate(entry, startDateString);
		
		/* 
		Date 
		*/
		 var pDate = document.createElement('p');
		 pDate.className = 'eventDate orangeSubheader';
	
		 pDate.appendChild(document.createTextNode(startDateString));
		 
		 // If the event spans across multiple dates, make sure to include the end date
		 if (startDateString != endDateString) {
			pDate.appendChild(document.createTextNode(' - ' + endDateString, false)); 
		 }
			
		
		var entryLinkHref = null;
		
		if (entry.getHtmlLink() != null) {
		  entryLinkHref = entry.getHtmlLink().getHref();
		}
		
		/* 
		Event Details
		*/
		var pDetails = document.createElement('p');
		pDetails.className = 'eventDetails';
	
		// If the event is not all day or does not span multiple days, display the start time
		if (startDateString == endDateString) {
			pDetails.appendChild(document.createTextNode(getStartTime(entry)));	
		}
	
		/* if we have a link to the event, create an 'a' element 
		if (entryLinkHref != null) {
		  entryLink = document.createElement('a');
		  entryLink.setAttribute('href', entryLinkHref);
		  entryLink.appendChild(document.createTextNode(title));
		  pDetails.appendChild(entryLink);
		  //p.appendChild(document.createTextNode(' - ' + dateString));
		} else {
		  pDetails.appendChild(document.createTextNode(title));// + ' - ' + dateString));
		}	    */
		
		pDetails.appendChild(document.createTextNode(title));// + ' - ' + dateString));
		 
		/*
		Output to Page
		*/
		 // If this event is on the same day as the previous one, don't print the date again
		 // unless the event spans across multiple days
		 if (i > 0) {
			 var prevStartDate = getStartDate(entries[i - 1]);
			 var prevEndDate = getEndDate(entries[i - 1], prevStartDate);
			if ((prevStartDate != startDateString) || (prevEndDate != endDateString)) {
				eventDiv.appendChild(pDate);
		 	}
		 } else {
			 eventDiv.appendChild(pDate);
		 }
		 
		 eventDiv.appendChild(pDetails);
	}
	
	// After the events are listed, add a "View all events" link underneath
	eventDiv.innerHTML += '<p class="allEventsLink"><a href="events.php">View all events</a></p>';
}
		 
function getStartDate(entry)
{
	var times = entry.getTimes();
		
	if (times.length > 0) {
  		startDateTime = times[0].getStartTime();
  		startJSDate = startDateTime.getDate();
	}
	
	return parseDateTime(startJSDate, false);
}

function getEndDate(entry, startDateString)
{
	var times = entry.getTimes();
		
	if (times.length > 0) {
  		endDateTime = times[0].getEndTime();
  		endJSDate = endDateTime.getDate();
	}

	endDateString = parseDateTime(endJSDate, false);
	
	// If the end date is different from the start date, then the event spans multiple days.
	// For some reason, the end date that is given is one day ahead of the actual end date.
	// We correct this here by subtracting one day from the end date
	if (startDateString != endDateString) {
			endDateString = parseDateTime(new Date(endJSDate.getTime() - (1000 * 60 * 60 * 24)), false);
	}
		 
	return endDateString;
}

function getStartTime(entry)
{
	var times = entry.getTimes();
		
	if (times.length > 0) {
  		startDateTime = times[0].getStartTime();
  		startJSDate = startDateTime.getDate();
	}
	
	return parseTime(startJSDate);
}

function parseDateTime(dateTime, bPrintTime)
{
		var formattedDateTime = "";
		var day = null;
		
		// Day of week
		switch (dateTime.getDay()) {
			case 0:
		 		formattedDateTime += "Sunday";
				break;
			case 1:
		 		formattedDateTime += "Monday";
				break;
			case 2:
		 		formattedDateTime += "Tuesday";
				break;
			case 3:
		 		formattedDateTime += "Wednesday";
				break;
			case 4:
		 		formattedDateTime += "Thursday";
				break;
			case 5:
		 		formattedDateTime += "Friday";
				break;
			case 6:
		 		formattedDateTime += "Saturday";
				break;
		}
		
		formattedDateTime += ", ";
		
		// Month
		switch (dateTime.getMonth()) {
			case 0:
				formattedDateTime += "January";
				break;
			case 1:
				formattedDateTime += "February";
				break;
			case 2: 
				formattedDateTime += "March";
				break;
			case 3: 
				formattedDateTime += "April";
				break;
			case 4:
				formattedDateTime += "May";
				break;
			case 5:
				formattedDateTime += "June";
				break;
			case 6:
				formattedDateTime += "July";
				break;
			case 7:
				formattedDateTime += "August";
				break;
			case 8:
				formattedDateTime += "September";
				break;
			case 9:
				formattedDateTime += "October";
				break;
			case 10:
				formattedDateTime += "November";
				break;
			case 11:
				formattedDateTime += "December";
				break;
		}
		
		formattedDateTime += " ";
		
		// Day of month
		formattedDateTime += dateTime.getDate();
		
		if (bPrintTime) {
			formattedDateTime += " at ";
			
			formattedDateTime += ParseTime(dateTime);
		}
		
		return formattedDateTime;	
}

function parseTime(dateTime)
{
	var formattedTime = "";

	// Hour
	var hours = (dateTime.getHours());
	var hours_mod = hours % 12;
	
	if (hours != 0) {
		formattedTime += hours_mod;
	
		formattedTime += ":";
	
		// Minutes
		var minutes = dateTime.getMinutes();
		if (minutes < 10) {
			minutes = "0" + minutes;
		}
		formattedTime += minutes;
	
		// AM or PM
		if (hours > 11) {
			formattedTime += " pm";
		} else {
			formattedTime += " am";
		}
		
		// Add a '-' (dash) after the time
		formattedTime += ' - ';
	}
	
	return formattedTime
}

google.setOnLoadCallback(init);
