﻿/*
News ticker plugin (BBC news style)
Bryan Gullan,2007-2010
version 2.2
updated 2010-04-04
Documentation at http://www.makemineatriple.com/news-ticker-documentation/
Demo at http://www.makemineatriple.com/jquery/?newsTicker
Use and distrubute freely with this header intact.
*/

(function ($) {

	var name = 'newsTicker';

	function runTicker(settings) {

		tickerData = $(settings.newsList).data('newsTicker');

		if (tickerData.currentItem > tickerData.newsItemCounter) {
			// if we've looped to beyond the last item in the list, start over
			tickerData.currentItem = 0;
		}
		else if (tickerData.currentItem < 0) {
			// if we've looped back before the first item, move to the last one
			tickerData.currentItem = tickerData.newsItemCounter;
		}

		if (tickerData.currentPosition == 0) {
			if (tickerData.newsLinks[tickerData.currentItem].length > 0) {
				$(tickerData.newsList).empty().append('<li><a href="' + tickerData.newsLinks[tickerData.currentItem] + '"></a></li>');
			}
			else {
				$(tickerData.newsList).empty().append('<li></li>');
			}
		}

		//only start the ticker itself if it's defined as animating: otherwise it's paused or under manual advance
		if (tickerData.animating) {

			if (tickerData.currentPosition % 2 == 0) {
				var placeHolder = tickerData.placeHolder1;
			}
			else {
				var placeHolder = tickerData.placeHolder2;
			}

			if (tickerData.currentPosition < tickerData.newsItems[tickerData.currentItem].length) {
				// we haven't completed ticking out the current item

				var tickerText = tickerData.newsItems[tickerData.currentItem].substring(0, tickerData.currentPosition);
				if (tickerData.newsLinks[tickerData.currentItem].length > 0) {
					$(tickerData.newsList + ' li a').text(tickerText + placeHolder);
				}
				else {
					$(tickerData.newsList + ' li').text(tickerText + placeHolder);
				}
				tickerData.currentPosition++;
				setTimeout(function () { runTicker(settings); settings = null; }, tickerData.tickerRate);
			}

			else {
				// we're on the last letter of the current item

				if (tickerData.newsLinks[tickerData.currentItem].length > 0) {
					$(tickerData.newsList + ' li a').text(tickerData.newsItems[tickerData.currentItem]);
				}
				else {
					$(tickerData.newsList + ' li').text(tickerData.newsItems[tickerData.currentItem]);
				}

				setTimeout(function () {
					if (tickerData.animating) {
						tickerData.currentPosition = 0;
						tickerData.currentItem++;
						runTicker(settings); settings = null;
					}
				}, tickerData.loopDelay);

			}
		}

		else {// settings.animating == false 

			// display the full text of the current item
			var tickerText = tickerData.newsItems[tickerData.currentItem];

			if (tickerData.newsLinks[tickerData.currentItem].length > 0) {
				$(tickerData.newsList + ' li a').text(tickerText);
			}
			else {
				$(tickerData.newsList + ' li').text(tickerText);
			}

		}

	}


	// 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 newsItems = new Array();
		var newsLinks = new Array();
		var newsItemCounter = 0;

		// Hide the static list items
		$(settings.newsList + ' li').hide();

		// Store the items and links in arrays for output
		$(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++;
		});

		var tickerElement = $(settings.newsList); // for quick reference below

		tickerElement.data(name, {
			newsList: settings.newsList,
			tickerRate: settings.tickerRate,
			startDelay: settings.startDelay,
			loopDelay: settings.loopDelay,
			placeHolder1: settings.placeHolder1,
			placeHolder2: settings.placeHolder2,
			controls: settings.controls,
			ownControls: settings.ownControls,
			stopOnHover: settings.stopOnHover,
			newsItems: newsItems,
			newsLinks: newsLinks,
			newsItemCounter: newsItemCounter - 1, // -1 because we've incremented even after the last item (above)
			currentItem: 0,
			currentPosition: 0,
			firstRun: 1
		})
        .bind({
        	stop: function (event) {
        		// show remainder of the current item immediately
        		tickerData = tickerElement.data(name);
        		if (tickerData.animating) { // only stop if not already stopped
        			tickerData.animating = false;
        		}
        	},
        	play: function (event) {
        		// show 1st item with startdelay
        		tickerData = tickerElement.data(name);
        		if (!tickerData.animating) { // if already animating, don't start animating again
        			tickerData.animating = true;
        			setTimeout(function () { runTicker(tickerData); tickerData = null; }, tickerData.startDelay);
        		}
        	},
        	resume: function (event) {
        		// start from next item, with no delay
        		tickerData = tickerElement.data(name);
        		if (!tickerData.animating) { // if already animating, don't start animating again
        			tickerData.animating = true;
        			// set the character position as 0 to ensure on resume we start at the right point
        			tickerData.currentPosition = 0;
        			tickerData.currentItem++;
        			runTicker(tickerData); // no delay when resuming.
        		}
        	},
        	next: function (event) {
        		// show whole of next item
        		tickerData = tickerElement.data(name);
        		// stop (which sets as non-animating), and call runticker
        		$(tickerData.newsList).trigger("stop");
        		// set the character position as 0 to ensure on resume we start at the right point
        		tickerData.currentPosition = 0;
        		tickerData.currentItem++;
        		runTicker(tickerData);
        	},
        	previous: function (event) {
        		// show whole of previous item
        		tickerData = tickerElement.data(name);
        		// stop (which sets as non-animating), and call runticker
        		$(tickerData.newsList).trigger("stop");
        		// set the character position as 0 to ensure on resume we start at the right point
        		tickerData.currentPosition = 0;
        		tickerData.currentItem--;
        		runTicker(tickerData);
        	}
        });
		if (settings.stopOnHover) {
			tickerElement.bind({
				mouseover: function (event) {
					tickerData = tickerElement.data(name);
					if (tickerData.animating) { // stop if not already stopped
						$(tickerData.newsList).trigger("stop");
						if (tickerData.controls) { // ensure that the ticker can be resumed if controls are enabled
							$('.stop').hide();
							$('.resume').show();
						}
					}
				}
			});
		}

		tickerData = tickerElement.data(name);

		// set up control buttons if the option is on
		if (tickerData.controls || tickerData.ownControls) {
			if (!tickerData.ownControls) {
				$('<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="previous"><a href="#previous">Previous</a></li><li class="next"><a href="#next">Next</a></li></ul>').insertAfter($(tickerData.newsList));
			}
			$('.play').hide();
			$('.resume').hide();

			$('.play').click(function (event) {
				$(tickerData.newsList).trigger("play");
				$('.play').hide();
				$('.resume').hide();
				$('.stop').show();
				event.preventDefault();
			});
			$('.resume').click(function (event) {
				$(tickerData.newsList).trigger("resume");
				$('.play').hide();
				$('.resume').hide();
				$('.stop').show();
				event.preventDefault();
			});
			$('.stop').click(function (event) {
				$(tickerData.newsList).trigger("stop");
				$('.stop').hide();
				$('.resume').show();
				event.preventDefault();
			});
			$('.newsticker-previous').click(function (event) {
				$(tickerData.newsList).trigger("previous");
				$('.stop').hide();
				$('.resume').show();
				event.preventDefault();
			});
			$('.newsticker-next').click(function (event) {
				$(tickerData.newsList).trigger("next");
				$('.stop').hide();
				$('.resume').show();
				event.preventDefault();
			});

		};

		// tell it to play
		$(tickerData.newsList).trigger("play");
	};

	// News ticker defaults 
	jQuery.fn[name].defaults = {
		newsList: "#news",
		tickerRate: 80,
		startDelay: 100,
		loopDelay: 3000,
		placeHolder1: " |",
		placeHolder2: "_",
		controls: true,
		ownControls: false,
		stopOnHover: true
	}

})(jQuery);
