﻿$.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);
						} else if(setting.virtual){
							delete setting.virtual;
							if (content.is(':animated')) return;
							check();
							marqueeRunTime();
						}
						
					})
				}
				setting.left = strToInt(content.css('left'));
				setting.top  = strToInt(content.css('top'));
				
				function check(){
					if(setting[setting.cssDirection]*setting.coefficient >= setting[setting.direction+'Position']*setting.coefficient) {
						if (setting.loop) {
							setting[setting.cssDirection] = setting[setting.direction+'InitPosition']+setting[setting.cssDirection]-setting[setting.direction+'Position'];
						} else {
							setting[setting.cssDirection] = setting[setting.direction+'InitPosition'];
						}
						content.css({left:setting.left, top:setting.top});
					}
				}

				function marqueeRunTime(){
					setting[setting.cssDirection] = setting[setting.cssDirection]+setting.speed*setting.coefficient;
					if (setting.animate) {
						content.stop().animate({left:setting.left, top:setting.top}, setting.animateTime, function(){
							check();
						});
					} else {
						content.css({left:setting.left, top:setting.top}) && check();
					}
				}
			}

			$this.clearMarqueeTimer(setting).mouseout();
		});
	}
});
