/**
 *  JavaScript file that defines all of the data sources for the feed aggregator
 * 
 *  @author luisat
 *  @requires jQuery 1.2.3
 *  @requires string-utils.js
 *  @requires array-utils.js
 *  @requires utils.js 
 */

if(!isLoggingEnabled) var isLoggingEnabled = false;
if(!citrix) var citrix = {};
if(!citrix.ws) citrix.ws = {};
if(!citrix.ws.isv) citrix.ws.isv = {};
if(ISV == null) var ISV = citrix.ws.isv;
if(ISV.log == null && isLoggingEnabled) ISV.log = log4javascript.getDefaultLogger();



// parent feed source class
ISV.FeedSource = function(datasource) {
	
	// assert invariants
	if(StringUtils.isEmpty(datasource)) {
		throw {
			name: "InitializeException",
			message: "Please provide all parameters when constructing a feed source"
		}
	}	
	var source = datasource;	
	var ready = false;
	
	return {
		getDataSource : function() {
			return source;
		},
		setDataSource : function(newSource) {				
			source = newSource;
		},
		isReady: function() {			
			return ready;
		},
		setIsReady: function(isReady) {
			ready = isReady;
		},			
		////  it is the responsability of each feed source to implement this method and locally
		////  cache the feed items
		fetchFeedItems: function() {		
			throw {
				name: "UnsupportedMethodException",
				message: "Method has not been defined in child class"
			}
		}
	}	
};


/////  Custom Data Source for Yahoo Pipes /////
ISV.YahooPipeFeedSource = function(config) {
	
	if(!config) {
		throw {
			name: "InitializeException",
			message: "Please config parameters when constructing yahoo pipe source!"
		}		 	
	}
			
	///  feed categories for yahoo pipe ///
	var sourceNames = [
		"CTV",
		"Yahoo",
		"Twitter",
		"Citrix Blogs",
		config.partner + " RSS",
		"3rd Party Feeds",
		"Community Verified"									
	];
	
	var displayNames = [	
		"Citrix TV",
		"Yahoo",
		"Twitter",
		"Citrix Blogs",
		config.partnerDisplayName + " RSS",
		"3rd Party Feeds",
		"Community Verified"	
	];
	
	// this is used to avoid cross domain security errors
	// for more information visit http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/
	// hidden private var
	var JSONP = "_callback=?";
	
	// yahoo pipe location
	// hidden private var
	var dataLoc = "http://pipes.yahoo.com/pipes/pipe.run?";
		
	// Note: do not leave config parameters empty. Yahoo pipes will throw an exception if any
	// of its input parameters are left empty	
	// build datasource from configuration	
	var datasource = 
		dataLoc + 
			"_id=" + config.sourcePipeID +
			"&_render=json&feedLimit=" + config.feedLimit + 
			"&total=" + config.total + 
			"&partner=" + config.partner + 
			"&partnerRSS=" + encodeURIComponent(config.partnerRSS) + 
			"&tpPipeRSSID=" + config.tpPipeRSSID + 
			"&searchSite=" + encodeURIComponent(config.searchSite) + 
			"&tpPipeLimit=" + config.tpPipeLimit + 
			"&" + JSONP;
		    	
	// inheritance ( a call to super )
	var parentObject = new ISV.FeedSource(datasource);				
	jQuery.extend(this, parentObject);	
	
	// cache feed items for pagination
	var feedItems = new Array();		
	
	// get pipe property helper
	var buildPipePropertyObject = function(pipeData) {
		if(!pipeData) {
			return;
		}			
		// this is the set of pipe properties we are supporting		
		var pipeProps = {
			"items" : pipeData.hasOwnProperty("value") && pipeData.value && 
						pipeData.value.hasOwnProperty("items") ? pipeData.value.items : null,
			
			"title" : pipeData.hasOwnProperty("value") && pipeData.value &&  
						pipeData.value.hasOwnProperty("title") ? pipeData.value.title : null,
			
			"count" : pipeData.hasOwnProperty("count") ? pipeData.count : null				
		}	
		return pipeProps;										
	}

	this.getFeedItems = function () {
		return feedItems;
	}
	
	this.isEmpty = function () {
		return feedItems.length === 0;
	}

	// @Override
	// every custom feed source should override this method so that it is able to 
	// pull data. Every class is enforced to implement this method, otherwise, they
	// will get an UnsupportedOperation exception	
	this.fetchFeedItems = function () {
		
		// make AJAX request to yahoo pipe source and extract feed items
		var that = this;  // for in closure reference to this
		jQuery.getJSON(this.getDataSource(), 
			function(pipeData) {				
				if(pipeData) {
					feedItems = new Array();
					// response code 200, extract pipe data
					var props = buildPipePropertyObject(pipeData);					
					var jsonItems = props["items"];									
					for(var i = 0; i < jsonItems.length; i++) {
						
						var title = StringUtils.deleteNewlineChars(jsonItems[i].title);   										
						var category = jsonItems[i].category;
						var description = jsonItems[i].description;
						var link = jsonItems[i].link;
						var pubDate = jsonItems[i].pubDate || null;						
										
																											
						try {
							
							// regex to extract source and title									 							 				
							var source = /^([^:]+):(.*)$/.exec(title)[1];
							
							// attempt to parse date 
							if(pubDate) {									
								if(isNaN(Date.parse(pubDate))) {
									if(isLoggingEnabled) {
										ISV.log.warn("Unparseable date for source " + source);										
									}
									pubDate = null;
								}																							
							}
							
							var newItem = null;	
							var newItemInit = {
								title : title,
								category : category,
								description : description,
								link : link,
								date : pubDate,
								source : source,
								icon : ""								
							};
							
							var index = ArrayUtils.find(sourceNames,source);		
							
							if(isLoggingEnabled) {									
								ISV.log.debug("index is " + index + " for source  " + source);
							}
							
							// Note: as per RDY-1015 we will have display names for
							// 		 the different feed sources
							newItemInit.displayName = displayNames[index];
												
							switch(index) {
								case 0:  /* CTV */ 
									newItemInit.icon = "/res/i/isv/citrixtv-icon.gif";
									newItem = new ISV.CTVFeedItem(newItemInit);									
									break;
								
								case 1:  /* Yahoo */
									newItemInit.icon = "/res/i/isv/yahoofeed-icon.gif";
									newItem = new ISV.FeedItem(newItemInit);
									break;
								
								case 2:  /* Twitter */
									newItemInit.icon = "/res/i/isv/twitter-icon.gif";
									newItem = new ISV.FeedItem(newItemInit);
									break;
								
								default: /* blogs, partner , 3rd Party, verified */								
									newItemInit.icon = "/res/i/isv/blogs-icon.gif"
									newItem = new ISV.FeedItem(newItemInit);
									break;	 
							}
							
							feedItems.push(newItem);
							if(isLoggingEnabled) {									
								ISV.log.debug("Pushed feed item with source :" + 
									newItem.getSource() + " and title: " + newItem.getTitle());
							}							
						}
						catch(e) {							
							// continue
							if(isLoggingEnabled) {									
								ISV.log.error("Exception creating feed item: " + e.message);
							}
						}																				
					}
					
					 // send a copy of the array					
					that.setIsReady(true);
				}
				else {					 
					alert("Cannot retrieve data from yahoo pipe!");
				}
			}	
		);			
	}			
	return this;
};