/*
News ticker plugin (BBC news style)
Bryan Gullan,2007-2010
version 2.0
updated 2010-03-28
http://www.makemineatriple.com/jquery
Use and distrubute freely with the header up to this point.

Options (defaults shown):
newsList: "#news" 	// assumes unordered list; specify the ul holding the news items
tickerRate: 80 		// time gap between display of each letter (ms)
startDelay: 100 	// delay before first run of the ticker (ms)
loopDelay: 3000 	// time for which full text of each item is shown at end of print-out (ms)
placeHolder1: " |"	// character placeholder shown on even loops
placeHolder2: "_"	// character placeholder shown on odd loops
controls: true,		// show resume / stop controls (see below for the markup added)
stopOnHover: true	// trigger the stop action on hovering over the links

Sample usage:
$(document).ready(function() {
	var options = {
  		newsList: "#news",
 		startDelay: 10,
 		placeHolder1: " []"
	}
	$().newsTicker(options);
});

for markup as follows:

<ul id="news">
<li><a href="http://www.makemineatriple.com">MakeMineATriple.com</a></li>
<li><a href="http://www.jquery.com">jQuery</a></li>
</ul>

Underline text decoration on the link is not recommended! :-)

If you enable the controls, the following will be added just after your list of items:
<ul class="ticker-controls">
<li class="play"><a href="#play">Play</a></li>
<li class="resume"><a href="#resume">Resume</a></li>
<li class="stop"><a href="#stop">Stop</a></li>
</ul>

Only one of these will be visible at any one time, depending on the play state of the ticker.

*/

(function($) {
	
	function runTicker(settings) {
		
		if (settings.running) {
			if(settings.firstRun == 1){
				currentLength = settings.currentLength;
				currentItem = settings.currentItem;
				settings.firstRun = 0;
			}
			if(currentItem == settings.newsItemCounter + 1){
				currentItem = 0;
			}
			
			if(currentLength == 0) {
				if(settings.newsLinks[currentItem].length > 0) {
					$(settings.newsList).empty().append('<li><a href="'+ settings.newsLinks[currentItem] +'"></a></li>');
				}
				else {
					$(settings.newsList).empty().append('<li></li>');
				}
			}
			
			if( currentLength % 2 == 0) {
					placeHolder = settings.placeHolder1;
			}
			else {
				placeHolder = settings.placeHolder2;
			}
			
			if( currentLength <= settings.newsItems[currentItem].length + 1) {
				var tickerText = settings.newsItems[currentItem].substring(0,currentLength);
				if(settings.newsLinks[currentItem].length > 0) {
					$(settings.newsList + ' li a').text(tickerText + placeHolder);
				}
				else {
					$(settings.newsList + ' li').text(tickerText + placeHolder);
				}
				currentLength ++;
				setTimeout(function(){runTicker(settings); settings = null;},settings.tickerRate);
			}
			else {
				if(settings.newsLinks[currentItem].length > 0) {
					$(settings.newsList + ' li a').text(settings.newsItems[currentItem]);
				}
				else {
					$(settings.newsList + ' li').text(settings.newsItems[currentItem]);
				}
				currentLength = 0;
				currentItem ++;
				setTimeout(function(){runTicker(settings); settings = null;},settings.loopDelay);	
			}
		}
		else {
			// settings.running == false
			if (currentLength < settings.newsItems[currentItem].length + 1) {
				//if the entire text of the current item hasn't yet been shown: [display it all]
				var tickerText = settings.newsItems[currentItem];
				if(settings.newsLinks[currentItem].length > 0) {
					$(settings.newsList + ' li a').text(tickerText);
				}
				else {
					$(settings.newsList + ' li').text(tickerText);
				}
				// increment current item so that on resume we scroll out the next item
				currentItem ++;
				currentLength = 0;
			}
		}
	}
	
	var name='newsTicker';
	
	// Core plugin setup and config
	jQuery.fn[name] = function(options) {
 
	    // Add or overwrite options onto defaults
	    var settings = jQuery.extend({}, jQuery.fn.newsTicker.defaults, options);
	 
	    // Iterate matched elements
	    
	        var tickerElement = $(settings.newsList);
	        
	        var newsItems = new Array();
			var newsLinks = new Array();
			var newsItemCounter = 0;
			
			$(settings.newsList + ' li').hide();
			
			$(settings.newsList + ' li').each(function(){
				if($(this).children('a').length) {
					newsItems[newsItemCounter] = $(this).children('a').text();
					newsLinks[newsItemCounter] = $(this).children('a').attr('href');
				}
				else {
					newsItems[newsItemCounter] = $(this).text();
					newsLinks[newsItemCounter] = '';
				}
				newsItemCounter ++;
			});

			// set up control buttons if the option is on
			if (settings.controls) {
				$('<ul class="ticker-controls"><li class="play"><a href="#play">Play</a></li><li class="resume"><a href="#resume">Resume</a></li><li class="stop"><a href="#stop">Stop</a></li></ul>').insertAfter($(settings.newsList));
				$('.play').hide();
			    $('.resume').hide();
				
			    $('.play').click(function(event){
			        $(settings.newsList).trigger("play");
			        $('.play').hide();
			        $('.resume').hide();
			        $('.stop').show();
			        event.preventDefault();
			    });
			    $('.resume').click(function(event){
			        $(settings.newsList).trigger("resume");
			        $('.play').hide();
			        $('.resume').hide();
			        $('.stop').show();
			        event.preventDefault();
			    });
				$('.stop').click(function(event){
			        $(settings.newsList).trigger("stop");
			        $('.stop').hide();
			        $('.resume').show();
			        event.preventDefault();
			    });
		    };
	        
	        tickerElement.data(name, {
	        	newsList: settings.newsList,
				tickerRate: settings.tickerRate,
				startDelay: settings.startDelay,
				loopDelay: settings.loopDelay,
				placeHolder1: settings.placeHolder1,
				placeHolder2: settings.placeHolder2,
	            newsItems: newsItems,
				newsLinks: newsLinks,
				newsItemCounter: newsItemCounter - 1,
				currentItem: 0,
				currentLength: 0,
				firstRun:1
	        })
	        .bind({
				stop: function(event) {
			    	var data = tickerElement.data(name);
			    	if (data.running) {
	            		data.running = false;
	            	}
			  	},
			  	play: function(event) {
			    	var data = tickerElement.data(name);
			    	if (!data.running) {
		            	data.running = true;
		            	setTimeout(function(){runTicker(data); data = null;},settings.loopDelay);
		            }
			  	},
			  	resume: function(event) {
			    	var data = tickerElement.data(name);
			    	if (!data.running) {
		            	data.running = true;
			            runTicker(data); //no delay when resuming.
			        }
			  	}
			}); 	
			if (settings.stopOnHover) {
		    	tickerElement.bind({			    	
				  	mouseover: function(event) {
				  		var data = tickerElement.data(name);
				    	if (data.running) {
					  		$(settings.newsList).trigger("stop");
					  		if (settings.controls) {
					  			$('.stop').hide();
				        		$('.resume').show();
					  		}
				  		}
				  	}
				});
	    	}
	    	
	    	// tell it to play
	    	$(settings.newsList).trigger("play");
	};

	
	// News ticker defaults 
	jQuery.fn[name].defaults = {
	    newsList: "#news",
		tickerRate: 80,
		startDelay: 100,
		loopDelay: 3000,
		placeHolder1: " |",
		placeHolder2: "_",
		controls: true,
		stopOnHover: true
	}

})(jQuery);
