function cScrollBar(Track, Tracker, Settings)
{
	this.Track = Track;
	this.Tracker = Tracker;
	this.Length = Settings.Length;
	this.Frame = Settings.Frame;
	this.Line = Settings.Line;
	this.LinesInWhell = Settings.LinesInWhell;
	this.OnComplete = Settings.OnComplete;
	this.OnUpdate = Settings.OnUpdate;
	this.ScrollElement = Settings.ScrollElement;
	this.Horizontal = !!Settings.Horizontal;
	
	this.Track.style.position = 'relative';
	this.Tracker.style.position = 'absolute';
	this.ScrollElement.style.display = 'block';
	
	if (this.Frame >= this.Length)
	{
		this.ScrollElement.style.display = 'none';
		this.Disabled = true;
		return false;
	}
	
	this.TrackerPos = 0;
	this.TrackSize = this.Horizontal ? Track.offsetWidth : Track.offsetHeight;
	this.RealTrackerSize = this.Frame/this.Length*this.TrackSize;
	this.TrackerSize = Math.round(this.RealTrackerSize < 50 ? 50 : this.RealTrackerSize);
	// для постраничной прокрутки
	this.RealTrackSize = this.TrackSize - this.TrackerSize + this.RealTrackerSize;
	this.RealTrackerSize = this.Frame / this.Length * this.RealTrackSize;
	
	if (this.Horizontal)
	{
		Tracker.style.width = Math.round(this.TrackerSize)+'px';
	} 
	else
	{
		Tracker.style.height = Math.round(this.TrackerSize)+'px';
	}
	
	this.OnTrackMouseDown = this.bindAsEventListener(this.TrackMouseDown);
	this.OnTrackerMouseDown = this.bindAsEventListener(this.TrackerMouseDown);
	this.OnDocumentMouseMove = this.bindAsEventListener(this.DocumentMouseMove);
	this.OnDocumentMouseUp = this.bindAsEventListener(this.DocumentMouseUp);
	this.OnArrowUpMouseDown = this.bindAsEventListener(this.ArrowUpMouseDown);
	this.OnArrowDownMouseDown = this.bindAsEventListener(this.ArrowDownMouseDown);
	this.OnArrowMouseUp = this.bindAsEventListener(this.ArrowMouseUp);
	this.OnPageMouseOver = this.bindAsEventListener(this.PageMouseOver);
	this.OnPageMouseOut = this.bindAsEventListener(this.PageMouseOut);
	this.OnPageMouseScroll = this.bindAsEventListener(this.PageMouseScroll);
	
	this.bindEvent(this.Track, 'mousedown', this.OnTrackMouseDown);
	this.bindEvent(this.Tracker, 'mousedown', this.OnTrackerMouseDown);
	this.bindEvent(this.Tracker, 'click', this.stopEvent);
	
	if (typeof Settings.OnInit == 'function')
	{
		Settings.OnInit.call(this);
	}
}

