﻿$.fn.extend({
	setChildRepeatX : function(){
		return this.each(function(){
			var $this = $(this), widthSum = 0, outerWidth;
			$this.children().pos('abs').each(function(i){
				outerWidth = $(this).outerWidth();
				$(this).css({left:widthSum});
				widthSum += outerWidth + (outerWidth-$(this).width())*2;
				$(this).width(outerWidth);
			});
			$this.data({repeatWidth:widthSum}).width(widthSum);
		});
	},
	
	setChildRepeatY : function(){
		return this.each(function(){
			var $this = $(this), thisHeight, heightSum = 0;
			$this.children().pos('abs').each(function(){
				heightSum += $(this).css({top:heightSum+'px'}).height();
				$(this).height(thisHeight);
			});
			$this.data({repeatHeight:heightSum}).height(heightSum);
		});
	},
	
	clearMarqueeTimer : function(setting){
		return this.each(function(){
			setting = setting || $(this).data('marqueeSetting');
			if (isObject(setting)) {
				setting.timer && clearInterval(setting.timer);
				setting.timer = '';
			}
		});
	},
	
	marquee : function(option){
		return this.each(function(){
			var marqueeSetting = $(this).data('marqueeSetting'),
				setting = $.extend(marqueeSetting || {
					direction   : 'left',         //滚动的方向
					speed       : 2,              //滚动的速度
					time        : 70,             //滚动的时间
					wrap        : false,          //是否自动包裹,如文本该项就要为true
					loop        : true,           //是否循环滚动
					run         : true,           //是否开始滚动,为false时停止滚动
					animate     : false,          //是否以动画的形式滚动
					animateTime : 'slow'          //以动画形式滚动的时间
				},option || {}),
				$this   = $(this);
			if (setting.direction == 'bottom') {
				setting.coefficient  = 1 ;
				setting.cssDirection = 'top';
			} else if (setting.direction == 'right') {
				setting.coefficient  = 1 ;
				setting.cssDirection = 'left';
			} else {
				setting.coefficient  = -1;
				setting.cssDirection = setting.direction;
			}
			
			if (!$this.data('marqueeSetting')) {
				var content      = $this.children();
				$.extend(setting,{
					thisWidth  : $this.width(),
					thisHeight : $this.height()
				});
				if (!setting.thisWidth || !setting.thisHeight) return;
				$this.css({width:setting.width||setting.thisWidth,height:setting.height||setting.thisHeight});
				$this.data('marqueeSetting', setting).css({overflow:'hidden'}).pos();
				if (!content.is('[marqueeWrap]')) {
					if (!content.length && $this.html().trim()) {
						content = $this.wrapInner('<div/>').wrapInner('<div/>').children();
					} else if (content.length > 1) {
						content = $this.wrapInner('<div/>').children();
					}
					content.attr('marqueeWrap',1).pos('abs');
					var contentChild  = content.children(),
						twoThisHeight = setting.thisHeight * 2,
						twoThisWidth  = setting.thisWidth * 2;
						
					if (setting.direction == 'left' || setting.direction == 'right') {
						if (!content.width()) return;
						content.css({height:setting.thisHeight});
						setting.onceContentWidth = content.setChildRepeatX().data('repeatWidth');
						if (!setting.loop) {
							setting.leftInitPosition  =  setting.thisWidth;
							setting.leftPosition      = -setting.onceContentWidth;
							setting.rightInitPosition = -setting.onceContentWidth;
							setting.rightPosition     =  setting.thisWidth;
						} else {
							do {
								contentChild.clone(true).appendTo(content);
							}while(content.setChildRepeatX().data('repeatWidth') < twoThisWidth);
							setting.rightInitPosition = -content.width()+setting.thisWidth;
							setting.rightPosition     = setting.rightInitPosition+setting.onceContentWidth;
							setting.leftInitPosition  = 0;
							setting.leftPosition      = -setting.onceContentWidth;
						}
						
					} else {
						if (!content.height()) return;
						content.css({width:setting.thisWidth});
						setting.onceContentHeight = content.setChildRepeatY().data('repeatHeight');
						if (!setting.loop) {
							setting.topInitPosition    =  setting.thisHeight;
							setting.topPosition        = -setting.onceContentHeight;
							setting.bottomInitPosition = -setting.onceContentHeight;
							setting.bottomPosition     =  setting.thisHeight;
						} else {
							do {
								contentChild.clone(true).appendTo(content);
							}while(content.setChildRepeatY().data('repeatHeight') < twoThisHeight);
							setting.topInitPosition = 0;
							setting.topPosition     = -setting.onceContentHeight;
							setting.bottomInitPosition = -content.height()+setting.thisHeight;
							setting.bottomPosition  = setting.bottomInitPosition+setting.onceContentHeight;
						}
					}
					content.css(setting.cssDirection,setting[setting.direction+'InitPosition']+'px');
					$this.hover(function(){$this.clearMarqueeTimer(setting);},function(){
						$this.clearMarqueeTimer(setting);
						if (setting.run) {
							setting.timer = setInterval(function(){marqueeRunTime()},setting.time);
						}
					})
				}
				setting.left = strToInt(content.css('left'));
				setting.top  = strToInt(content.css('top'));
				function marqueeRunTime(){
					setting[setting.cssDirection] = setting[setting.cssDirection]+setting.speed*setting.coefficient;
					setting[setting.cssDirection]*setting.coefficient >= setting[setting.direction+'Position']*setting.coefficient && 
						(setting[setting.cssDirection] = setting.loop ? 
							setting[setting.direction+'InitPosition']+setting[setting.cssDirection]-setting[setting.direction+'Position'] :
							setting[setting.direction+'InitPosition']
						);
					setting.animate && content.animate({left:setting.left,top:setting.top},setting.animateTime) || content.css({left:setting.left,top:setting.top});
				}
			}
	
			$this.clearMarqueeTimer(setting).mouseout();
		});
	}
});
