/**
 * @class de_epages.presentation
 * 
 */

/**
 * Load an parse a rss file.
 * 
 * The `de_epages.presentation.Rss()` method checks if the content of the given file is already stored on the epages server or if it
 * has to be loaded. Then the feed data is parsed and the callback function is called with the parsed data.
 * 
 * The data for the callback function is in the following format:
 * 
 *     data: {
 *       description: '',
 *       items: [
 *         {
 *           link : '',
 *           pubDate: '',
 *           text: '',
 *           textEncoded,
 *           title: '',
 *           audio: [],
 *           image: [],
 *           video: []
 *         }
 *       ],
 *       logo: {
 *         link : '',
 *         src : '',
 *         title: ''
 *       },
 *       name: '',
 *       pageLink: '',
 *       pubDate: '',
 *       version: ''
 *     }
 * 
 * ### Dependencies
 * 
 *  + `de_epages`
 *  + `jQuery.class`
 *  + `ep.ajax`
 * 
 * @param {String} url The url of the rss feed which should be loaded and parsed.
 * @param {Function} function(data) Callback function which is called with the parsed data after the feed is loaded.
 * @param {Boolean} [fullPath] Is the feed stored under it url on the server or is it stored under RSSFeeds inside epages
 * 
 * @method Rss
 * @static 
 * @member de_epages.presentation
 * 
 * @since 6.11.0
 */

/*
 * @copyright		© Copyright 2006-2010, epages GmbH, All Rights Reserved.
 *
 * @module			de_epages.presentation.rss
 *
 * @revision		$Revision: 1.6 $
 */

