/* WHEEL // ROULETTE SOURI */
Object.extend(Event, {
	Wheel:function (event){
		var delta = 0;
		if (!event) event = window.event;
		if (event.wheelDelta) {
			delta = event.wheelDelta/120; 
			if (window.opera) delta = -delta;
		} else if (event.detail) { delta = -event.detail*2;	}
		return Math.round(delta);
	}
});

/* DRAG SCROLL */
var Drag = Class.create({
	
	initialize: function (target,xMin,xMax,yMin,yMax,onMoveFunction) {
		this.target = target;
		this.xMin = xMin;
		this.xMax = xMax;
		this.yMin = yMin;
		this.yMax = yMax;
		this.onMoveFunction = onMoveFunction;
		this.targetXMax = xMax-target.offsetWidth;
		this.targetYMax = yMax-target.offsetHeight;	
		this.draggable = false;
		this.targetDown = this.setDraggable.bind(this,true);
		this.targetUp = this.setDraggable.bind(this,false);
		this.docMouseMove = this.move.bindAsEventListener(this);
		this.mouseOldPos = null;
		Event.observe(target,"mousedown",this.targetDown);
		Event.observe(document,"mouseup",this.targetUp);
		Event.observe(document,"mousemove",this.docMouseMove);
	},
	
	setDraggable: function (draggable) {
		this.draggable = draggable;
		this.mouseOldPos = null;
	},
	
	move: function (e) {
		if (this.draggable) {
			
			var xMouse = Event.pointerX(e);
			var yMouse = Event.pointerY(e);
			
			if (this.mouseOldPos) {
				if (this.xMax>this.xMin) {
					var xNew = this.target.offsetLeft-(this.mouseOldPos.xMouse-xMouse);
					if (xNew<this.xMin) { xNew = this.xMin; }
					else if (xNew+this.target.offsetWidth>this.xMax) { xNew = this.targetXMax; }
					this.target.style.left = xNew+"px";
				}
				if (this.yMax>this.yMin) {
					var yNew = this.target.offsetTop-(this.mouseOldPos.yMouse-yMouse);
					if (yNew<this.yMin) { yNew = this.yMin; }
					else if (yNew+this.target.offsetHeight>this.yMax) { yNew = this.targetYMax; }	
					this.target.style.top = yNew+"px";
				}
				Event.SelectionClear();
				if (this.onMoveFunction) { this.onMoveFunction(); }
			}
			
			this.mouseOldPos = {xMouse:xMouse,yMouse:yMouse};
			
		}
	},
	
	reload: function (xMin,xMax,yMin,yMax) {
		this.xMin = xMin;
		this.xMax = xMax;
		this.yMin = yMin;
		this.yMax = yMax;
		this.targetXMax = xMax-this.target.offsetWidth;
		this.targetYMax = yMax-this.target.offsetHeight;
	},
	
	kill: function () {
		Event.stopObserving(target,"mousedown",this.targetDown);
		Event.stopObserving(document,"mouseup",this.targetUp);
		Event.stopObserving(document,"mousemove",this.docMouseMove);
	}

});

/* SELECTION CLEAR */
Object.extend(Event, {
	SelectionClear: function () {
		if (document.execCommand&&navigator.userAgent.indexOf("Firefox")==-1) document.execCommand("Unselect");
		else if (window.getSelection&&window.getSelection().removeAllRanges) window.getSelection&&window.getSelection().removeAllRanges();
	}
});

