/*

---- dmxFeedTicker options
	feeds:			[],		// string with the feed or an array with feed strings/objects
	showItems:		0,		// number of items to display (0 is all items of a feed)
	fetchItems:		5,		// number of items to fetch per feed
	displayType:	'img',	// display the images or titles from the feed ('img' or 'txt')
	orientation:	'ver',	// orientation of the images ('ver' or 'hor')
	thumbSize:		2,		// size of the images (0:small, 1:medium, 2:large)
	linkTarget:		'_blank',	// target for the links
	title:			null	// id of element to use to contain the title
---- options from cycle plugin
    fx:           'fade', // one of: fade, shuffle, zoom, slideX, slideY, scrollUp/Down/Left/Right 
    timeout:       4000,  // milliseconds between slide transitions (0 to disable auto advance) 
    continuous:    0,     // true to start next transition immediately after current one completes 
    speed:         1000,  // speed of the transition (any valid fx speed value) 
    speedIn:       null,  // speed of the 'in' transition 
    speedOut:      null,  // speed of the 'out' transition 
    next:          null,  // id of element to use as click trigger for next slide 
    prev:          null,  // id of element to use as click trigger for previous slide 
    prevNextClick: null,  // callback fn for prev/next clicks:  function(isNext, zeroBasedSlideIndex, slideElement) 
    pager:         null,  // id of element to use as pager $container 
    pagerClick:    null,  // callback fn for pager clicks:  function(zeroBasedSlideIndex, slideElement) 
    pagerAnchorBuilder: null, // callback fn for building anchor links 
    before:        null,  // transition callback (scope set to element to be shown) 
    after:         null,  // transition callback (scope set to element that was shown) 
    end:           null,  // callback invoked when the slideshow terminates (use with autostop or nowrap options) 
    easing:        null,  // easing method for both in and out transitions 
    easeIn:        null,  // easing for "in" transition 
    easeOut:       null,  // easing for "out" transition 
    shuffle:       null,  // coords for shuffle animation, ex: { top:15, left: 200 } 
    animIn:        null,  // properties that define how the slide animates in 
    animOut:       null,  // properties that define how the slide animates out 
    cssBefore:     null,  // properties that define the initial state of the slide before transitioning in 
    cssAfter:      null,  // properties that defined the state of the slide after transitioning out 
    fxFn:          null,  // function used to control the transition 
    height:       'auto', // $container height 
    startingSlide: 0,     // zero-based index of the first slide to be displayed 
    sync:          1,     // true if in/out transitions should occur simultaneously 
    random:        0,     // true for random, false for sequence (not applicable to shuffle fx) 
    fit:           0,     // force slides to fit $container 
    pause:         0,     // true to enable "pause on hover" 
    autostop:      0,     // true to end slideshow after X transitions (where X == slide count) 
    autostopCount: 0,     // number of transitions (optionally used with autostop to define X) 
    delay:         0,     // additional delay (in ms) for first transition (hint: can be negative) 
    slideExpr:     null,  // expression for selecting slides (if something other than all children is required) 
    cleartype:     0,     // true if clearType corrections should be applied (for IE) 
    nowrap:        0      // true to prevent slideshow from wrapping 

*/

