/** 
 * Simple jQuery "newsticker" plugin.
 *
 * {newsticker:type=(fade|curtain|scroll|slide|slidefade)|delay=(ms)|speed=(ms)|easing=(linear|swing)}
 * * *Heading1* text text text
 * * *Heading2* text text text
 * * *Heading3* text text text  
 * {newsticker}
 *
 * Lewis Stewart
 * (c) Crocodile Clips Ltd
 */

(function($) {

	$.fn.ccnews = function( options ) 
	{
		var opts = $.extend( {}, $.fn.ccnews.defaults, options );
		return $(this).each( function() {
			$this = $(this);
			var o = $.metadata ? $.extend( {}, opts, $this.metadata() ) : opts;
			$this.each( function() { attach( this, o ); } );
		} );
	};

	$.fn.ccnews.defaults = 
	{
		width:       210,
		height:      'fit',
		controls:    true,
		type:        'slidefade', // type of display (fade|curtain|scroll|slide|slidefade|swap)
		orientation: 'vertical',  // for 'slide', the plane of movement (horizontal|vertical)
		direction:   'rtl',       // for 'slide', direction of movement (rtl|ltr)
		delay:       5000,        // duration each item is displayed (ms)		
		speed:       1000,        // speed of transition (slow|normal|fast|[millis])
		easing:      'linear',    // easing for transition (linear|swing)
		transitions: { 
			fade: { 
				concurrent: false,
				prep: {}, 
				tin:  { opacity: "show" }, 
				tout: { opacity: "hide" } 
			},
			curtain: { 
				concurrent: false,			
				prep: {}, 
				tin:  { height: "show" }, 
				tout: { height: "hide" }  
			},
			scroll: { 
				concurrent: true,			
				prep: function(el){ return {display: "block", top: $(el).outerHeight(true)} }, 
				tin:  function(el){ return {top: 0}; },
				tout: function(el){ return {top: -$(el).height()}; } 
			},			
			slide: {
				concurrent: true,			
				prep: function(el){ return {display: "block", left: $(el).outerWidth(true), top: 0} }, 
				tin:  function(el){ return {top: 0, left: 0}; },
				tout: function(el){ return {top: 0, left: -$(el).outerWidth(true)}; } 
			},
			slidefade: {
				concurrent: true,			
				prep: function(el){ return {display: "block", top: $(el).outerHeight(true)} }, 
				tin:  {top: 0, left: 0},
				tout: {opacity: "hide"} 			
			}
		}
	};

	function attach( el, opts )
	{
		el.opts = opts;
		
		var $el = $(el);
		var $ul = $el.find( "ul" );
		var $li = $ul.find( "li" );

		$li.css( {width: opts.width, top: 0, left: 0} );
		$ul.css( {width: $li.outerWidth(true) } );
		$el.css( {width: $ul.outerWidth() } );

		var mh = 0;
		if( opts.height!="fit" )
		{
			mh = opts.height;
		}
		else
		{		
			$li.each( function() { var h = $(this).outerHeight(true); if( h>mh ) mh = h; } );
		}
		$ul.css( {height: mh} );
		$li.css( {height: mh} );
		
		$li.not( ":eq(0)" ).hide();
		$li.hover(
			function() { pause( el ); },
			function() { pause( el ); }
		);	
		
		$( ".next",  el ).click( function() { uinext(  el ); } );
		$( ".prev",  el ).click( function() { uiprev(  el ); } );
		$( ".pause", el ).click( function() { uipause( el ); } );
		$( ".all",   el ).click( function() { uiall(   el ); } );

		if( opts.controls == false )
		{
			$( ".prev,.pause,.next,.all", el ).hide();
		}

		el.transPrep = function( el, cb )
		{
			var tp = opts.transitions[opts.type].prep;
			if( $.isFunction( tp ) ) tp = tp(el);
			$(el).css( tp );
		};
		
		el.transIn  = function( el, cb ) 
		{ 
			var ts = opts.transitions[opts.type].tin;
			if( $.isFunction( ts ) ) ts = ts(el);
			$(el).animate( ts,  opts.speed, opts.easing, cb ); 
		};
		
		el.transOut = function( el, cb ) 
		{ 
			var ts = opts.transitions[opts.type].tout;
			if( $.isFunction( ts ) ) ts = ts(el);
			$(el).animate( ts, opts.speed, opts.easing, cb ); 
		};			

		el.items = $li;
		el.current = 0;
		el.paused = false;
		el.uipaused = false;
				
		start( el );
	};

	function start( el )
	{
		el.timer = setInterval( function() { tick( el ) }, el.opts.delay );
	};

	function stop( el )
	{
		clearInterval( el.timer );
	};
	
	function pause( el )
	{
		el.paused = !el.paused;
		(el.paused || el.uipaused) ? $( ".pause", el ).addClass( "paused" ) : $( ".pause", el ).removeClass( "paused" );		
	};	

	function uipause( el )
	{
		el.uipaused = !el.uipaused;
		(el.paused || el.uipaused) ? $( ".pause", el ).addClass( "paused" ) : $( ".pause", el ).removeClass( "paused" );
	};
	
	function uinext( el )
	{
		$(el.items).each( function(){ $(this).stop(true,true); } );
		trans( el, el.current, ++el.current % el.items.size() );
	};
	
	function uiprev( el )
	{
		$(el.items).each( function(){ $(this).stop(true,true); } );
		trans( el, el.current, (el.items.size() + (el.current-1)) % el.items.size() );
	};	
	
	function uiall( el )
	{
		$(el.items).each( function(){ $(this).stop(true,true).show(); } );	
	};	
	
	function tick( el )
	{
		if( el.paused || el.uipaused ) return;
		trans( el, el.current, ++el.current % el.items.size() );
	};
	
	function trans( el, idx1, idx2 )
	{
		stop( el );	
		el.current = idx2;
		el.transPrep( $(el.items[idx2]) );	
		if( el.opts.transitions[el.opts.type].concurrent==true )
		{
			el.transOut( $(el.items[idx1]) );		
			el.transIn( $(el.items[idx2]), function() { start( el ); } );					
		} 
		else
		{	
			el.transOut( 
				$(el.items[idx1]), 
				function() {
					el.transIn( 
						$(el.items[idx2]), 
						function() {
							start( el ); 
						} 
					);			
				} 
			);
		}
	};

})(jQuery);