NG.Scroller = function() { }
NG.Scroller.prototype.Enable = function(content, bar, nodule) {
	if (content.offsetHeight < content.scrollHeight) {
		bar.style.display = 'block';
		nodule.style.display = 'block';
	}
	this.scrolling = false;
	this.content = content;
	this.content.style.overflow = 'hidden';
	this.bar = bar;
	this.nodule = nodule;
	nodule.scroller = this;
	bar.scroller = this;
	if (NG.getElementsByClassName(bar, 'arrow-up').length > 0)    nodule.style.marginTop    = NG.getElementsByClassName(bar, 'arrow-up')[0].offsetHeight + 'px';
	if (NG.getElementsByClassName(bar, 'arrow-down').length > 0)  nodule.style.marginBottom = NG.getElementsByClassName(bar, 'arrow-down')[0].offsetHeight + 'px';
	if (NG.getElementsByClassName(bar, 'arrow-left').length > 0)  nodule.style.marginLeft   = NG.getElementsByClassName(bar, 'arrow-left')[0].offsetHeight + 'px';
	if (NG.getElementsByClassName(bar, 'arrow-right').length > 0) nodule.style.marginRight  = NG.getElementsByClassName(bar, 'arrow-right')[0].offsetHeight + 'px';
	content.scroller = this;
	if (document.NGDefaultScroller == null) {
		document.NGDefaultScroller = this;
	}

	var tmp = this;
	NG.addEventListener(content, 'mousewheel', function(e) { tmp.Scroll('wheel', e); NG.stopPropagation(); });
	NG.addEventListener(bar,     'click',      function(e) { tmp.Scroll('click', e); NG.stopPropagation(); });
	NG.addEventListener(nodule,  'mousedown',  function(e) { tmp.Start(e); });
	if (document.NGDefaultScroller == this) {
		NG.addEventListener(document, 'mousewheel', function(e) { tmp.Scroll('wheel', e); NG.stopPropagation(); });
	}
	this.moveHandler = function(e) { tmp.Scroll('move', e); }
	this.stopHandler = function(e) { tmp.Stop(e); }

	this.stretchers = new Array;
	var images = this.content.getElementsByTagName('img');
	for (var i = 0; i < images.length; i++) {
		if (NG.hasClass(images[i], 'scroll-stretch')) {
			images[i].originalHeight = images[i].offsetHeight;
			images[i].originalWidth = images[i].offsetWidth;
			this.stretchers[this.stretchers.length] = images[i];
		}
	}
	if (this.content.scrollHeight > this.content.clientHeight) {
		this.bar.style.display = 'block';
	}
}