(function($) {

if (!window.google) {
    alert("You must include the Google AJAX Feed API script");
    return;
}

if (!google.feeds) google.load("feeds", "1");

var defaultOptions = {
	feeds: [],
	showItems: 0, // showItems
	fetchItems: 5, // fetchItems
	displayType: "img", //thumbs: true, // displayType = txt / img
	orientation: "ver", //horizontal: false, // orientation = hor / ver
	thumbSize: 2,
	linkTarget: "_blank",
	title: null,
	pause: 1,
	fx: "random"
};

$.fn.dmxFeedTicker = function(options)
{
	return this.each(function() { $.dmxFeedTicker(this, options); });
}

$.dmxFeedTicker = function(target, options)
{
	var $container = $(target);
	var loaded = 0;
	var errors = 0;
	var feeds = [];
	var results = [];
	
	var config = $.extend({}, defaultOptions, options || {});
	
	init();
	
	function init()
	{
		if (typeof config.feeds == "string") {
			// single feed url
			feeds.push({url: config.feeds});
		} else if (typeof config.feeds == "object") {
			// array of feeds
			for (var i = 0; i < config.feeds.length; i++) {
				var feed = config.feeds[i];
				if (typeof feed == "string") {
					// feed is an url
					feeds.push({url: feed});
				} else if (typeof feed == "object") {
					// feed is an object
					feeds.push(feed);
				}
			}
		}
		
		// stop the cycle plugin (clears the timeout timer)
		$container.children(":first").cycle("stop");
		// stop any animation still running
		$container.find(".dmxFeedTicker_slide").stop();
		// empty container
		$container.addClass("dmxFeedTicker").empty();
		
		if (config.showItems > 0) {
			config.showItems = Math.min(config.showItems, config.fetchItems);
		} else {
			config.showItems = config.fetchItems;
		}
		
		for (var i = 0; i < feeds.length; i++) {
			var feed = new google.feeds.Feed(feeds[i].url);
			feed.setResultFormat(google.feeds.Feed.MIXED_FORMAT);
			feed.setNumEntries(config.fetchItems);
			feed.load(bind(feedLoaded, i));
		}
	}
	
	function bind(method)
	{
		var self = this;
		var opt_args = [].slice.call(arguments, 1);
		return function() {
			var args = opt_args.concat([].slice.call(arguments));
			return method.apply(self, args);
		}
	}
	
	function feedLoaded(index, result)
	{
		loaded++;
		
		if (result.error) {
			result.error.url = feeds[index].url;
			log(result.error);
			if (++errors >= feeds.length) {
				$container.text("No feed could be loaded.");
			}
			return;
		}
		
		if (feeds[index].title) {
			result.feed.title = feeds[index].title;
		}
		results.push(result);
		
		if (loaded == feeds.length) {
			createSlideshow();
		}
	}
	
	function createSlideshow()
	{
		var base = $("<div/>").appendTo($container);
		var maxHeight = 0;
		
		for (var i = 0; i < results.length; i++) {
			var feed = results[i].feed;
			
			if (config.displayType == "img") {
				var table;
				var row = null;
				for (var j = 0; j < feed.entries.length; j++) {
					var entry = feed.entries[j];
					
					if (j%config.showItems == 0) {
						table = $("<table/>").addClass("dmxFeedTicker_table").appendTo($("<div/>").addClass("dmxFeedTicker_slide dmxFeedTicker_table_div").attr("title", feed.title).css({width:"100%",height:"100%"}).appendTo(base));
						row = null;
					}
					
					if (config.orientation == "ver" || row == null) {
						row = $("<tr/>").appendTo(table);
					}
					
					var thumb = getThumb(feed.entries[j]);
					$("<td/>").append(thumb).appendTo(row);
					
					maxHeight = Math.max(maxHeight, table.height());
				}
			} else {
				var list;
				for (var j = 0; j < feed.entries.length; j++) {
					var entry = feed.entries[j];
					
					if (j%config.showItems == 0) {
						list = $("<ul/>").addClass("dmxFeedTicker_list").appendTo($("<div/>").attr("title", feed.title).addClass("dmxFeedTicker_slide").css({width:"100%",height:"100%"}).appendTo(base));
					}
					
					var anode = $("<a/>").attr("href", entry.link)
						.attr("target", config.linkTarget)
						.attr("title", entry.contentSnippet)
						.text(entry.title);
					var div = $("<div/>").addClass("dmxFeedTicker_result")
						.append(anode);
					$("<li/>").append(div).appendTo(list);
					
					var h = parseInt(list.height()) || 0;
					var t = parseInt(list.css("marginTop")) || 0;
					var b = parseInt(list.css("marginBottom")) || 0;
					
					maxHeight = Math.max(maxHeight, h + t + b);
				}
			}
		}
		
		base.width("100%");
		base.height(maxHeight);
		
		if (config.fx == "random") {
			var effects = ["fade","scrollLeft","scrollUp"];
			var effects1 = ["fade","scrollUp","scrollDown","turnUp","turnDown"];
			var effects2 = ["fade","scrollLeft","scrollRight","turnLeft","turnRight"];
			config.fx = (config.displayType == "txt") ? effects[Math.floor(Math.random()*effects.length)] : (config.orientation == "hor") ? effects1[Math.floor(Math.random()*effects.length)] : effects2[Math.floor(Math.random()*effects.length)];
		}
		
		if (config.title) {
			config.before = function() {
				$(config.title).text($(this).attr("title"));
			}
		}
		
		base.cycle(config);
	}
	
	function getThumb(entry)
	{
		var thumbNodes = google.feeds.getElementsByTagNameNS(entry.xmlNode, "http://phobos.apple.com/rss/1.0/modules/itms/", "coverArt");
		if (!thumbNodes || thumbNodes.length == 0) {
			thumbNodes = google.feeds.getElementsByTagNameNS(entry.xmlNode, "http://search.yahoo.com/mrss/", "thumbnail");
			if (!thumbNodes || thumbNodes.length == 0) {
				thumbNodes = google.feeds.getElementsByTagNameNS(entry.xmlNode, "http://search.yahoo.com/mrss", "thumbnail");
				if (!thumbNodes || thumbNodes.length == 0) {
					thumbNodes = google.feeds.getElementsByTagNameNS(entry.xmlNode, "http://search.yahoo.com/mrss/", "content");
					for (var i = thumbNodes.length - 1; i >= 0; i--) {
						if ($(thumbNodes[i]).attr("type").indexOf("image") == -1) {
							thumbNodes.splice(i, 1);
						}
					}
					if (!thumbNodes || thumbNodes.length == 0) {
						thumbNodes = google.feeds.getElementsByTagNameNS(entry.xmlNode, "http://search.yahoo.com/mrss", "content");
						for (var i = thumbNodes.length - 1; i >= 0; i--) {
							if ($(thumbNodes[i]).attr("type").indexOf("image") == -1) {
								thumbNodes.splice(i, 1);
							}
						}
						if (!thumbNodes || thumbNodes.length == 0) {
							return null;
						}
					}
				}
			}
		}
		
		var ti = 0;
		if (config.thumbSize == 0) ti = 0;
		if (config.thumbSize == 1) ti = Math.floor(thumbNodes.length / 2);
		if (config.thumbSize == 2) ti = thumbNodes.length - 1;
		
		var node = $(thumbNodes[ti]);
		
		var defSize = 50;
		if (config.thumbSize == 0) defSize = 50;
		if (config.thumbSize == 1) defSize = 80;
		if (config.thumbSize == 2) defSize = 110;
		
		var img = $("<img />").attr("src", node.attr("url") ? node.attr("url") : node.text())
			.attr("width", node.attr("width") || defSize)
			.attr("height", node.attr("height") || defSize);
		
		var anode = $("<a />").attr("href", entry.link)
			.attr("target", config.linkTarget)
			.attr("title", entry.title.replace(/^\d*\./, ""))
			.append(img);
		var div = $("<div />").addClass("dmxFeedTicker_result")
			.append(anode);
		
		return div;
	}
	
	function log()
	{
		if (window.console && window.console.log)
        window.console.log('[dmxFeedTicker] ', arguments);
	}
}

})(jQuery);
