// V 0.9.2
//What it does:
//Retrieves a list of event information from a Google calendar and outputs a DIV named “events”.  The DIV can be place anywhere in the HTML code to be rendered.  The event items are ordered ascending by start time.  The only events that will show are anything past in the current month and all future.
//The DIV looks as follows:
//<div id="content">
//<h3>DATE WHEN</h3>
//<p class="blank"><span class="eventTitle">TITLE</span>
//<br class="blank" />DESCRIPTION
//<br class="blank" />WHERE
//<br class="blank" />TIME WHEN
//</p>
//...
//</div>
// If there are no events noEventsMsg is put in the div.  noEventsMsg can include HTML
//google API Key:http://code.google.com/apis/gdata/signup.html
//by jeff.malick at gmail

//Loads the Google data JavaScript client library
google.load("gdata", "2.x");
// msg it there are no events
var noEventsMsg = "No upcoming events scheduled";

function init() {
	// init the Google data JS client library with an error handler
	google.gdata.client.init(handleGDError);
	// load the calendar
	loadMyCalendar();
}

/*
 * Date format lib http://blog.stevenlevithan.com/archives/date-time-format
 */

var dateFormat = function() {
	var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g, timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g, timezoneClip = /[^-+\dA-Z]/g, pad = function(
			val, len) {
		val = String(val);
		len = len || 2;
		while (val.length < len)
			val = "0" + val;
		return val;
	};

	// Regexes and supporting functions are cached through closure
	return function(date, mask, utc) {
		var dF = dateFormat;

		// You can't provide utc if you skip other args (use the "UTC:" mask
		// prefix)
		if (arguments.length == 1
				&& Object.prototype.toString.call(date) == "[object String]"
				&& !/\d/.test(date)) {
			mask = date;
			date = undefined;
		}

		// Passing date through Date applies Date.parse, if necessary
		date = date ? new Date(date) : new Date;
		if (isNaN(date))
			throw SyntaxError("invalid date");

		mask = String(dF.masks[mask] || mask || dF.masks["default"]);

		// Allow setting the utc argument via the mask
		if (mask.slice(0, 4) == "UTC:") {
			mask = mask.slice(4);
			utc = true;
		}

		var _ = utc ? "getUTC" : "get", d = date[_ + "Date"](), D = date[_
				+ "Day"](), m = date[_ + "Month"](), y = date[_ + "FullYear"](), H = date[_
				+ "Hours"](), M = date[_ + "Minutes"](), s = date[_ + "Seconds"]
				(), L = date[_ + "Milliseconds"](), o = utc ? 0 : date
				.getTimezoneOffset(), flags = {
			d : d,
			dd : pad(d),
			ddd : dF.i18n.dayNames[D],
			dddd : dF.i18n.dayNames[D + 7],
			m : m + 1,
			mm : pad(m + 1),
			mmm : dF.i18n.monthNames[m],
			mmmm : dF.i18n.monthNames[m + 12],
			yy : String(y).slice(2),
			yyyy : y,
			h : H % 12 || 12,
			hh : pad(H % 12 || 12),
			H : H,
			HH : pad(H),
			M : M,
			MM : pad(M),
			s : s,
			ss : pad(s),
			l : pad(L, 3),
			L : pad(L > 99 ? Math.round(L / 10) : L),
			t : H < 12 ? "a" : "p",
			tt : H < 12 ? "am" : "pm",
			T : H < 12 ? "A" : "P",
			TT : H < 12 ? "AM" : "PM",
			Z : utc ? "UTC" : (String(date).match(timezone) || [ "" ]).pop()
					.replace(timezoneClip, ""),
			o : (o > 0 ? "-" : "+")
					+ pad(
							Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o)
									% 60, 4),
			S : [ "th", "st", "nd", "rd" ][d % 10 > 3 ? 0
					: (d % 100 - d % 10 != 10) * d % 10]
		};

		return mask.replace(token, function($0) {
			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
		});
	};
}();

