/**
 * @class Scroller
 * @author hans <serg@orava.ru>
 * @version 1.0 24.12.2007
 * @requires jQuery 1.2.1+
 * @requires ScrollerSpeed
 */

var _aScrollers = [];
 

function Scroller (oContainer, oObj, eventType, oLeftWidget, oRightWidget, oTopWidget, oBottomWidget) {
	
	this._eventType = eventType ? eventType : 'mouseover';
	
	switch (this._eventType) {
		case 'mouseover':
			this._backEventType = 'mouseout';
		break;
		
		case 'click':
			this._backEventType = 'click';
		break;
		
		case 'mousedown':
			this._backEventType = 'mouseup'; 
		break;

		default:
			return false;
		break;
	}
	
	this.oContainer = $(oContainer);
	this.oObj = $(oObj);
	this.oLeftWidget = oLeftWidget ? $(oLeftWidget) : null;
	this.oRightWidget = oRightWidget ? $(oRightWidget) : null;
	this.oTopWidget = oTopWidget ? $(oTopWidget) : null;
	this.oBottomWidget = oBottomWidget ? $(oBottomWidget) : null;
	
	this._x = 0;
	this._y = 0;
	
	this.DIRECTION_LEFT = 0;
	this.DIRECTION_RIGHT = 1;
	this.DIRECTION_UP = 2;
	this.DIRECTION_DOWN = 3;
	
	this._speed = new ScrollerSpeed( this );
	
	/**
	 * 0 - left
	 * 1 - right
	 * 2 - up
	 * 3 - down
	 */
	this._direction = null;
	
	this._interval = 20;
	this.oInterval = null;
	
	this.iMaxLeft = 0;
	this.iMinLeft = this.oContainer.width() - this.oObj.width();
	this.iMaxTop = 0;
	this.iMinTop = this.oContainer.height() - this.oObj.height();
	
	this._index = _aScrollers.length;
	_aScrollers[_aScrollers.length] = this;
	
	this.init();
	
}

Scroller.prototype = {
	
	startAnimation : function ( dir ) {
		this._direction = dir;
		this.onAnimationStart();
	},
	
	stopAnimation : function (e) {
		this._direction = null;
		this.onAnimationEnd();
	},
	
	setX : function (x) {
		this.oObj.css('left', (this._x = x) + 'px');
	},
	
	setY : function (y) {
		this.oObj.css('top', (this._y = y) + 'px');
	},
	
	move : function () {
		var cX = this._speed.getX();
		var cY = this._speed.getY();
		
		if (cX > 0) {
			if ( this._x + cX > this.iMinLeft && this._x + cX < this.iMaxLeft ) {
				this.setX( this._x + cX );					
			} else {
				this.setX( this.iMaxLeft );
			}
		} else if (cX < 0) {
			if ( this._x + cX > this.iMinLeft && this._x + cX < this.iMaxLeft ) {
				this.setX( this._x + cX );					
			} else {
				this.setX( this.iMinLeft );
			}
		}
		if (cY > 0) {
			if ( this._y + cY < this.iMaxTop ) {
				this.setY( this._y + cY );					
			} else {
				this.setY( this.iMaxTop );
			}
		} else if (cY < 0) {
			if ( this._y + cY > this.iMinTop ) {
				this.setY( this._y + cY );					
			} else {
				this.setY( this.iMinTop );
			}
		}
//		document.title = this.iMinLeft + ' : ' + this._x + '(' + this._direction + '/' + cX + ')' + ' : ' + this.iMaxLeft;	
//		document.title = this.iMinTop + ' : ' + this._y + '(' + this._direction + '/' + cY + ')' + ' : ' + this.iMaxTop;	
//		document.title = this._x
		
	},
	
	doAnimation : function ( iIndex ) {
		
		var oObj = _aScrollers[iIndex];
		
		if (oObj._direction != null) {
			oObj._speed.increase( oObj._direction  );
		} else {
			oObj._speed.fade();
		}
			
		oObj.move();
		
//		document.title = oObj._speed.toString();
			
//		document.title = Math.random();
	},
	
	onAnimate : function () {
		
	},
	 
	onAnimationStart : function () {
//		document.title = this._direction;
	},
	
	onAnimationEnd : function () {
		checkRatesChooserArrows()
	},
	
	reactOnHover : function ( oObj ) {

	},
	
	reactOnHout : function ( oObj ) {
		
	},
	
	setInterval : function ( ) {
		window.setInterval('_aScrollers[' + this._index + '].doAnimation(' + this._index + ')', this._interval);
	},
	
	init : function () {
		
		if ( this.oObj.width() < this.oContainer.width() ) {
			if (this.oLeftWidget)
				this.oLeftWidget.css('display', 'none');
			if (this.oRightWidget)
				this.oRightWidget.css('display', 'none');
		} else {
			if (this.oLeftWidget) {
				this.oLeftWidget.bind( this._eventType, {oObj : this} , function (e) {
					e.data.oObj.startAnimation(e.data.oObj.DIRECTION_LEFT);
				});
				this.oLeftWidget.bind( this._backEventType, {oObj : this}, function (e) {
					e.data.oObj.stopAnimation();
				});
				this.oLeftWidget.bind( 'mouseover', {oObj : this}, function (e) {
					e.data.oObj.reactOnHover( e.data.oObj.oLeftWidget );
				});
				this.oLeftWidget.bind( 'mouseout', {oObj : this}, function (e) {
					e.data.oObj.reactOnHout( e.data.oObj.oLeftWidget );
				});
			}
			if (this.oRightWidget) {
				this.oRightWidget.bind( this._eventType, {oObj : this} , function (e) {
					e.data.oObj.startAnimation(e.data.oObj.DIRECTION_RIGHT);
				});
				this.oRightWidget.bind( this._backEventType, {oObj : this}, function (e) {
					e.data.oObj.stopAnimation();
				});
				this.oRightWidget.bind( 'mouseover', {oObj : this}, function (e) {
					e.data.oObj.reactOnHover( e.data.oObj.oRightWidget );
				});
				this.oRightWidget.bind( 'mouseout', {oObj : this}, function (e) {
					e.data.oObj.reactOnHout( e.data.oObj.oRightWidget );
				});
			}
		}
		
		if ( this.oObj.height() < this.oContainer.height() ) {
			if (this.oTopWidget)
				this.oTopWidget.css('display', 'none');
			if (this.oBottomWidget)
				this.oBottomWidget.css('display', 'none');
		} else {
			if (this.oTopWidget) {
				this.oTopWidget.bind( this._eventType, {oObj : this} , function (e) {
					e.data.oObj.startAnimation(e.data.oObj.DIRECTION_UP);
				});
				this.oTopWidget.bind( this._backEventType, {oObj : this}, function (e) {
					e.data.oObj.stopAnimation();
				});
				this.oTopWidget.bind( 'mouseover', {oObj : this}, function (e) {
					e.data.oObj.reactOnHover( e.data.oObj.oTopWidget );
				});
				this.oTopWidget.bind( 'mouseout', {oObj : this}, function (e) {
					e.data.oObj.reactOnHout( e.data.oObj.oTopWidget );
				});
			}
			if (this.oBottomWidget) {
				this.oBottomWidget.bind( this._eventType, {oObj : this} , function (e) {
					e.data.oObj.startAnimation(e.data.oObj.DIRECTION_DOWN);
				});
				this.oBottomWidget.bind( this._backEventType, {oObj : this}, function (e) {
					e.data.oObj.stopAnimation();
				});
				this.oBottomWidget.bind( 'mouseover', {oObj : this}, function (e) {
					e.data.oObj.reactOnHover( e.data.oObj.oBottomWidget );
				});
				this.oBottomWidget.bind( 'mouseout', {oObj : this}, function (e) {
				e.data.oObj.reactOnHout( e.data.oObj.oBottomWidget );
			});
		}
		}
		
		this.setInterval();
		
	}
	
	
}

