/****************************************************************************************
*   Project 	: beije.fi
*   Type    	: javascript prototype
*   File    	: rssparser.prototype.js
*	Description : Parses RSS feeds with javascript, returns object with each entry
*
*	Usage		:
*
*	feed = new Rssparser( URL_TO_VALID_RSS_FEED );	// Create new rssparser object, send in url to feed
*	feed.set( 'proxy', URL_TO_PROXY );				// Optional, String, send in proxy url if feed resides on a other server
*	feed.set( 'useproxy', true );					// Optional, boolean, use proxy
*	feed.set( 'usetag', 'item' );					// Optional, String, what tag the parser should look after, 'item' being default
*
*	if( data = feed.parse() )						// fetch feed items to data, return false on error
*	{
*		console.log( data );						// debug data
*	}
*
****************************************************************************************/

function Rssparser()
{
	// Url where the feed resides
	this.url = '';
	
	this.complete = false;
	
	// Proxy url, a file on the server that fetches the rss feed and returns it 
	// (circumventing the "same domain" security )
	this.proxyurl = '';
	
	// If the rssparser should use the proxy (use only if the feed is not located on your server)
	this.useproxy = true;
	
	// What tag the parser should look after, item being default
	this.itemtagname = 'item';
	
	// Set the parsing objects
	this.xmlhttp = null;
	this.rawdata = null;
	this.parser = null;
	this.feed = null;
	
	// i and n will be used in forloops, only added here so it doesn't collide with any global vars
	this.i = 0;
	this.n = 0;
	
	// The array which will contain the data when all is done.
	this.posts = new Array();
	
	// if you want to add an identifier to each post
	this.identifier = '';
}

Rssparser.prototype.set = function( type, value )
{
	switch( type )
	{
		case 'url':
			this.url = value
		break;
		
		case 'proxy':
			this.proxyurl = value
		break;
		
		case 'useproxy':
			this.useproxy = ( value ? true : false );
		break;
		
		case 'usetag':
			this.itemtagname = value;
		break;
		
		case 'identifier':
			this.identifier = value;
		break;
	}
}

Rssparser.prototype.parse = function()
{
	// Check that raw data is not empty nor false
	if( this.rawdata )
	{ 
		// Check if browser has DOMParser, otherwise it's IE
		// this.feed will contain the DOM tree of the feed
		if ( window.DOMParser )
		{
			this.parser = new DOMParser();
			this.feed = this.parser.parseFromString( this.rawdata, "text/xml" );
		}
		else
		{
			this.feed = new ActiveXObject("Microsoft.XMLDOM");
			this.feed.loadXML( this.rawdata );
		}  

		// Fetch all items that are named 'item', all valid RSS feeds have their data within item
		this.feeditems = this.feed.getElementsByTagName( this.itemtagname );
		
		// this.posts will contain the final data
		this.posts = new Array();

		// Loop through all the items
		for( this.i = 0; this.i < this.feeditems.length; this.i++ )
		{
			// Set an array for this item
			this.posts[this.i] = new Array();

			// Loop through all childnodes within current item
			for( this.n = 0; this.n < this.feeditems[this.i].childNodes.length; this.n++ )
			{
			
				// Save the data within previous array using the nodename as index (set to lower case, pubDate = pubdate)
				if( this.feeditems[this.i].childNodes[this.n].textContent != '' )
				{
				
					// If textContent is not empty, use it as value
					this.posts[this.i][this.feeditems[this.i].childNodes[this.n].nodeName.toLowerCase()] = this.feeditems[this.i].childNodes[this.n].textContent;
					
				}
				else
				{
				
					// Otherwise save the object (because there might be attributes you want)
					// flickr for example uses <link> with attributes instead of having 
					// the actual link inside of the object
					this.posts[this.i][this.feeditems[this.i].childNodes[this.n].nodeName.toLowerCase()] = this.feeditems[this.i].childNodes[this.n];
					
				}
			}
			
			// Set the identifier
			if( this.identifier != '' )
			{
			
				this.posts[this.i]['RSSPARSER_ID'] = this.identifier;
				
			}

		}
		
		// return posts
		return this.posts;

	}
	else
	{
		// return false if it fails.
		return false;
	}
}
Rssparser.prototype.fetch = function()
{
	this.complete = false;

	// Check if XMLHttpRequest exists, if it doesn't it's IE
	if ( window.XMLHttpRequest )
	{
		// Moz, Chrome, whatever
		this.xmlhttp = new XMLHttpRequest();
	}
	else
	{
		// IE
		this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}

	this.xmlhttp.parserobject = this;
	
	this.xmlhttp.onreadystatechange=function()
	{
		if ( this.readyState == 4 && this.status == 200 )
		{
			this.parserobject.complete = true;
			this.parserobject.rawdata = this.responseText;
		
		}
	}
	
	// Set the url, use proxy or don't
	if( this.useproxy )
	{
		this.xmlhttp.open("GET",this.proxyurl+escape(this.url),true);
	}
	else
	{
		this.xmlhttp.open("GET",this.url,true);
	}
	
	// Send the request
	this.xmlhttp.send();

	return false;

}