NG.Scroller.prototype.Scroll = function(type, event) {
	switch (type) {
		case 'wheel':
			var data = event.detail ? event.detail : event.wheelDelta / -40;
			this.Scroll('delta', {x:data * 2, y:data * 2});
			break;
		case 'click':
			this.Scroll('absolute', {x:event.clientX - (this.nodule.marginTop ? this.nodule.marginTop : 0), y:event.clientY - (this.nodule.marginLeft ? this.nodule.marginLeft : 0)});
			break;
		case 'move':
			if (this.scrolling) this.Scroll('absolute', {x:event.clientX - (this.nodule.marginTop ? this.nodule.marginTop : 0), y:event.clientY - (this.nodule.marginLeft ? this.nodule.marginLeft : 0)});
			break;
		case 'top':
			this.Scroll('to', {x:0, y:0});
			break;
		case 'bottom':
			if (NG.hasClass(scrolling.bar, 'horizontal')) {
				this.Scroll('to', {x:0, y:this.bar.offsetWidth});
			} else {
				this.Scroll('to', {x:0, y:this.bar.offsetHeight});
			}
			break;
		case 'absolute':
			var wscroll = this.GetOffset();
			event.y = event.y - NG.getPagePos(this.bar).y + wscroll.y;
			event.x = event.x - NG.getPagePos(this.bar).x + wscroll.x;
			this.Scroll('to', event);
			break;
		case 'delta':
			var point = {x:(this.nodule.style.left ? parseInt(this.nodule.style.left.replace(/px/,'')) : 0) + event.x, y:(this.nodule.style.top ? parseInt(this.nodule.style.top.replace(/px/,'')) : 0) + event.y};
			this.Scroll('to', point);
			break;
		default:
		case 'to':
			var x = event.x; var y = event.y;
			if (NG.hasClass(this.bar, 'horizontal')) {
				if (x > this.bar.offsetWidth - this.nodule.offsetWidth - this.GetNoduleMargins()) {
					this.nodule.style.left = this.bar.offsetLeft + this.bar.offsetWidth - this.nodule.offsetWidth - this.GetNoduleMargins() + 'px';
				} else if (x  < 0) {
					this.nodule.style.left = this.bar.offsetLeft + 'px';
				} else {
					this.nodule.style.left = this.bar.offsetLeft + x + 'px';
				}
				this.content.scrollTop = (this.content.scrollHeight - this.content.offsetHeight) * this.PointToPercentage({x:x,y:0}).x;
				var position = (x / (this.bar.offsetWidth - this.nodule.GetNoduleMargins() - this.nodule.offsetWidth));
				if (position < 0) position = 0;
				if (position > 100) position = 100;
				if (position < 1) {
					for (var i = 0; i < this.stretchers.length; i++) {
						var stretch = this.stretchers[i];
						stretch.style.width = (stretch.originalWidth + this.content.scrollTop) + 'px';
					}
				}
			} else {
				if (y > this.bar.offsetHeight - this.nodule.offsetHeight - this.GetNoduleMargins()) {
					this.nodule.style.top = this.bar.offsetHeight - this.nodule.offsetHeight - this.GetNoduleMargins() + 'px';
				} else if (y  < 0) {
					this.nodule.style.top = 0 + 'px';
				} else {
					this.nodule.style.top = y + 'px';
				}
				this.content.scrollTop = (this.content.scrollHeight - this.content.offsetHeight) * this.PointToPercentage({x:0,y:y}).y;
				var position = (y / (this.bar.offsetHeight - this.GetNoduleMargins() - this.nodule.offsetHeight));
				if (position < 0) position = 0;
				if (position > 1) position = 1;
				if (position < 1) {
					if (this.stretchers.length > 0) {
						this.stretchers[0].style.height = (this.stretchers[0].originalHeight + this.content.scrollTop) + 'px';
					}
				}
			}
			break;
	}
}
NG.Scroller.prototype.GetNoduleMargins = function() {
	if (NG.hasClass(this.bar, 'horizontal')) {
		return (this.nodule.style.marginLeft ? parseInt(this.nodule.style.marginLeft.replace(/px/,'')) : 0) + (this.nodule.style.marginRight ? parseInt(this.nodule.style.marginRight.replace(/px/,'')) : 0);
	} else {
		return (this.nodule.style.marginTop ? parseInt(this.nodule.style.marginTop.replace(/px/,'')) : 0) + (this.nodule.style.marginBottom ? parseInt(this.nodule.style.marginBottom.replace(/px/,'')) : 0);
	}
}

NG.Scroller.prototype.GetOffset = function() {
	var point = new Object;

	point.x = 0; point.y = 0;
	if( document.documentElement && (document.documentElement.scrollTop || document.documentElement.scrollLeft)) {
		point.x = document.documentElement.scrollLeft;
		point.y = document.documentElement.scrollTop;
	}
	else if( document.body && (document.body.scrollTop || document.body.scrollLeft)) {
		point.x = document.body.scrollLeft;
		point.y = document.body.scrollTop;
	}
	else if(window.pageYOffset || window.pageXOffset) {
		point.x = window.pageXOffset;
		point.y = window.pageYOffset;
	}
	else if(window.scrollX || window.scrollY) {
		point.x = window.scrollX;
		point.y = window.scrollY;
	}

	return point;
}

NG.Scroller.prototype.Start = function(event) {
	this.scrolling = true;
	NG.addEventListener(document, 'mouseup',   this.stopHandler);
	NG.addEventListener(document, 'mousemove', this.moveHandler);
}

NG.Scroller.prototype.Stop = function(event)  {
	NG.removeEventListener(document, 'mouseup',   this.stopHandler);
	NG.removeEventListener(document, 'mousemove', this.moveHandler);
	this.scrolling = false;
}

NG.Scroller.prototype.PointToPercentage = function(point) {
	point.x = (point.x / (this.bar.offsetWidth - this.nodule.offsetWidth - (NG.hasClass(this.bar, 'horizontal') ? this.GetNoduleMargins() : 0)));
	point.y = (point.y / (this.bar.offsetHeight - this.nodule.offsetHeight - (!NG.hasClass(this.bar, 'horizontal') ? this.GetNoduleMargins() : 0)));
	if (point.x < 0) point.x = 0;
	if (point.y < 0) point.y = 0;
	if (point.x > 100) point.x = 100;
	if (point.y > 100) point.y = 100;

	return point;
}
