ScrollObj = function(currScrollParams)
{
	this.deltaChange = currScrollParams.deltaChange || 6;
	this.deltaScrollChange = currScrollParams.deltaChange || 65;
	this.cannotWheel = (currScrollParams.cannotWheel) ? true : false;
	this.isVertical = (currScrollParams.isHorizontal) ? false : true;
	this.isNotNumeric = (currScrollParams.isNumeric) ? false : true;
	this.isVariableScroll = (currScrollParams.isVariableScroll) ? true : false;

	this.sliderLine = $("#" + currScrollParams.sliderLine);
	this.arrowUpLeft = $("#" + currScrollParams.arrowUpLeft);
	this.arrowDownRight = $("#" + currScrollParams.arrowDownRight);
	this.dragSlider = $("#" + currScrollParams.dragSlider);
	this.outerElement = $("#" + currScrollParams.outerElement);
	if (this.isNotNumeric) this.innerElement = $("#" + currScrollParams.innerElement);
	this.currCopy = (this.isNotNumeric) ? currScrollParams.innerElement + "Object" : currScrollParams.outerElement + "Object";
	this.currSliderPos = (this.isVertical) ? parseInt(this.dragSlider.css("top")) : parseInt(this.dragSlider.css("left"));
	eval(this.currCopy + "=this");
	if (this.isNotNumeric)
	{
		this.innerElementTopLeft = (this.isVertical) ? parseInt(this.innerElement.css("top")) : parseInt(this.innerElement.parent().css("left"));
		this.innerElementTopLeft = (isNaN(this.innerElementTopLeft)) ? 0 : this.innerElementTopLeft;
	}
	else
	{
		this.maxValue = currScrollParams.maxValue || 100;
		this.minValue = currScrollParams.minValue || 0;
		this.currValue = currScrollParams.startValue || parseInt(this.outerElement.text()) || this.minValue;
		this.currMask = currScrollParams.currMask || "";
	}
	this.scrollTimer = null;
	this.makeUpdate();
	var currObj = this;
	this.dragSlider.click(function(){return false;}).mousedown(function(currEvent){currObj.startDrag(currEvent); return false;});
	this.arrowUpLeft.click(function(){return false;}).mousedown(function(){currObj.stopScroll(); currObj.startScroll(currObj.deltaChange); return false}).mouseup(function(){currObj.stopScroll()}).mouseout(function(){currObj.stopScroll()});
	this.arrowDownRight.click(function(){return false;}).mousedown(function(){currObj.stopScroll(); currObj.startScroll(- currObj.deltaChange); return false}).mouseup(function(){currObj.stopScroll()}).mouseout(function(){currObj.stopScroll()});
	this.sliderLine.bind("DOMMouseScroll", function(currEvent){currObj.mouseWheel(currEvent);}).bind("mousewheel", function(currEvent){currObj.mouseWheel(currEvent);});
	if (this.isNotNumeric)
	{
		this.innerElement.bind("DOMMouseScroll", function(currEvent){currObj.mouseWheel(currEvent);}).bind("mousewheel", function(currEvent){currObj.mouseWheel(currEvent);});
	}
}