/* SCROLLER */
var Scroller = Class.create({
	
	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 = false;
		this._scrollVOld = this._scrollHOld = 0;
		this._intMoveV = this._intMoveH = null;
	},
	
	init: function () {
		if (this._type=="vertical"||this._type=="multi") {
			if (this._objs.mask.scrollHeight>this._objs.mask.offsetHeight) { this.viewScrollElems(this._type,"visible",true); }
			else { this.viewScrollElems(this._type,"hidden",false); }			
			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();			
		}
		if (this._type=="horizontal"||this._type=="multi") {
			if (this._objs.mask.scrollWidth>this._objs.mask.offsetWidth) { this.viewScrollElems(this._type,"visible",true); }
			else { this.viewScrollElems(this._type,"hidden",false); }			
			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();
		}		
	},
	
	_moveUpDown: function (move) {
		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) {
		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._setUpDownCursor();
		if (this._objs.mask.scrollTop==this._scrollVOld) { this.stop(); }
		this._scrollVOld = this._objs.mask.scrollTop;
	},
	
	_leftRight: function (move) {
		this._objs.mask.scrollLeft += this._speed*move;
		this._setLeftRightCursor();
		if (this._objs.mask.scrollLeft==this._scrollHOld) { this.stop(); }
		this._scrollHOld = this._objs.mask.scrollLeft;
	},
	
	_setUpDownCursor: function () {
		this._objs.cursorV.style.top = this.cursorV.startY+this._objs.mask.scrollTop*this.cursorV.coeffY+"px";
	},
	
	_setLeftRightCursor: function () {
		this._objs.cursorH.style.left = this.cursorH.startX+this._objs.mask.scrollLeft*this.cursorH.coeffX+"px";
	},
	
	viewScrollElems: function (type,visibility,scrolling) {
		if (type=="vertical") {
			this.showScrollElems(type,visibility);
			if (scrolling!="noChange") { this._scrollingV = scrolling; }
		}
		else if (type=="horizontal") {
			this.showScrollElems(type,visibility);
			if (scrolling!="noChange") { this._scrollingH = scrolling; }
		}
	},
	
	showScrollElems: function (type,visibility) {
		if (type=="vertical") {
			this._objs.scrollbar.style.visibility = this._objs.scUp.style.visibility = this._objs.scDn.style.visibility = this._objs.cursorV.style.visibility = visibility;
		}
		else if (type=="horizontal") {
			this._objs.scrollbar.style.visibility = this._objs.scLeft.style.visibility = this._objs.scRight.style.visibility = this._objs.cursorH.style.visibility = visibility;
		}
	},
	
	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(); }
	},
	
	_setVerticalCursor: function () {		
		if (!this.cursorV) {
			this.cursorV = {
				startY:this._objs.cursorV.offsetTop,
				initHeight:this._objs.cursorV.offsetHeight,
				diff:this._objs.mask.offsetHeight-this._objs.cursorV.offsetHeight,
				endY:this._objs.cursorV.offsetTop+this._objs.cursorV.offsetHeight
			};
		}
		else {
			this._objs.cursorV.style.top = this.cursorV.startY+"px";
			this._objs.cursorV.style.height = this.cursorV.initHeight+"px";
		}
		
		this.cursorV.coeffY = (this._objs.mask.offsetHeight-this.cursorV.diff)/(this._objs.mask.scrollHeight-this.cursorV.diff);
		
		if(this.cursorV.coeffY<0) this.cursorV.coeffY = 0;
		this._objs.cursorV.style.height = this._objs.cursorV.offsetHeight*this.cursorV.coeffY+"px";
		if (!this.myDragV) {
			this.myDragV = new Drag(this._objs.cursorV,this._objs.cursorV.offsetLeft,this._objs.cursorV.offsetLeft,this.cursorV.startY,this.cursorV.endY,this.moveToY.bind(this));	
		}
		else {
			this.myDragV.reload(this._objs.cursorV.offsetLeft,this._objs.cursorV.offsetLeft,this.cursorV.startY,this.cursorV.endY);
		}
		this._setUpDownCursor();
		this.moveToY();
	},

	_setHorizontalCursor: function () {		
		if (!this.cursorH) {
			this.cursorH = {
				startX:this._objs.cursorV.offsetLeft,
				initWidth:this._objs.cursorV.offsetWidth,
				diff:this._objs.mask.offsetWidth-this._objs.cursorV.offsetWidth
			};
		}
		else {
			this._objs.cursorH.style.left = this.cursorH.startX+"px";
			this._objs.cursorH.style.width = this.cursorH.initWidth+"px";
		}		
		this.cursorH.coeffX = (this._objs.mask.offsetWidth-this.cursorH.diff)/(this._objs.mask.scrollWidth-this.cursorH.diff);
		this._objs.cursorH.style.width = this._objs.cursorH.offsetWidth*this.cursorV.coeffX+"px";
		this.cursorH.endX = this.cursorH.startX+this.cursorV.initWidth;
		if (!this.myDragH) {
			this.myDragH = new Drag(this._objs.cursorH,this.cursorH.startX,this.cursorH.endX,this._objs.cursorV.offsetTop,this._objs.cursorV.offsetTop,this.moveToX.bind(this));	
		}
		else {
			this.myDragH.reload(this.cursorH.startX,this.cursorH.endX,this._objs.cursorV.offsetTop,this._objs.cursorV.offsetTop);
		}
		this._setLeftRightCursor();
		this.moveToX();
	},
	
	_mouseWheelVChecker: function (e)  {
		if (this._scrollingV) { this._upDown(Event.Wheel(e)*-1); }
	},
	
	moveToY: function () {
		this._objs.mask.scrollTop = (parseInt(this._objs.cursorV.style.top)-this.cursorV.startY)/this.cursorV.coeffY;
	},
	
	moveToX: function () {
		this._objs.mask.scrollLeft = (parseInt(this._objs.cursorV.style.left)-this.cursorV.startX)/this.cursorV.coeffX;
	},
	
	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";
			}
		}
	},
	
	reload: function () {
		if (this._type=="vertical"||this._type=="multi") {
			if (this._objs.mask.scrollHeight>this._objs.mask.offsetHeight) {
				this._fixFirefox();
				this._setVerticalCursor();
				this.viewScrollElems(this._type,"visible",true);
			}
			else { this.viewScrollElems(this._type,"hidden",false); }
		}
		if (this._type=="horizontal"||this._type=="multi") {
			if (this._objs.mask.scrollWidth>this._objs.mask.offsetWidth) {
				this._setHorizontalCursor();
				this.viewScrollElems(this._type,"visible",true);
			}
			else { this.viewScrollElems(this._type,"hidden",false); }
		}		
	},
	
	_fixFirefox: function () {
		var d = document.createElement("b");
		this._objs.mask.appendChild(d);
	}
	
});