// Some common format strings
dateFormat.masks = {
	"default" : "dddd, mmmm d",
	shortDate : "m/d/yy",
	mediumDate : "mmm d, yyyy",
	longDate : "mmmm d, yyyy",
	fullDate : "dddd, mmmm d, yyyy",
	shortTime : "h:MM TT",
	mediumTime : "h:MM:ss TT",
	longTime : "h:MM:ss TT Z",
	isoDate : "yyyy-mm-dd",
	isoTime : "HH:MM:ss",
	isoDateTime : "yyyy-mm-dd'T'HH:MM:ss",
	isoUtcDateTime : "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

// Internationalization strings
dateFormat.i18n = {
	dayNames : [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sunday",
			"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
	monthNames : [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
			"Sep", "Oct", "Nov", "Dec", "January", "February", "March",
			"April", "May", "June", "July", "August", "September", "October",
			"November", "December" ]
};

// For convenience...
Date.prototype.format = function(mask, utc) {
	return dateFormat(this, mask, utc);
};
/** ********end of date format library ****** */

// Loads Calendar by passing in address
// get address at:
// http://www.google.com/support/calendar/bin/answer.py?answer=37103&query=calendar+address&topic=&type=
// Calendar must be set to public for this implementation
function loadMyCalendar() {
	
	loadCalendarByAddress('calshakes@gmail.com'); // Cal Shakes Calendar
}

// 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 = 'http://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-cal-disp');
	var query = new google.gdata.calendar.CalendarEventQuery(calendarUrl);
	var d = new Date();
	var thisYear = d.getUTCFullYear();
	var thisMonth = d.getUTCMonth() + 1;
	// Create query to get all events from todays month on

	var startMin = google.gdata.DateTime.fromIso8601(thisYear + '-' + thisMonth
			+ '-01T00:00:00.000-08:00');
	query.setMinimumStartTime(startMin);
	query.setOrderBy('starttime');
	query.setSortOrder('ascending');
	query.setFutureEvents(false);
	query.setSingleEvents(true);
	query.setMaxResults(4);
	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. List of
// events is added into a div called 'events'.
// feedRoot is the root of the feed, containing all entries
function listEvents(feedRoot) {
	var entries = feedRoot.feed.getEntries();
	var eventDiv = document.getElementById('events');
	var eventText = '';
	if (eventDiv.childNodes.length > 0) {
		eventDiv.removeChild(eventDiv.childNodes[0]);
	}
	var len = entries.length;
	// check events list and make sure there is an event if not display the msg
	if (len == 0){
		eventText = noEventsMsg;
		}
	// loop through each event in the feed format and place in div
	for ( var i = 0; i < len; i++) {
		var entry = entries[i];
		var jsTitle = entry.getTitle().getText();
		var jsContent = entry.getContent().getText();
		var startDateTime = null;
		var startJSDate = null;
		var times = entry.getTimes();
		if (times.length > 0) {
			startDateTime = times[0].getStartTime();
			startJSDate = startDateTime.getDate();
		}
		var jsWhere = entry.getLocations()[0].getValueString();
		// build Div content
		// all HTML tags can be placed here
		eventText += '<p class=eventDate>' + dateFormat(startJSDate, "dddd, mmmm d");
		if (jsTitle != '') {
			eventText += '<br class=blank><span class=eventTitle>' + jsTitle
					+ '</span>';
		}
		if (jsContent != '') {
			eventText += '<br class="blank" /><span class=eventTitle>' + jsContent + '</span>';
		}
		if (jsWhere != '') {
			eventText += '<br class="blank" />' + jsWhere;
		}
		eventText += '<br class="blank" />'
				
		eventText += '</p>';
	}
	// add content to div
	document.getElementById("events").innerHTML = eventText;
}
// initialize script
google.setOnLoadCallback(init);