ScrollObj.prototype.makeUpdate = function()
{
	this.dragSliderSize = (this.isVertical) ? this.dragSlider.height() : this.dragSlider.width();
	this.sliderLineSize = (this.isVertical) ? this.sliderLine.height() : this.sliderLine.width();
	this.sliderLineTotalSize = this.sliderLineSize - this.dragSliderSize;

	var currOrient = (this.isVertical) ? "top" : "left";
	if (this.isNotNumeric)
	{
		this.outerElementSize = (this.isVertical) ? this.outerElement.height() : this.outerElement.width();
		this.innerElementSize = (this.isVertical) ? this.innerElement.height() : this.innerElement.width();
		this.innerElementTotalSize = this.innerElementSize - this.outerElementSize;
		this.scrollCoefficient = (this.innerElementTotalSize == 0) ? 0 : this.sliderLineTotalSize / this.innerElementTotalSize;
		this.scrollCoefficient = (isNaN(this.scrollCoefficient)) ? 0 : this.scrollCoefficient;
		var currInnerPos = (this.isVertical) ? parseInt(this.innerElement.css(currOrient)) : parseInt(this.innerElement.parent().css(currOrient));
		currInnerPos = (isNaN(currInnerPos)) ? 0 : currInnerPos;
		if (currInnerPos > 0)
		{
			currInnerPos = 0;
			if (this.isVertical) this.innerElement.css(currOrient, "0px"); else this.innerElement.parent().css(currOrient, "0px");
		}
		if (currInnerPos + this.innerElementSize < this.outerElementSize)
		{
			currInnerPos = this.outerElementSize - this.innerElementSize;
			if (this.isVertical) this.innerElement.css(currOrient, currInnerPos + "px"); else this.innerElement.parent().css(currOrient, currInnerPos + "px");
		}
		if (this.innerElementTotalSize < 1)
		{
			currInnerPos = 0;
			if (this.isVertical) this.innerElement.css(currOrient, "0px"); else this.innerElement.parent().css(currOrient, "0px");
			this.dragSlider.hide();
		}
		else this.dragSlider.show();
		this.currSliderPos = - currInnerPos * this.scrollCoefficient;
	}
	else
	{
		this.scrollCoefficient = ((this.maxValue - this.minValue) == 0) ? 0 : this.sliderLineTotalSize / (this.maxValue - this.minValue);
		this.scrollCoefficient = (isNaN(this.scrollCoefficient))? 0 : this.scrollCoefficient;
		this.outerElement.text(this.currValue + this.currMask);
		this.currSliderPos = this.currValue * this.scrollCoefficient;
	}
	this.currSliderPos = (this.currSliderPos < 0) ? 0 : (this.currSliderPos > this.sliderLineTotalSize) ? this.sliderLineTotalSize : this.currSliderPos;
	var dragToNewPosition = Math.round(this.currSliderPos);
	this.dragSlider.css(currOrient, dragToNewPosition + "px");
}

ScrollObj.prototype.startDrag = function(currEvent)
{
	this.dragStartMouse = (this.isVertical) ? (currEvent.clientY || currEvent.pageY) + $(document).scrollTop() : (currEvent.clientX || currEvent.pageX) + $(document).scrollLeft();
	var currObj = this;
	$(document).mousemove(function(currEvent){currObj.makeDrag(currEvent)}).mouseup(function(){currObj.stopDrag()});
}

ScrollObj.prototype.makeDrag = function(currEvent)
{
	var currentMousePosition = (this.isVertical) ? (currEvent.clientY || currEvent.pageY) + $(document).scrollTop() : (currEvent.clientX || currEvent.pageX) + $(document).scrollLeft();
	var mouseDifference = currentMousePosition - this.dragStartMouse;
	var dragToNewPosition = this.currSliderPos + mouseDifference;
	dragToNewPosition = (dragToNewPosition < 0) ? 0 : (dragToNewPosition > this.sliderLineTotalSize) ? this.sliderLineTotalSize : dragToNewPosition;
	var currOrient = (this.isVertical) ? "top" : "left";
	this.tempDrag = dragToNewPosition;
	this.dragSlider.css(currOrient, Math.round(dragToNewPosition) + "px");
	if (this.isNotNumeric)
	{
		if (this.isVertical)
			this.innerElement.css(currOrient, Math.round(- dragToNewPosition * (1 / this.scrollCoefficient)) + "px");
		else
			this.innerElement.parent().css(currOrient, Math.round(- dragToNewPosition * (1 / this.scrollCoefficient)) + "px");
	}
	else
	{
		this.currValue = dragToNewPosition * (1 / this.scrollCoefficient);
		this.currValue = (this.currValue < this.minValue) ? this.minValue : (this.currValue > this.maxValue) ? this.maxValue : this.currValue;
		this.outerElement.text(Math.round(this.currValue) + this.currMask);
	}

	if (currEvent.stopPropagation) currEvent.stopPropagation(); else currEvent.cancelBubble = true;
	if (currEvent.preventDefault) currEvent.preventDefault(); else currEvent.returnValue = false;
}

