/*
A feed reader object - a reader must prototype a feed() method to read in a feed and return it in desired format.
wrtier - a feed writer that knows how to write raw feed into desired format
feedParameters - parameters of this feed
*/ 
function GoogleAJAXFeedReader(url, parameters){
	this.url = url;
	this.parameters = parameters;
}

GoogleAJAXFeedReader.prototype.feed = function(writer){
	var feedURL = this.url;
	if(this.parameters != null){
		feedURL += "?" + this.parameters;
	}
	var feed = new google.feeds.Feed(feedURL);
	feed.setResultFormat(google.feeds.Feed.XML_FORMAT);
	feed.load(function(result) {
	if (!result.error) {
		var w3NS = "http://www.w3.org/2005/Atom";
		var googleNS = "http://schemas.google.com/g/2005";
	    var entries = google.feeds.getElementsByTagNameNS(result.xmlDocument, w3NS, "entry");
	    for (var i = 0; i < entries.length; i++) {
	       var titleElement = google.feeds.getElementsByTagNameNS(entries[i], w3NS, "title")[0].firstChild.nodeValue;
		   var content = google.feeds.getElementsByTagNameNS(entries[i], w3NS, "content")[0].firstChild.nodeValue;
	       var mylinkElement = google.feeds.getElementsByTagNameNS(entries[i], w3NS, "link")[0].getAttribute('href');
	       var whenElement = google.feeds.getElementsByTagNameNS(entries[i], googleNS, "when")[0];
	       var starttime = whenElement.getAttribute('startTime');
	       var endtime = whenElement.getAttribute('endTime');
		   var location = google.feeds.getElementsByTagNameNS(entries[i], googleNS, "where")[0].getAttribute('valueString');
	       
		   //Build the meta data for writer
		   var rawData = { "title" 		: titleElement, 
						   "link" 		: mylinkElement,
						   "startTime" 	: starttime,
						   "endTime" 	: endtime,
						   "location"	: location,
						   "content"	: content					   
						 };
			//Delegate writer to wrte the meta data
			writer.write(rawData);			 
	    }
		
		if(entries.length == 0){
			writer.write(null);		
		}
	}
	});
}



/*
A writer that knows how to interpret data passed in and format the data into desired output.
A writer may delegate some work to other writers.
In this case, this writer writes the event entries into an HTML DOM object
*/
function CalendarEventListDOMWriter(containerID){
	this.dateWriter = new StartEndDateDOMWriter();
	this.containerID = containerID;
	this.listDOM = null;
	this.maxTitleLen = 40;
}


CalendarEventListDOMWriter.prototype.write = function(data){
	if(this.listDOM == null){
		this.listDOM = document.createElement("ul");
		document.getElementById(this.containerID).appendChild(this.listDOM);
	}	
	
	var li = document.createElement("li");
	if(data != null){
	    if(data.title && data.link){
			var a = document.createElement("a");
			a.setAttribute("href", data.link);
			var title = data.title;
			if(title.length > this.maxTitleLen){
				title = title.substring(0, this.maxTitleLen) +"..."
			}
			
			a.appendChild(document.createTextNode(title));
			li.appendChild(a);
			li.appendChild(document.createElement("br"));
			
			if(data.startTime || data.endTime){
				var spanwhen = document.createElement("span");
				spanwhen.setAttribute("class", "when");
				//delegate creation of start time and end time string to a date writer
				spanwhen.appendChild(document.createTextNode(this.dateWriter.write(data)));
				li.appendChild(spanwhen);
			}
			
		}
	}
	else{
		li.appendChild(document.createTextNode("Sorry, there are currently no future events."));
	}
	this.listDOM.appendChild(li);
}


function CalendarEventFullDOMWriter(containerID){
	this.dateWriter = new StartEndDateDOMWriter();
	this.containerID = containerID;
	this.eventClassName = "calendarEvent";
	this.maxContent = 15;
}

CalendarEventFullDOMWriter.prototype.write = function(data){
	var eventContainer = document.createElement("div");
	eventContainer.className = this.eventClassName;
	
	if(data != null){
	    if(data.title && data.link){
			var title = document.createElement("h3");			
			var a = document.createElement("a");
			a.setAttribute("href", data.link);
			a.appendChild(document.createTextNode(data.title));
			title.appendChild(a);
			eventContainer.appendChild(title);
		}

		if(data.startTime || data.endTime){
			eventContainer.appendChild(document.createTextNode(this.dateWriter.write(data)));
			eventContainer.appendChild(document.createElement("br"));
		}
			
		if(data.location){
			eventContainer.appendChild(document.createTextNode("Location: " + data.location));			
			eventContainer.appendChild(document.createElement("br"));
		}			
		
		if(data.content){
			var content = document.createElement("div");	
			content.innerHTML = unescape(data.content);
			eventContainer.appendChild(content);
		}		
	}
	else{
		eventContainer.appendChild(document.createTextNode("Sorry, there are currently no events."));
	}
	
	document.getElementById(this.containerID).appendChild(eventContainer);
}

/*
This writer writes a pair of start and end times as a  formated String
*/

function StartEndDateDOMWriter(){
	this.regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
        "(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
        "(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
}

StartEndDateDOMWriter.prototype.createISO8601Date = function(dateString){
	var d = dateString.match(new RegExp(this.regexp));
    var offset = 0;
    var date = new Date(d[1], 0, 1);

    if (d[3]) { date.setMonth(d[3] - 1); }
    if (d[5]) { date.setDate(d[5]); }
    if (d[7]) { date.setHours(d[7]); }
    if (d[8]) { date.setMinutes(d[8]); }
    if (d[10]) { date.setSeconds(d[10]); }
    if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
    if (d[14]) {
        offset = (Number(d[16]) * 60) + Number(d[17]);
        offset *= ((d[15] == '-') ? 1 : -1);
    }

    offset -= date.getTimezoneOffset();
    time = (Number(date) + (offset * 60 * 1000));
    date.setTime(Number(time));
	return date;
}

StartEndDateDOMWriter.prototype.write = function(data){
	if(data.startTime && data.endTime){
		var startdate = this.createISO8601Date(data.startTime);
	    var enddate = this.createISO8601Date(data.endTime);
	    var startstring = (startdate.getDate() + 1) + '/' + (startdate.getMonth() + 1) + '/' + startdate.getFullYear();
	    var endstring = (enddate.getDate() + 1) + '/' + (enddate.getMonth() + 1) + '/' + enddate.getFullYear();
	    if (startstring == endstring) {
			whenstring = '' + startstring;
	    }
	    else {
			whenstring = '' + startstring + ' - ' + endstring;
	    } 
		return whenstring;
	}
	else{
		return "";
	}
}