cScrollBar.prototype = {
	ScrollTo: function(pos)
	{
		if (this.Disabled) 
			return false;
		if (pos < 0)
			pos = 0;
		if (pos > this.Length - this.Frame)
			pos = this.Length - this.Frame;
		this.Position = pos;
		
		var SpaceSize = this.TrackSize - this.TrackerSize;
		var Y = SpaceSize * this.Position / (this.Length - this.Frame);
		this.TrackerPos = Y;
		if (this.Horizontal)
		{
			this.Tracker.style.left = Math.round(Y) + 'px';
		} 
		else
		{
			this.Tracker.style.top = Math.round(Y) + 'px';
		}
		
		if (typeof this.OnUpdate == 'function')
		{
			this.OnUpdate.call(this, this.Position);
		}
	},
	TrackMouseDown: function(event)
	{
		if (this.Horizontal)
		{
			var X = event.clientX + document.documentElement.scrollLeft - this.getOffsets(this.Track)[0];
			if (X < this.TrackerPos)
				this.PageUp();
			if (X >= this.TrackerPos + this.TrackerSize)
				this.PageDown();
		} 
		else
		{
			var Y = event.clientY + document.documentElement.scrollTop - this.getOffsets(this.Track)[1];
			if (Y < this.TrackerPos)
				this.PageUp();
			if (Y >= this.TrackerPos + this.TrackerSize)
				this.PageDown();
		}
		return this.stopEvent(event);
	},
	TrackerMouseDown: function(event)
	{
		this.TrackerOffsets = this.getOffsets(this.Track);
		if (this.Horizontal)
		{
			this.DragDot = event.clientX + document.documentElement.scrollLeft - this.getOffsets(this.Tracker)[0];
			this.TrackerDrugUpdate(event.clientX + document.documentElement.scrollLeft - this.TrackerOffsets[0]);
		} 
		else
		{
			this.DragDot = event.clientY + document.documentElement.scrollTop - this.getOffsets(this.Tracker)[1];
			this.TrackerDrugUpdate(event.clientY + document.documentElement.scrollTop - this.TrackerOffsets[1]);
		}
		
		this.bindEvent(document, 'mousemove', this.OnDocumentMouseMove);
		this.bindEvent(document, 'mouseup', this.OnDocumentMouseUp);
		return this.stopEvent(event);
	},
	DocumentMouseMove: function(event)
	{
		if (this.Horizontal)
		{
			this.TrackerDrugUpdate(event.clientX + document.documentElement.scrollLeft - this.TrackerOffsets[0]);
		} 
		else
		{
			this.TrackerDrugUpdate(event.clientY + document.documentElement.scrollTop - this.TrackerOffsets[1]);
		}
		return this.stopEvent(event);
	},
	DocumentMouseUp: function(event)
	{
		this.unbindEvent(document, 'mousemove', this.OnDocumentMouseMove);
		this.unbindEvent(document, 'mouseup', this.OnDocumentMouseUp);

		if (typeof this.OnComplete == 'function')
		{
			this.OnComplete.call(this);
		}
		return this.stopEvent(event);
	},
	TrackerDrugUpdate: function (Y)
	{
		Y -= this.DragDot;
		if (Y < 0)
			Y = 0;
		var SpaceSize = this.TrackSize - this.TrackerSize;
		if (Y > SpaceSize)
			Y = SpaceSize;
		this.TrackerPos  = Y;
		if (this.Horizontal)
		{
			this.Tracker.style.left = Math.round(Y) + 'px';
		} 
		else
		{
			this.Tracker.style.top = Math.round(Y) + 'px';
		}
		this.Position = Y / SpaceSize * (this.Length - this.Frame);
		
		if (typeof this.OnUpdate == 'function') 
		{
			this.OnUpdate.call(this, this.Position);
		}
	},
	
	BindAsArrowUp: function(el)
	{
		this.bindEvent(el, 'mousedown', this.OnArrowUpMouseDown);
		this.bindEvent(el, 'click', this.stopEvent);
	},	
	BindAsArrowDown: function(el)
	{
		this.bindEvent(el, 'mousedown', this.OnArrowDownMouseDown);
		this.bindEvent(el, 'click', this.stopEvent);
	},
	BindAsScrolledPage: function(el)
	{
		this.bindEvent(el, 'mouseover', this.OnPageMouseOver);
		this.bindEvent(el, 'mouseout', this.OnPageMouseOut);
		this.bindEvent(window, 'DOMMouseScroll', this.OnPageMouseScroll);
		window.onmousewheel = document.onmousewheel = this.OnPageMouseScroll;
	},
	
	PageMouseOver: function(event) 
	{
		this.MouseOverPage = true;
	},
	PageMouseOut: function(event) 
	{
		this.MouseOverPage = false;
	},
	PageMouseScroll: function(event) 
	{
		if (this.MouseOverPage) 
		{
			var delta = (typeof event.wheelDelta != 'undefined') ? event.wheelDelta  : -event.detail;
			
			if ((this.TrackerPos <= 0) && (delta > 0))
				return true;
			if ((this.TrackerPos >= this.TrackSize - this.TrackerSize) && (delta < 0))
				return true;
			
			if (delta > 0)
				this.LineUp(this.LinesInWhell);
			else 
				this.LineDown(this.LinesInWhell);
			
			return this.stopEvent(event);
		}
	},
	ArrowUpMouseDown: function(event) 
	{
		this.bindEvent(document, 'mouseup', this.OnArrowMouseUp);
		var _this = this;
		this.ArrowTimer = setInterval(function() 
		{
			_this.LineUp();
		}, 50);
		this.LineUp();
		return this.stopEvent(event);
	},
	ArrowDownMouseDown: function(event) 
	{
		this.bindEvent(document.documentElement, 'mouseup', this.OnArrowMouseUp);
		var _this = this;
		this.ArrowTimer = setInterval(function() 
		{
			_this.LineDown();
		}, 50);
		this.LineDown();
		return this.stopEvent(event);
	},
	ArrowMouseUp: function(event) 
	{
		this.unbindEvent(document.documentElement, 'mouseup', this.OnArrowMouseUp);
		//alert(this.OnArrowMouseUp);
		if (this.ArrowTimer)
			clearInterval(this.ArrowTimer);
		return this.stopEvent(event);
	},
	PageUp: function() 
	{
		this.DragDot = 0;
		this.TrackerDrugUpdate(this.TrackerPos - this.RealTrackerSize);
	},
	PageDown: function() 
	{
		this.DragDot = 0;
		this.TrackerDrugUpdate(this.TrackerPos + this.RealTrackerSize);
	},
	LineUp: function(num) 
	{
		this.DragDot = 0;
		this.TrackerDrugUpdate(this.TrackerPos - this.Line * (num || 1) / this.Length * this.RealTrackSize);
	},
	LineDown: function(num) 
	{
		this.DragDot = 0;
		this.TrackerDrugUpdate(this.TrackerPos + this.Line * (num || 1) / this.Length * this.RealTrackSize);
	},	
	
	
	getOffsets: function(element) 
	{
	    var valueT = 0, valueL = 0;
	    do {
			valueT += element.offsetTop  || 0;
			valueL += element.offsetLeft || 0;
			element = element.offsetParent;
	    } while (element);
	    return [valueL, valueT];
	},
	leadSpaces: function(numb)
	{
		var res = '';
		numb = numb.toString();
		var l = numb.length;
		for (var i=l; i>0; i--)
			if ((l-i)%3==2)
				res = '&nbsp;'+numb.charAt(i-1)+res;
			else
				res = numb.charAt(i-1)+res;
		return res;
	},
	bindEvent: function(element, event, callBack)
	{
		if (element.addEventListener) 
		{
			element.addEventListener(event, callBack, false);
		} 
		else 
		{
			element.attachEvent('on' + event, callBack);
		}
	},
	unbindEvent: function(element, event, callBack)
	{
		if (element.removeEventListener) 
		{
			element.removeEventListener(event, callBack, false);
	    } 
		else if (element.detachEvent) 
		{
			element.detachEvent('on' + event, callBack);
	    }
	},
	bindAsEventListener: function (callBack)
	{
		var _this = this;
		return function(event) 
		{
			return callBack.call(_this, event || window.event);
		}
	},
	stopEvent: function (event)
	{
		if (event.preventDefault) 
		{
			event.preventDefault();
			event.stopPropagation();
		}
		else
		{
			event.returnValue = false;
			event.cancelBubble = true;
		}
		return false;
	}
}

