Scroller = Class.create();

Scroller.prototype = {
	
	initialize: function (type,objs,interval,speed) {
		this.type = type;
		this.objs = objs;
		this.interval = interval;
		this.speed = speed;
		this.mouseWheelEvent = (document.all) ?"mousewheel" :"DOMMouseScroll";
		this.scrollingV = this.scrollingH = true;
		this.scrollVOld = this.scrollHOld = 0;
		this.intMoveV = this.intMoveH = null;
	},
	
	init: function () {
		
		if (this.type=="vertical"||this.type=="multi") {
			if (this.objs.container.offsetHeight>this.objs.mask.offsetHeight) {
				Event.observe(this.objs.scUp, "mouseover", this.moveUpDown.bind(this,-1));
				Event.observe(this.objs.scDn, "mouseover", this.moveUpDown.bind(this,1));
				Event.observe(this.objs.scUp, "mouseout", this.stop.bind(this));
				Event.observe(this.objs.scDn, "mouseout", this.stop.bind(this));
				Event.observe(this.objs.mask, this.mouseWheelEvent, this.mouseWheelVChecker.bindAsEventListener(this));
				this.setVerticalCursor();
			}
			else this.hideVerticalScrollElems();
		}
		if (this.type=="horizontal"||this.type=="multi") {
			if (this.objs.container.offsetWidth>this.objs.mask.offsetWidth) {
				Event.observe(this.objs.scLeft, "mouseover", this.moveLeftRight.bind(this,-1));
				Event.observe(this.objs.scRight, "mouseover", this.moveLeftRight.bind(this,1));
				Event.observe(this.objs.scLeft, "mouseout", this.stop.bind(this));
				Event.observe(this.objs.scRight, "mouseout", this.stop.bind(this));
				this.setHorizontalCursor();
			}
			else this.hideHorizontalScrollElems();
		}
		
	},
	
	moveUpDown: function (move) {
		this.cursorV.speedHCheck = 0;
		if (this.intMoveV==null) this.intMoveV = new PeriodicalExecuter(this.upDown.bind(this,move),this.interval/1000);
		else {
			this.intMoveV.callback = this.upDown.bind(this,move);
			this.intMoveV.registerCallback();
		}
	},
	
	moveLeftRight: function (move) {
		this.cursorH.speedVCheck = 0;
		if (this.intMoveH==null) this.intMoveH = new PeriodicalExecuter(this.leftRight.bind(this,move),this.interval/1000);
		else {
			this.intMoveH.callback = this.leftRight.bind(this,move);
			this.intMoveH.registerCallback();
		}
	},
	
	upDown: function (move) {
		this.objs.mask.scrollTop += this.speed*move;
		this.cursorV.speedHCheck = (this.cursorV.speedHCheck<1) ?this.cursorV.speedHCheck + this.cursorV.speed :0;
		if (this.cursorV.speedHCheck>=1) this.objs.cursorV.style.top = this.objs.cursorV.offsetTop + Math.round(this.cursorV.speedHCheck)*move + "px";
		if (this.objs.mask.scrollTop==this.scrollVOld) {
			this.stop();
			this.objs.cursorV.style.top = (move==-1) ?this.cursorV.startY + "px" :this.cursorV.endY + "px";
		}
		this.scrollVOld = this.objs.mask.scrollTop;
	},
	
	leftRight: function (move) {
		this.objs.mask.scrollLeft += this.speed*move;
		this.cursorH.speedVCheck = (this.cursorH.speedVCheck<1) ?this.cursorH.speedVCheck + this.cursorH.speed :0;
		if (this.cursorH.speedVCheck>=1) this.objs.cursorH.style.left = this.objs.cursorH.offsetLeft + Math.round(this.cursorH.speedVCheck)*move + "px";
		if (this.objs.mask.scrollLeft==this.scrollHOld) {
			this.stop();
			this.objs.cursorH.style.left = (move==-1) ?this.cursorH.startX + "px" :this.cursorH.endX + "px";
		}
		this.scrollHOld = this.objs.mask.scrollLeft;
	},
	
	hideVerticalScrollElems: function () {
		this.objs.scUp.style.visibility = this.objs.scDn.style.visibility = this.objs.cursorV.style.visibility = "hidden";
		this.scrollingV = false;
	},
	
	hideHorizontalScrollElems: function () {
		this.objs.scLeft.style.visibility = this.objs.scRight.style.visibility = this.objs.cursorH.style.visibility = "hidden";
		this.scrollingH = false;
	},
	
	stop: function () {
		if (this.type=="vertical"&&this.intMoveV!=null||this.type=="multi"&&this.intMoveV!=null) this.intMoveV.stop();
		if (this.type=="horizontal"&&this.intMoveH!=null||this.type=="multi"&&this.intMoveH!=null) this.intMoveH.stop();
	},
	
	reset: function () {
		if (this.scrollingV) {
			if (this.type=="vertical"||this.type=="multi") {
				this.objs.mask.scrollTop = 0;
				this.objs.cursorV.style.top = this.cursorV.startY;
			}
		}
		if (this.scrollingH) {
			if (this.type=="horizontal"||this.type=="multi") {
				this.objs.mask.scrollLeft = 0;
				this.objs.cursorH.style.left = this.cursorH.startX;
			}
		}
	},
	
	setVerticalCursor: function () {
		this.objs.cursorV.style.top = this.objs.cursorV.offsetTop + "px";
		this.cursorV = { 
						startY:this.objs.cursorV.offsetTop,
						endY:this.objs.cursorV.offsetTop + this.objs.cursorV.offsetHeight,
						coeffY:this.objs.mask.offsetHeight / this.objs.container.offsetHeight,
						speedHCheck:0
					};
		this.objs.cursorV.style.height = this.objs.cursorV.offsetHeight * this.cursorV.coeffY + "px";
		this.cursorV.endY -= this.objs.cursorV.offsetHeight;
		this.cursorV.speed = this.speed * this.cursorV.coeffY;
		this.cursorDragV = new Drag(this.objs.cursorV,false,this.objs.cursorV.offsetLeft,this.objs.cursorV.offsetLeft,this.cursorV.startY,this.cursorV.endY,this.moveToY.bind(this));
	},

	setHorizontalCursor: function () {
		this.objs.cursorH.style.left = this.objs.cursorH.offsetLeft + "px";
		this.cursorH = { 
						startX:this.objs.cursorH.offsetLeft,
						endX:this.objs.cursorH.offsetLeft + this.objs.cursorH.offsetWidth,
						coeffX:this.objs.mask.offsetWidth / this.objs.container.offsetWidth,
						speedVCheck:0
					};
		this.objs.cursorH.style.width = this.objs.cursorH.offsetWidth * this.cursorH.coeffX + "px";
		this.cursorH.endX -= this.objs.cursorH.offsetWidth;
		this.cursorH.speed = this.speed * this.cursorH.coeffX;
		this.cursorDragH = new Drag(this.objs.cursorH,false,this.cursorH.startX,this.cursorH.endX,this.objs.cursorH.offsetTop,this.objs.cursorH.offsetTop,this.moveToX.bind(this));
	},
	
	mouseWheelVChecker: function (e)  {
		this.upDown(Event.Wheel(e)*-1);
	},
	
	moveToX: function () {
		this.objs.mask.scrollLeft = Math.round(this.objs.container.offsetWidth*((this.objs.cursorH.offsetLeft-this.cursorH.startX)/this.cursorH.endX));
		if (this.objs.cursorH.offsetLeft==this.cursorH.endX) this.objs.mask.scrollLeft = this.objs.mask.scrollWidth;
	},
	
	moveToY: function () {
		this.objs.mask.scrollTop = Math.round(this.objs.container.offsetHeight*((this.objs.cursorV.offsetTop-this.cursorV.startY)/this.cursorV.endY));
		if (this.objs.cursorV.offsetTop==this.cursorV.endY) this.objs.mask.scrollTop = this.objs.mask.scrollHeight;
	},
	
	moveToAnchor: function (label) {
		if (this.scrollingV) {
			if (this.type=="vertical"||this.type=="multi") {
				this.objs.mask.scrollTop = $(label).offsetTop;
				var cursorToMove = $(label).offsetTop * this.cursorV.coeffY;
				this.objs.cursorV.style.top = (this.cursorV.startY + cursorToMove<this.cursorV.endY) ?this.cursorV.startY + cursorToMove + "px" :this.cursorV.endY + "px";
			}
		}
		if (this.scrollingH) {
			if (this.type=="horizontal"||this.type=="multi") {
				this.objs.mask.scrollLeft = $(label).offsetLeft;
				var cursorToMove = $(label).offsetLeft * this.cursorH.coeffX;
				this.objs.cursorH.style.left = (this.cursorH.startX + cursorToMove<this.cursorH.endX) ?this.cursorH.startX + cursorToMove + "px" :this.cursorH.endX + "px";
			}
		}
	}

}