
//OBJECTS
	//default values for html tags used
	var imageTag = "<img id='chan_image'";
	var startItemTag = "<div id='item'>";
	var startTitle = "<div id='item_title'>";
	var startDate = "<div id='item_pubDate'>";
	var startDescription = "<div id='item_description'>";
	var endTag = "</div>";
	var rssUrl = blogUrl 		// url of blog source file
// TODO: validate blogUrl equals trusted rss source

//objects inside the RSS2Item object

/*
function RSS2Enclosure(encElement)
{
	if (encElement == null)
	{
		this.url = null;
		this.length = null;
		this.type = null;
	}
	else
	{
		this.url = encElement.getAttribute("url");
		this.length = encElement.getAttribute("length");
		this.type = encElement.getAttribute("type");
	}
}
*/
function RSS2Guid(guidElement)
{
	if (guidElement == null)
	{
		this.isPermaLink = null;
		this.value = null;
	}
	else
	{
		this.isPermaLink = guidElement.getAttribute("isPermaLink");
		this.value = guidElement.childNodes[0].nodeValue;
	}
}

function RSS2Source(souElement)
{
	if (souElement == null)
	{
		this.url = null;
		this.value = null;
	}
	else
	{
		this.url = souElement.getAttribute("url");
		this.value = souElement.childNodes[0].nodeValue;
	}
}

//object containing the RSS 2.0 item
function RSS2Item(itemxml)
{
	//required
	this.title;
	this.link;
	this.description;

	//optional vars
	this.author;
	this.comments;
	this.pubDate;

	//optional objects
	this.category = new Array();
	this.enclosure;
	this.guid;
	this.source;

// TODO: make item properties generic; loop through XML elements to build array
	var properties = new Array("title", "link", "description", "author", "comments", "pubDate");
	var tmpElement = null;
	for (var i=0; i<properties.length; i++)
	{
		tmpElement = itemxml.getElementsByTagName(properties[i])[0];
		if (tmpElement != null) {
			eval("this."+properties[i]+"=tmpElement.childNodes[0].nodeValue");
		}
	}

// TODO: loop through all categories
	for(var i=0; i<itemxml.getElementsByTagName("category").length; i++)
	{
		if(itemxml.getElementsByTagName("category")[i].nodeValue != null)
		{
			this.category[i] = new RSS2Category(itemxml.getElementsByTagName("category")[i]);
		}
	}
	this.enclosure = new RSS2Enclosure(itemxml.getElementsByTagName("enclosure")[0]);
	this.guid = new RSS2Guid(itemxml.getElementsByTagName("guid")[0]);
	this.source = new RSS2Source(itemxml.getElementsByTagName("source")[0]);
}

//objects inside the RSS2Channel object
function RSS2Category(catElement)
{
	if (catElement == null)
	{
		this.domain = null;
		this.value = null;
	}
	else
	{
		this.domain = catElement.getAttribute("domain");
		this.value = catElement.childNodes[0].nodeValue;
	}
}

//object containing RSS image tag info
function RSS2Image(imgElement)
{
	if (imgElement == null)
	{
	this.url = null;
	this.link = null;
	this.width = null;
	this.height = null;
	this.description = null;
	}
	else
	{
		imgAttribs = new Array("url","title","link","width","height","description");
		for (var i=0; i<imgAttribs.length; i++)
			if (imgElement.getAttribute(imgAttribs[i]) != null)
				eval("this."+imgAttribs[i]+"=imgElement.getAttribute("+imgAttribs[i]+")");
	}
}

//object containing the parsed RSS 2.0 channel
function RSS2Channel(rssxml)
{
	//required
	this.title;
	this.link;
	this.description;

	//array of RSS2Item objects
	this.items = new Array();

	//optional vars
	this.language;
	this.copyright;
	this.managingEditor;
	this.webMaster;
	this.pubDate;
	this.lastBuildDate;
	this.generator;
	this.docs;
	this.ttl;
	this.rating;

	//optional objects
	this.category = new Array();
	this.image;

	var chanElement = rssxml.getElementsByTagName("channel")[0];
	var itemElements = rssxml.getElementsByTagName("item");

	for (var i=0; i<itemElements.length; i++)
	{
		Item = new RSS2Item(itemElements[i]);
		this.items.push(Item);
		//chanElement.removeChild(itemElements[i]);
	}

// TODO: make channel properties generic; loop through XML elements to build array
	var properties = new Array("title", "link", "description", "language", "copyright", "lastBuildDate", "generator", "docs");
	var tmpElement = null;
	for (var i=0; i<properties.length; i++)
	{
		tmpElement = chanElement.getElementsByTagName(properties[i])[0];
		if (tmpElement!= null)
			eval("this."+properties[i]+"=tmpElement.childNodes[0].nodeValue");
	}

// TODO: loop through all categories
	for(i = 0; i<chanElement.getElementsByTagName("category").length; i++)
	{
		if(chanElement.getElementsByTagName("category")[i].nodeValue != null)
		{
			this.category[i] = new RSS2Category(chanElement.getElementsByTagName("category")[i]);
		}
	}
	this.image = new RSS2Image(chanElement.getElementsByTagName("image")[0]);
}