ScrollObj.prototype.stopDrag = function()
{
	$(document).unbind("mousemove").unbind("mouseup");
	if (this.tempDrag > -1)
	{
		this.currSliderPos = this.tempDrag;
		this.tempDrag = -1;
	}
}

ScrollObj.prototype.startScroll = function(deltaChange)
{
	if (this.innerElementTotalSize < 1) return false;
	var currOrient = (this.isVertical) ? "top" : "left";
	var dragContent = 0;
	if (this.isNotNumeric)
	{
		dragContent = (this.isVertical) ? parseInt(this.innerElement.css(currOrient)) + deltaChange : parseInt(this.innerElement.parent().css(currOrient)) + deltaChange;
		dragContent = (this.innerElementTopLeft - dragContent < 0) ? this.innerElementTopLeft : (this.innerElementTopLeft - dragContent > this.innerElementTotalSize) ? - (this.innerElementTopLeft + this.innerElementTotalSize) : dragContent;
		this.currSliderPos = this.currSliderPos - deltaChange * this.scrollCoefficient;
	}
	else
	{
		this.currValue = this.currValue + deltaChange;

		this.currValue = (this.currValue < this.minValue) ? this.minValue : (this.currValue > this.maxValue) ? this.maxValue : this.currValue;
		this.currSliderPos = this.currSliderPos + deltaChange * this.scrollCoefficient;
	}

	this.currSliderPos = (this.currSliderPos < 0) ? 0 : (this.currSliderPos > this.sliderLineTotalSize) ? this.sliderLineTotalSize : this.currSliderPos;

	var dragToNewPosition = Math.round(this.currSliderPos);
	this.dragSlider.css(currOrient, dragToNewPosition + "px");
	if (this.isNotNumeric)
	{
		if (this.isVertical)
			this.innerElement.css(currOrient, dragContent + "px");
		else
			this.innerElement.parent().css(currOrient, dragContent + "px");
	}
	else this.outerElement.text(Math.round(this.currValue) + this.currMask)

	this.scrollTimer = window.setTimeout(this.currCopy + ".startScroll(" + deltaChange + ")", 25);
}

ScrollObj.prototype.stopScroll = function()
{
	if (this.scrollTimer)
	{
		window.clearTimeout(this.scrollTimer);
		this.scrollTimer = null;
	}
}

ScrollObj.prototype.mouseWheel = function(currEvent)
{
	if ((this.innerElementTotalSize < 0) || (this.cannotWheel) || (!this.scrollCoefficient)) return false;

	currEvent = currEvent || window.event;
	var wheelDelta = 0;
	if (currEvent.wheelDelta) 
		wheelDelta = - currEvent.wheelDelta / 120;
	else
		if (currEvent.detail) wheelDelta = currEvent.detail / 3;
	var currStep = (this.isVariableScroll) ? 1 * wheelDelta * this.deltaChange : 1 * wheelDelta * this.deltaScrollChange * this.scrollCoefficient;

	var dragToNewPosition = this.currSliderPos + currStep;
	dragToNewPosition = (dragToNewPosition < 0) ? 0 : (dragToNewPosition > this.sliderLineTotalSize) ? this.sliderLineTotalSize : dragToNewPosition;
	var currOrient = (this.isVertical) ? "top" : "left";
	this.currSliderPos = dragToNewPosition;

	this.dragSlider.css(currOrient, Math.round(dragToNewPosition) + "px");
	if (this.isNotNumeric)
	{
		if (this.isVertical)
			this.innerElement.css(currOrient, Math.round(- dragToNewPosition * (1 / this.scrollCoefficient)) + "px");
		else
			this.innerElement.parent().css(currOrient, Math.round(- dragToNewPosition * (1 / this.scrollCoefficient)) + "px");
	}
	else
	{
		this.currValue = dragToNewPosition * (1 / this.scrollCoefficient);
		this.currValue = (this.currValue < this.minValue) ? this.minValue : (this.currValue > this.maxValue) ? this.maxValue : this.currValue;
		this.outerElement.text(Math.round(this.currValue) + this.currMask);
	}

	if (currEvent.stopPropagation) currEvent.stopPropagation();
	if (currEvent.preventDefault) currEvent.preventDefault();
	currEvent.returnValue = false;
}
