/*
News ticker plugin (BBC news style)
Bryan Gullan,2007-2010
version 2.1
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.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>');
			}
		}
		
		//only start the ticker itself if it's defined as running: otherwise it's paused or under manual advance
		if (settings.running) {
			
			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);
	 
        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><li class="next"><a href="#next">Next</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();
		    });
		    $('.next').click(function(event){
		        $(settings.newsList).trigger("next");
		        $('.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.
		        }
		  	},
		  	next: function(event) {
		  		var data = tickerElement.data(name);
		  		// stop (which sets as non-running), and call runticker
		  		$(settings.newsList).trigger("stop");
		  		runTicker(data);
		  	}
		}); 	
		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);
