/**
 * scroll plugin
 * @author 王超
 * @desc 循环滚动内容，最外层最好用 div, 且必须赋予 width 和 overflow:hidden 属性
 * @version 1.0
 * @example
 *
 * @license free
 * @site http://www.chinaido.com
 *
 */

(function($) {
	$.fn.scroll = function (settings) {
		return this.each(function() {
			settings = $.extend({
				type: 'horizontal',   // h, horizontal, v, vertical
				direction: 'left',   // left, right, up, down
				step: 1,   // 每次滚动的距离(像素)
				interval: 50,   // 毫秒
				stopTimeAtStart: 3000,   // 初始化完毕后暂停指定时间后再滚动
				mouseoverStop: true,   // 鼠标悬浮时暂停_
				stopStep: 0,   // 每滚动指定像素暂停_
				stopTime: 3000,   // 暂停时间(毫秒)
				leftTriggerId: '',
				upTriggerId: '',
				rightTriggerId: '',
				downTriggerId: '',
				fasterSettings: null
			}, settings);

			var originalSettings = {
				step: settings.step,
				interval: settings.interval,
				stopStep: settings.stopStep,
				stopTime: settings.stopTime
			};

			function _Start() {
				if (timer) clearTimeout(timer);
				if (!settings.mouseoverStop || !mouseovering) {
					if (stopping) stopping = false;
					var step = settings.step;
					// 水平滚动
					if (settings.type == 'h' || settings.type == 'horizontal') {
						var tmp = outerContainer.scrollLeft();
						if (settings.direction == 'left') {
							while (tmp >= scrollWidth) {
								tmp -= scrollWidth;
								outerContainer.scrollLeft(tmp);
							}
							if (settings.stopStep > 0) {
								distance += step;
								if (distance >= settings.stopStep) {
									step -= (distance - settings.stopStep);
									distance = 0;
									stopping = true;
								} else if (tmp + step >= scrollWidth) {
									step = scrollWidth - tmp;
									distance = 0;
									stopping = true;
								}
							}
							outerContainer.scrollLeft(tmp + step);

						} else if (settings.direction == 'right') {
							while (tmp <= scrollWidth) {
								tmp += scrollWidth;
								outerContainer.scrollLeft(tmp);
							}
							if (settings.stopStep > 0) {
								distance += step;
								if (distance >= settings.stopStep) {
									step -= (distance - settings.stopStep);
									distance = 0;
									stopping = true;
								} else if (tmp - step <= scrollWidth) {
									step = tmp - scrollWidth;
									distance = 0;
									stopping = true;
								}
							}
							outerContainer.scrollLeft(tmp - step);
						}

					// 垂直滚动
					} else if (settings.type == 'v' || settings.type == 'vertical') {
						var tmp = outerContainer.scrollTop();
						if (settings.direction == 'up') {
							while (tmp >= scrollHeight) {
								tmp -= scrollHeight;
								outerContainer.scrollTop(tmp);
							}
							if (settings.stopStep > 0) {
								distance += step;
								if (distance >= settings.stopStep) {
									step -= (distance - settings.stopStep);
									distance = 0;
									stopping = true;
								} else if (tmp + step >= scrollHeight) {
									step = scrollHeight - tmp;
									distance = 0;
									stopping = true;
								}
							}
							outerContainer.scrollTop(tmp + step);

						} else if (settings.direction == 'down') {
							while (tmp <= scrollHeight) {
								tmp += scrollHeight;
								outerContainer.scrollTop(tmp);
							}
							if (settings.stopStep > 0) {
								distance += step;
								if (distance >= settings.stopStep) {
									step -= (distance - settings.stopStep);
									distance = 0;
									stopping = true;
								} else if (tmp - step <= scrollHeight) {
									step = tmp - scrollHeight;
									distance = 0;
									stopping = true;
								}
							}
							outerContainer.scrollTop(tmp - step);
						}

					} else {
						return;
					}
				}
				timer = setTimeout(_Start, (stopping ? settings.stopTime : settings.interval));
			}

			var me = $(this);
			var html = me.html();
			var width  = me.width();
			var height = me.height();
			var scrollWidth  = me.attr('scrollWidth');
			var scrollHeight = me.attr('scrollHeight');

			var timer;
			var mouseovering = false;   // 鼠标当前是否悬停
			var distance = 0;   // 连续移动的距离_
			var stopping = false;   // 是否处于暂停滚动状态

			var outerContainer = $('<div style="overflow:hidden;white-space:nowrap;"></div>');
			if (settings.type == 'h' || settings.type == 'horizontal') {
				if (width == 0) {
					alert('请指定滚动区域的宽度。');
					return;
				} else {
					outerContainer.width(width);
				}
			} else if (settings.type == 'v' || settings.type == 'vertical') {
				if (height == 0) {
					alert('请指定滚动区域的高度。');
					return;
				} else {
					outerContainer.height(height);
				}
			} else
				return;

			// 添加鼠标悬浮事件
			if (settings.mouseoverStop) {
				outerContainer
					.mouseover(function(){mouseovering = true;})
					.mouseout(function(){mouseovering = false;});
			}

			var innerContainer = $('<table cellspacing="0" cellpadding="0" style="border:none;white-space:normal;"></table>');
			if (settings.type == 'h' || settings.type == 'horizontal')
				innerContainer.width(scrollWidth * 3).height(scrollHeight).append($('<tr><td></td><td></td><td></td></tr>'));
			else if (settings.type == 'v' || settings.type == 'vertical')
				innerContainer.width(scrollWidth).height(scrollHeight * 3).append($('<tr><td></td></tr><tr><td></td></tr><tr><td></td></tr>'));
			else
				return;

			$('td', innerContainer).css('border', 'none').width(scrollWidth).height(scrollHeight).html(html);
			me.empty().append(outerContainer.append(innerContainer));

			if (settings.leftTriggerId) {
				$('#' + settings.leftTriggerId).mousedown(function(){
					if (settings.stopStep <= 0) {
						settings.direction = 'left';
						if (settings.fasterSettings) $.extend(settings, settings.fasterSettings);
					} else if (stopping) {
						settings.direction = 'left';
						if (settings.fasterSettings) $.extend(settings, settings.fasterSettings);
						_Start();
					}
				}).mouseup(function(){
					if (settings.stopStep <= 0) {
						settings.direction = 'left';
						if (settings.fasterSettings) $.extend(settings, originalSettings);
					} else {
						if (stopping) settings.direction = 'left';
						if (settings.fasterSettings) $.extend(settings, settings.fasterSettings);
						_Start();
					}
				});
			}
			if (settings.rightTriggerId) {
				$('#' + settings.rightTriggerId).mousedown(function(){
					if (settings.stopStep <= 0) {
						settings.direction = 'right';
						if (settings.fasterSettings) $.extend(settings, settings.fasterSettings);
					} else if (stopping) {
						settings.direction = 'right';
						if (settings.fasterSettings) $.extend(settings, settings.fasterSettings);
						_Start();
					}
				}).mouseup(function(){
					if (settings.stopStep <= 0) {
						settings.direction = 'right';
						if (settings.fasterSettings) $.extend(settings, originalSettings);
					} else {
						if (stopping) settings.direction = 'right';
						if (settings.fasterSettings) $.extend(settings, settings.fasterSettings);
						_Start();
					}
				});
			}
			if (settings.upTriggerId) {
				$('#' + settings.upTriggerId).mousedown(function(){
					if (settings.stopStep <= 0) {
						settings.direction = 'up';
					} else if (stopping) {
						settings.direction = 'up';
						_Start();
					}
				}).mouseup(function(){
					if (settings.stopStep <= 0) {
						settings.direction = 'up';
						if (settings.fasterSettings) $.extend(settings, originalSettings);
					} else {
						if (stopping) settings.direction = 'up';
						if (settings.fasterSettings) $.extend(settings, settings.fasterSettings);
						_Start();
					}
				});
			}
			if (settings.downTriggerId) {
				$('#' + settings.downTriggerId).mousedown(function(){
					if (settings.stopStep <= 0) {
						settings.direction = 'down';
					} else if (stopping) {
						settings.direction = 'down';
						_Start();
					}
				}).mouseup(function(){
					if (settings.stopStep <= 0) {
						settings.direction = 'down';
						if (settings.fasterSettings) $.extend(settings, originalSettings);
					} else {
						if (stopping) settings.direction = 'down';
						if (settings.fasterSettings) $.extend(settings, settings.fasterSettings);
						_Start();
					}
				});
			}

			if (settings.stopTimeAtStart) {
				timer = setTimeout(_Start, settings.stopTimeAtStart);
			} else {
				_Start();
			}

		});
	};
})(jQuery);