/**
 * @class ScrollerSpeed
 * @author hans <serg@orava.ru>
 * @requires jQuery 1.2.1+
 * @version	1.0	24.12.2007
 */
function ScrollerSpeed ( oObj ) {
	this.oObject = oObj;
	this.left = 0;
	this.top = 0;
	
	this._coeff = 0.5;
	this._coeff2 = 7;
	this._sign = 1;
	this._fadingCoeff = 1.1;
	
	this._invert = -1;
}

ScrollerSpeed.prototype = {
	
	
	
	increase : function ( dir, val ) {
		switch (dir) {
			case this.oObject.DIRECTION_LEFT:
				this._sign = -1;
				if (val)
					this.left -= val;
				else 
					if (this.left != 0)
						this.left = this.increaseFunction( this.left );
					else
						this.left = -1;			
			break;
			
			case this.oObject.DIRECTION_RIGHT:
				this._sign = 1;
				if (val)
					this.left += val;
				else 
					if (this.left != 0)
						this.left = this.increaseFunction( this.left );
					else
						this.left = 1;			
			break;
			
			case this.oObject.DIRECTION_UP:
				this._sign = -1;
				if (val)
					this.top -= val;
				else 
					if (this.top != 0)
						this.top = this.increaseFunction( this.top );
					else
						this.top = -1;			
			break;

			case this.oObject.DIRECTION_DOWN:
				this._sign = 1;
				if (val)
					this.top += val;
				else 
					if (this.top != 0)
						this.top = this.increaseFunction( this.top );
					else
						this.top = 1;			
			break;
			
			default:
				return false;
			break;
		}
		
		
//		document.title = this.toString();
	},
	
	invert : function () {
		this._invert = this._invert == -1 ? 1 : -1;
	},
	
	increaseFunction : function ( iVal ) {
		return  this._invert * this._sign * this._coeff2 * Math.log( (Math.abs(iVal) + Math.E) * this._coeff ) ;
	},
		
	fade : function () {
		this.left = ( this.left / this._fadingCoeff );
		this.top  = ( this.top  / this._fadingCoeff );
	},
	
	toString : function () {
		return 'left: ' + this.left + '; top: ' + this.top;
	},
	
	getX : function () {
		return Math.round( this.left );	
	},
	
	getY : function () {
		return Math.round( this.top );
	}
	
}