( function( $ ) {
	$.fn.marquee = function( opts ) {
		var defaults = {
			content : new Array(),
			interval : new Array(),
			id : 0,
			delay : 6000,
			count : 1,
			height : 20,
			direction : 'up',
			handler : false
		};
		defaults.marqueeBox = document.createElement( 'DIV' );
		$( defaults.marqueeBox ).css({
			'overflow' : 'hidden',
			'height' : defaults.height + 'px',
			'list-style' : 'none',
			'line-height' : defaults.height + 'px'
		});
		var options = $.extend( defaults , opts );
		var str = new Array();
		var nextLine = new Array();
		options.handler && $( options.handler ).css({ 'float' : 'right' , 'cursor' : 'pointer' });
		$( this ).mouseover( function() {
			options.handler && $( options.handler ).show();
			clearInterval( options.interval[0] );
		}).mouseout( function() {
			options.handler && $( options.handler ).hide();
			options.interval[0] = setInterval( function() { startMarquee( options.direction ); } , options.delay );
		});
		$( options.marqueeBox ).css({ 'height' : options.height * options.count });
		options.count = options.count > options.content.length ? options.content.length : options.count;
		$( this ).append( options.marqueeBox );
		for( var i = 0 ; i < options.count ; i++ ) {
			$( options.marqueeBox ).append( '<div>'+ options.content[i] +'</div>' );
		}
		options.handler && $( '[_direction=up]' , options.handler ).click( function() {
			startMarquee( 'up' );
		});
		options.handler && $( '[_direction=down]' , options.handler ).click( function() {
			startMarquee( 'down' );
		});
		options.id += options.count;
		options.interval[0] = setInterval( function() { startMarquee( options.direction ); } , options.delay );
					 		
		function startMarquee( direction ) {
			for( var i = 0 ; i < options.count ; i++ ) {
				str[i] = options.content[options.id++];
				if( options.id >= options.content.length ) 
					options.id = 0;
				if( options.marqueeBox.childNodes.length == options.count ) {
					nextLine[i] = document.createElement( 'DIV' );
					nextLine[i].innerHTML = str[i];
				} else {
					switch( direction ) {
						case 'down' : 
							options.marqueeBox.childNodes[options.marqueeBox.childNodes.length - ( i + 1 )].innerHTML = str[i];
							nextLine[i] = options.marqueeBox.childNodes[options.marqueeBox.childNodes.length - ( i + 1 )];
							break;
						case 'up' :
							options.marqueeBox.childNodes[i].innerHTML = str[i];
							nextLine[i] = options.marqueeBox.childNodes[i];
							break;
					}
				}
			}
			appendNode( direction );
		}

		function appendNode( direction ) {
			for( var i = 0 ; i < options.count ; i++ ) {
				switch ( direction ) {
					case 'down':
						$( options.marqueeBox ).prepend( nextLine[i] );
						options.marqueeBox.scrollTop = options.height * options.count;
						break;
					case 'up':
						$( options.marqueeBox ).append( nextLine[i] );
						options.marqueeBox.scrollTop = 0;
						break;
					default:
						return ;
				}
			}
			
			clearInterval( options.interval[1] );
			options.interval[1] = setInterval( function() { scrollMarquee( direction ); } , 10 );
		}
					 		
		function scrollMarquee( direction ) {
			switch ( direction ) {
				case 'down':
					options.marqueeBox.scrollTop--;
					break;
				
				case 'up':
					options.marqueeBox.scrollTop++;
					break;
				default:
					return ;
			}
			
			if( options.marqueeBox.scrollTop % ( options.height * options.count ) == ( options.height * options.count ) ) {
				clearInterval( options.interval[1] );
			}
		}
		return $(this);
	};
} )( jQuery );