define("de_epages/presentation/rss", [
	"jquery",
	"ep",
	"de_epages",
	"class",

	"ep/ajax"
], function ($, ep, de_epages, Class) {

	var mediaExpr = /(audio|image|video)/;

	Class('de_epages.presentation.Rss', {
		RSSCallbackFunc: null,
		constructor: function( url, callbackFunc, fullPath ){
			//if fullPath is given we dont need to change the rss path
			this.RSSCallbackFunc = callbackFunc;
			this.requestFile(url,fullPath);
		},
		requestFile: function(url,fullPath){
			//check if file is already stored on server
			var fileURL = url;
			if(!fullPath){
				fileURL = '/WebRoot/RssFeeds/'+url.replace(/[^A-Za-z0-9]/g,"_")+'.xml';
			}

			ep.ajax({
				dataType:	'xml',
				url:		fileURL,
				type: 'GET',
				context:	this
			})
			.done(function(data, textStatus, XMLHttpRequest){
				this.readResponse(data);
			})
			.fail(function(data, textStatus, XMLHttpRequest){
				this.requestFeed(url);
			});
		},

		requestFeed: function(url){
			//file is not stored on server ask server to fetch it
			ep.ajax({
				dataType:	'xml',
				data: {
					'ObjectID' : ep.config.siteId,
					'ChangeAction': 'GetFeed',
					'feedurl': url
				},
				context:	this
			})
			.done(function(data, textStatus, XMLHttpRequest){
				this.readResponse(data);
			})
			.fail(function(data, textStatus, XMLHttpRequest){
				//if the second request although fails we do nothing
			});
		},

		readResponse: function(data){
			var itemname,
				subtitle,
				content,
				logo,
				date,
				xmlData = $(data);
			var feedData = {
				'version': null,
				'name': null,
				'description': null,
				'pageLink': null,
				'pubDate': null,
				'logo': {
					'src': null,
					'link': null,
					'title': null
				},
				'items': null
			};
			//rss feed type detection
			if(xmlData.find('rss').length){
				//RSS
				feedData.version = 'RSS';
				itemname = 'item';
				subtitle = 'description';
				content = 'description';
				logo = 'image';
				date = 'pubDate';
			}
			else if(xmlData.find('feed').length){
				//ATOM
				feedData.version = 'ATOM';
				itemname = 'entry';
				subtitle = 'subtitle';
				content = 'summary';
				logo = 'logo';
				date = 'updated';
			}
			//jquery has problems with xml namespaces see: http://bugs.jquery.com/ticket/155
			else if(xmlData.find('rdf\\:RDF').length || xmlData.find('RDF').length){
				//RDF
				feedData.version = 'RDF';
				itemname = 'item';
				subtitle = 'description';
				content = 'description';
				logo = 'image';
				//date = 'date'; //dc\\:date is the correct tag but we have to use only date because of the bug http://bugs.jquery.com/ticket/155
				date = (xmlData.find('dc\\:date')[0] !== undefined)? "dc\\:date" : "date";
			}
			else{
				//no valid feed
				return false;
			}

			//detect name of feed
			feedData.name = xmlData.find('title:first').text();
			//detect description
			var feedDesciption = xmlData.find(subtitle + ':first');
			feedData.description = feedDesciption.length ? feedDesciption.text() : xmlData.find('tagline:first').text();
			//detect link to feeds source page
			var firstLink = xmlData.find('link:first');
			feedData.pageLink = firstLink.text();
			if(!feedData.pageLink){
				var pageLink =  xmlData.find('link[rel="alternate"]:first');
				feedData.pageLink = pageLink.length ? pageLink.attr('href') : firstLink.attr('href');
			}
			//detect logo of feed
			var firstLogoNode = xmlData.find(logo+':first');
			var logoNode = firstLogoNode.length ? firstLogoNode : xmlData.find('icon:first');
			if(logoNode.length){
				var logoSrc = logoNode.find('url');
				feedData.logo.src = logoSrc.length ? logoSrc.text() : logoNode.text();
				if(!feedData.logo.src && logoNode[0].attributes[0]){
					feedData.logo.src = logoNode[0].attributes[0].value;
				}
				var logoTitle = logoNode.find('title');
				feedData.logo.title = logoTitle.length? logoTitle.text() : feedData.name;
				var logoLink = logoNode.find('link');
				feedData.logo.link = logoLink.length ? logoLink.text() : feedData.pageLink;
			}
			//detect date
			feedData.pubDate = xmlData.find(date + ':first').text();
			if(feedData.pubDate){
				var pareDateString = feedData.pubDate;
				feedData.pubDate = new Date(feedData.pubDate);
				//internet explorers date function can not pare ISO 8601 strings so we have to do it on our own
				if(isNaN(feedData.pubDate)){
					feedData.pubDate = new Date(pareDateString.substr(0,19).replace(/-/g,"/").replace(/[TZ]/g," "));
				}
			}
			var items = [];
			xmlData.find(itemname).each(function(index, elm){
				var item = {};
				var tmpElm = $(elm);
				//get title of news
				item.title = tmpElm.find('title:first').text();
				//get link of news
				if(feedData.version == 'ATOM'){
					var linkNode = tmpElm.find('link[rel="alternate"]:first');
					item.link = linkNode.length ? linkNode.attr('href') : tmpElm.find('link:first').attr('href');
				}
				else{
					var linkNode =tmpElm.find('link:first');
					item.link = linkNode.length ? linkNode.text() : feedData.pageLink;
				}
				//get content of news
				var textNode = tmpElm.find(content + ':first');
				item.text = textNode.length ? textNode.text() : tmpElm.find('content:first').text();
				if(!item.text){
					textNode = tmpElm.find('content\\:encoded:first');
					item.text = textNode.length ? textNode.text() : '';
				}
				else{
					textEncodedNode = tmpElm.find('content\\:encoded:first');
					item.textEncoded = textEncodedNode.length ? textEncodedNode.text(): tmpElm.find('encoded').text();
				}

				//get media elements of news
				item.audio = [];
				item.image = [];
				item.video = [];
				if(feedData.version == 'RSS'){
					tmpElm
						.find('enclosure')
						.each(function(){
							var elem = $(this),
								type = elem
									.attr('type')
									.replace(/\/.*$/,'');

							if( mediaExpr.test(type) ){
								item[ type ].push( elem.attr('url') );
							}
						});
				}

				//get pubDate if given
				var pubDateNode = tmpElm.find('pubDate:first');
				item.pubDate = pubDateNode.length ? pubDateNode.text() : tmpElm.find('published:first').text();
				if(item.pubDate){
					item.pubDate = new Date(item.pubDate);
				}
				items.push(item);
			});
			feedData.items = items;

			//give data to callback function
			this.RSSCallbackFunc(feedData);
			return true;
		}
	});

	return de_epages;

});