//PROCESSES
function BlogReader()
{
  // grab any existing onload so its not overwritten
  window.priorOnloadHandler = window.onload; 
  window.onload = this.getRSS;
}

BlogReader.prototype.getRSS = getRSS;


//uses xmlhttpreq to get the raw rss xml
function getRSS()
{
    if(window.priorOnloadHandler != null){ window.priorOnloadHandler(); };
    
	//call the right constructor for the browser being used
	if (window.ActiveXObject)
	{
		xhr = new ActiveXObject("Microsoft.XMLHTTP");
	}
	else if (window.XMLHttpRequest)
	{
		xhr = new XMLHttpRequest();
	}
	else
	{
//		showRSS("error");
		document.getElementById("chan").innerHTML = defaultText;
//		alert("not supported");
	}

	//prepare the xmlhttprequest object
	xhr.open("GET",rssUrl,true);
	xhr.setRequestHeader("Cache-Control", "no-cache");
	xhr.setRequestHeader("Pragma", "no-cache");
	xhr.onreadystatechange = function() {
		if (xhr.readyState == 4)
		{
			if (xhr.status == 200)
			{
				if (xhr.responseXML != null)
				{
					processRSS(xhr.responseXML);
				}
				else
				{
//					showRSS("error");
//					alert("Failed to receive RSS file from the server - file not found.");
					document.getElementById("chan").innerHTML = defaultText;
					return false;
				}
			}
			else
			{
//				showRSS("error");
//				alert("Error code " + xhr.status + " received: " + xhr.statusText);
				document.getElementById("chan").innerHTML = defaultText;
			}
		}
	}

	//send the request
	xhr.send(null);
}

//processes the received rss xml
function processRSS(rssxml)
{
	RSS = new RSS2Channel(rssxml);
	showRSS(RSS);
}

//shows the RSS content in the browser
function showRSS(RSS)
{
	if(RSS == "error")
	{
		document.write(defaultText);
	}
	else
	{
		//populate channel data
	// TODO: make channel properties generic; loop through XML elements to build array
		var properties = new Array("title","link","description","copyright","lastBuildDate");
		for (var i=0; i<properties.length; i++)
		{
			curProp = eval("RSS."+properties[i]);
			if (curProp != null)
			{
				if (properties[i] == "link")  // set href of rss link and innerhtml of all other channel properties
				{
					eval("document.getElementById('chan_"+properties[i]+"').href = curProp");
				}
				else if (properties[i] == "lastBuildDate")
				{
					curProp = formatDate(curProp);
					eval("document.getElementById('chan_"+properties[i]+"').innerHTML = curProp");
				}
				else
				{
					eval("document.getElementById('chan_"+properties[i]+"').innerHTML = curProp");
				}
			}
			else
			{
				eval("document.getElementById('chan_"+properties[i]+"').innerHTML = ''");
			}
		}

		//show the image
		document.getElementById("chan_image_link").innerHTML = "";
		if (RSS.image.src != null)
		{
			document.getElementById("chan_image_link").href = RSS.image.link;
			document.getElementById("chan_image_link").innerHTML = imageTag
				+" alt='"+RSS.image.description
				+"' width='"+RSS.image.width
				+"' height='"+RSS.image.height
				+"' src='"+RSS.image.url
				+"' "+"/>";
		}
		//populate the items
		document.getElementById("chan_items").innerHTML = "";
		for (var i=0; i<feedCount; i++)
		{
		// truncate description at a space between words
		var descrLastChar = RSS.items[i].description.indexOf(" ", descrLength);
		var itemDescription = RSS.items[i].description;
	// TODO: add char count of URL to length of descrLength to offset additional chars of embedded anchor tags
		// add ellipsis to description if it has been truncated
		if (descrLength > 0 && descrLength < RSS.items[i].description.length)
		{
			itemDescription = RSS.items[i].description.substr(0, descrLastChar) + "..."
		}
			item_html = startItemTag;
			item_html += (RSS.items[i].title == null) ? "" : startTitle + "<a href='" + RSS.items[i].link + "' target='_blank'>" + RSS.items[i].title + "</a>" + endTag;
			item_html += startDate + "posted on " + formatDate(RSS.items[i].pubDate) + endTag;
			item_html += (RSS.items[i].description == null) ? "" : startDescription + itemDescription + endTag;
			item_html += endTag;
			document.getElementById("chan_items").innerHTML += item_html;
		}
	}
	return true;
}

var xhr;

// display dates in Month d, yyyy format
function formatDate(dateValue)
{
	var newDate = new Date(dateValue);
	var monthName = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
	var dayName = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
	return monthName[newDate.getMonth()] + " " + newDate.getDate() + ", " + newDate.getFullYear();
}


BlogReader();
