var ScrollEx = Scroll.extend({
	constructor: function(scrollbarbg, scrollbar){
		this.scrollbarbg = scrollbarbg;
		this.scrollbar = scrollbar;
		this.init();
	}
	,prev: function(){
		this.ScrollTo(this.getNextPos(), 2);
	}
	,next: function(){
		this.ScrollTo(this.getNextPos(true), 2);
	}
	,getNextPos: function (rev){
		var scrollbarbg = this.scrollbarbg;
		var scrollbar = this.scrollbar;
		var spans = scrollbarbg.getElementsByTagName('span');
		for(var i=0, j=spans.length, span; i<j; i++){
			span = spans[rev ? i : j-1-i];
			if(rev && (this.rl(span) > this.rl(scrollbar)) ){
				return span.offsetLeft - .5 * (scrollbar.offsetWidth - span.offsetWidth);
			}else
			if(!rev && (span.offsetLeft < scrollbar.offsetLeft) ){
				return span.offsetLeft - .5 * (scrollbar.offsetWidth - span.offsetWidth);
			}
		}
		return rev ? this._nMax : 0;
	}
	// 动画移动到指定位置
	,ScrollTo: function(pos, type){
		switch(type){
			case 2:
				pos = this.l2p(pos);
		}
		if(this.fx)this.fx.stop();
		this.fx = new Fx.Cfn(function(now){
			if(now < this._nMin || now > this._nMax)
				this.fx.stop();
			this.parent(now);
		}, {duration:400, fps:50}, this);
		if(!window.ie){
			this.fx.options.duration = 1000;
			this.fx.options.transition = function(p){
				status = p;
				var dv = Math.pow(128, -p);
				var y = 1-dv + dv * (1-Math.cos(p * (2 * (1 || 1) + .5) * Math.PI));
				return y;
			};
		}
		this.fx.start(this._nPos, pos);

	}
	,rl: function (ele){
		return ele.offsetLeft + ele.offsetWidth;
	}
	
});

function Scroll(scrollbarbg, scrollbar){
	// Properties
	// true 为固定滚动条长度， false 为根据滚动范围自动计算
	this.barChangeless	= false;
	this.scrollbarbg = scrollbarbg;
	this.scrollbar = scrollbar;

	// Events
	// 滚动回调函数
	this.OnScroll		= function(nPos){};		
	this.OnScrollEnd	= function(nPos){};		

	// Methods
	this.ScrollTo = function(pos, type){
		switch(type){
			case 2:
				pos = this.l2p(pos);
		}
		pos = pos.limit(this._nMin, this._nMax);
		this.SetScrollInfo({fMask:4, nPos:pos});
		this.OnScroll.call(this, pos);
	};

	this.SetScrollInfo = function(si){
		if((si.fMask & 1) == 1){
			this._nMin = si.nMin;
			this._nMax = si.nMax;
			_nPage = si.nPage;
			if(!this.barChangeless)
				scrollbar.setStyle('width', scrollbarbg.offsetWidth * _nPage / (this._nMax - this._nMin) );
		}
		if((si.fMask & 4) == 4){
			this._nPos = si.nPos.limit(0, this._nMax);
			scrollbar.setStyle('left', (scrollbarbg.offsetWidth - scrollbar.offsetWidth) * (this._nPos - this._nMin) / (this._nMax - this._nMin) );
		}
		
	};

	this.init = function(){
		scrollbarbg = this.scrollbarbg;
		scrollbar = this.scrollbar;

		bd_mm = dMouseMove.bindWithEvent(this);
		bd_mu = dMouseUp.bindWithEvent(this);

		scrollbarbg.addEvent('mousedown', function(event){
			if(document.body.setCapture)document.body.setCapture();
			document.body.style.cursor = 'default';
			if('SPAN' == event.target.nodeName){
				this.ScrollTo(event.target.offsetLeft - .5 * (scrollbar.offsetWidth - event.target.offsetWidth), 2);// 跳转
			}else{
				var pOfst = scrollbarbg.getPosition();
				di.offset = {x:pOfst.x};
				if(event.page.x < pOfst.x + scrollbar.offsetLeft)
					this.ScrollTo(event.page.x - pOfst.x, 2);// 跳转
				else if(event.page.x > pOfst.x + scrollbar.offsetLeft + scrollbar.offsetWidth){
					this.ScrollTo(event.page.x - pOfst.x - scrollbar.offsetWidth, 2);// 跳转
					di.offset.x += scrollbar.offsetWidth;
				}else if(event.page.x >= pOfst.x + scrollbar.offsetLeft)
					di.offset.x = event.page.x - scrollbar.offsetLeft;

				event.preventDefault();
				document.addListener('mousemove', bd_mm);
			}
			document.addListener('mouseup', bd_mu);
		}.bindWithEvent(this));
	}

	// private
	// Fields
	var scrollbarbg;
	var scrollbar;
	var _nPage;
	this._nMin = this._nMax = this._nPos = 0;
	var di = {};
	var thisClass;
	var bd_mm;
	var bd_mu;
	// init
	//init();

	
	function dMouseMove(event){
		if(this.fx)this.fx.stop();
		this._nPos = this.l2p( (event.page.x - di.offset.x).limit(0, scrollbarbg.offsetWidth - scrollbar.offsetWidth) );
		this.SetScrollInfo({fMask:4, nPos:this._nPos});
		this.OnScroll.call(this, this._nPos);
	}
	
	function dMouseUp(){
		this.OnScrollEnd.call(this, this._nPos);

		if(document.releaseCapture)	document.releaseCapture();
		document.removeListener('mousemove', bd_mm);
		document.removeListener('mouseup', bd_mu);
	}
	
	this.l2p = function(left){
		return (this._nMax - this._nMin) * left / (scrollbarbg.offsetWidth - scrollbar.offsetWidth);
	}

}

