 
	function Scroller(strDirection, strClipId, strBodyId, strUpId, strDownId, strBarContId, strBarId)
	{
		this.ScrollTimout = null;
		this.intSpeed = 100;
		this.intSteps = 10;
		this.intDragStart = 0;

		this.strDirection = (strDirection == "horizontal" || strDirection == "h") ? "h" : "v";
		this.Clipper = document.getElementById(strClipId);
		this.Body = document.getElementById(strBodyId);
		this.Up = document.getElementById(strUpId);
		this.Down = document.getElementById(strDownId);
		this.BarCont = document.getElementById(strBarContId);
		this.Bar = document.getElementById(strBarId);

		this.intBarSize = this.Bar ? (this.strDirection == "h" ? this.Bar.offsetWidth : this.Bar.offsetHeight) : 0;
		this.intBarY = this.intBarX = 0;
		this.intBarContY = this.intBarContX = 0;

		this.bolInitialized = false;
		this.Holder = null;
		this.bolBodyScrollable = false;
	}

	Scroller.prototype.Init = function()
	{
		if (!this.bolInitialized)
		{
			if (this.strDirection == "h")
			{
				if (this.Body) this.Body.style.left = "0px";
				if (this.Bar)
				{
					this.Bar.style.top = ((Utils.GetOffsetY(this.BarCont) + ((this.BarCont.offsetHeight / 2) - (this.Bar.offsetHeight / 2))) - (this.Holder ? Utils.GetOffsetY(this.Holder) : 0)) + "px";
					this.Bar.style.left = (this.intBarX = this.intBarContX = (Utils.GetOffsetX(this.BarCont) - (this.Holder ? Utils.GetOffsetX(this.Holder) : 0))) + "px";
				}
			} else {
				if (this.Body) this.Body.style.top = "0px";
				if (this.Bar)
				{
					this.Bar.style.left = ((Utils.GetOffsetX(this.BarCont) + ((this.BarCont.offsetWidth / 2) - (this.Bar.offsetWidth / 2))) - (this.Holder ? Utils.GetOffsetX(this.Holder) : 0)) + "px";
					this.Bar.style.top = (this.intBarY = this.intBarContY = (Utils.GetOffsetY(this.BarCont) - (this.Holder ? Utils.GetOffsetY(this.Holder) : 0))) + "px";
				}
			}

			clearInterval(this.InitInterval);
			this.InitByInterval();
			if (this.Bar) this.Bar.style.visibility = "visible";
			this.bolInitialized = true;
		} else if (this.Bar) {
			this.Bar.style.visibility = "visible";
		}
	}

	Scroller.prototype.InitByInterval = function()
	{
		var Self = this;
		this.InitInterval = setInterval(function()
		{
			if (Self.Clipper && Self.Body)
			{
				if (Self.Body.offsetWidth <= Self.Clipper.offsetWidth) Self.Body.style.left = "0px";
				if (Self.Body.offsetHeight <= Self.Clipper.offsetHeight) Self.Body.style.top = "0px";
			}

			if (Self.strDirection == "h" && Self.BarCont && Self.Bar && Self.Clipper && Self.Body)
			{
				var intX = Utils.GetOffsetX(Self.BarCont) - (Self.Holder ? Utils.GetOffsetX(Self.Holder) : 0);
				var intWidth = (Self.Clipper.offsetWidth / (Self.Clipper.offsetWidth + Self.Body.offsetWidth)) * Self.BarCont.offsetWidth;
				if (intWidth < Self.intBarSize) intWidth = Self.intBarSize;
				if (Self.Body.offsetWidth <= Self.Clipper.offsetWidth) intWidth = Self.BarCont.offsetWidth;
				Self.Bar.style.top = ((Utils.GetOffsetY(Self.BarCont) + ((Self.BarCont.offsetHeight / 2) - (Self.Bar.offsetHeight / 2))) - (Self.Holder ? Utils.GetOffsetY(Self.Holder) : 0)) + "px";
				Self.Bar.style.width = intWidth + "px";
				if (intX != Self.intBarContX)
				{
					Self.intBarX = (Self.intBarX - Self.intBarContX) + intX;
					Self.Bar.style.left = Self.intBarX + "px";
					Self.intBarContX = intX;
				}
			} else if (Self.BarCont && Self.Bar && Self.Clipper && Self.Body) {
				var intY = Utils.GetOffsetY(Self.BarCont) - (Self.Holder ? Utils.GetOffsetY(Self.Holder) : 0);
				var intHeight = (Self.Clipper.offsetHeight / (Self.Clipper.offsetHeight + Self.Body.offsetHeight)) * Self.BarCont.offsetHeight;
				if (intHeight < Self.intBarSize) intHeight = Self.intBarSize;
				if (Self.Body.offsetHeight <= Self.Clipper.offsetHeight) intHeight = Self.BarCont.offsetHeight;
				Self.Bar.style.left = ((Utils.GetOffsetX(Self.BarCont) + ((Self.BarCont.offsetWidth / 2) - (Self.Bar.offsetWidth / 2))) - (Self.Holder ? Utils.GetOffsetX(Self.Holder) : 0)) + "px";
				/*Self.Bar.style.height = 5 + "px";/*
				/* intHeight */
				if (intY != Self.intBarContY)
				{
					Self.intBarY = (Self.intBarY - Self.intBarContY) + intY;
					Self.Bar.style.top = Self.intBarY + "px";
					Self.intBarContY = intY;
				}
			}
			Self.CatchEvents();
		}, 1000);
	}

	Scroller.prototype.SetBarHolder = function(strId)
	{
		var Holder = document.getElementById(strId);
		if (Holder)
		{
			this.Holder = Holder;
		}
	}

	Scroller.prototype.SetBodyScrollable = function()
	{
		if (this.Body)
		{
			this.bolBodyScrollable = true;
			this.Body.style.cursor = "default";
		}
	}

	Scroller.prototype.HideBar = function()
	{
		if (this.Bar) this.Bar.style.visibility = "hidden";
	}

	Scroller.prototype.CatchEvents = function()
	{
		if (
			(this.strDirection == "h" && this.Body.offsetWidth > this.Clipper.offsetWidth)
			|| (this.strDirection == "v" && this.Body.offsetHeight > this.Clipper.offsetHeight)
		)
		{
			var Self = this;

			if (this.Up)
			{
				this.Up.onmousedown = function()
				{
					Self.Scroll("up");
					return false;
				}
				this.Up.onmouseup = function()
				{
					Self.Stop();
					return false;
				}
			}

			if (this.Down)
			{
				this.Down.onmousedown = function()
				{
					Self.Scroll("down");
					return false;
				}
				this.Down.onmouseup = function()
				{
					Self.Stop();
					return false;
				}
			}

			if (this.Bar)
			{
				this.Bar.onmousedown = function(AEvent)
				{
					Self.MakeMoveable(AEvent);
					return false;
				}
			}

			if (this.strDirection == "v" && this.Body)
			{
				this.Body.onmousewheel = function(AEvent)
				{
					Self.ScrollByWheel(AEvent);
					return false;
				}
				this.Body.onMouseWheel = function(AEvent)
				{
					alert("scrollen");
					//Self.ScrollByWheel(AEvent);
					return false;
				}
			} else this.Body.onmousewheel = function() { return false; }

			if (this.bolBodyScrollable && this.Body)
			{
				this.Body.onmousedown = function(AEvent)
				{
					Self.MakeBodyMoveable(AEvent);
					return false;
				}
			}
		} else {
			if (this.Up)
			{
				this.Up.onmousedown = function() { return false; }
				this.Up.onmouseup = function() { return false; }
			}

			if (this.Down)
			{
				this.Down.onmousedown = function() { return false; }
				this.Down.onmouseup = function() { return false; }
			}

			if (this.Bar)
			{
				if (this.strDirection == "h") this.Bar.style.left = (Utils.GetOffsetX(this.BarCont) - (this.Holder ? Utils.GetOffsetX(this.Holder) : 0)) + "px";
				else this.Bar.style.top = (Utils.GetOffsetY(this.BarCont) - (this.Holder ? Utils.GetOffsetY(this.Holder) : 0)) + "px";
				this.Bar.onmousedown = function() { return false; }
			}

			if (this.Body) this.Body.onmousewheel = function() { return false; }
			if (this.bolBodyScrollable) this.Body.onmousedown = function() { return false; }
		}
	}

	Scroller.prototype.CheckPosition = function(intY)
	{
		var intReturnVal = 0;
		var intX = intY;
		if (this.Clipper && this.Body)
		{
			if (this.strDirection == "h")
			{
				if (intX > 0) intX = 0;
				if (intX < this.Clipper.offsetWidth - this.Body.offsetWidth) intX = this.Clipper.offsetWidth - this.Body.offsetWidth;
				intReturnVal = intX;
			} else {
				if (intY > 0) intY = 0;
				if (intY < this.Clipper.offsetHeight - this.Body.offsetHeight) intY = this.Clipper.offsetHeight - this.Body.offsetHeight;
				intReturnVal = intY;
			}
		}
		return intReturnVal;
	}

	Scroller.prototype.PositionScrollbar = function()
	{
		if (this.BarCont && this.Bar && this.Body && this.Clipper)
		{
			if (this.strDirection == "h")
			{
				var intZero = Utils.GetOffsetX(this.BarCont) - (this.Holder ? Utils.GetOffsetX(this.Holder) : 0);
				var intX = Math.round(-(((this.BarCont.offsetWidth - this.Bar.offsetWidth) / (this.Body.offsetWidth - this.Clipper.offsetWidth)) * parseInt(this.Body.style.left)) + intZero);
				if (intX < intZero) intX = intZero;
				if (intX > (this.BarCont.offsetWidth - this.Bar.offsetWidth) + intZero) intX = (this.BarCont.offsetWidth - this.Bar.offsetWidth) + intZero;
				this.Bar.style.left = (this.intBarX = intX) + "px";
			} else {
				var intZero = Utils.GetOffsetY(this.BarCont) - (this.Holder ? Utils.GetOffsetY(this.Holder) : 0);
				var intY = Math.round(-(((this.BarCont.offsetHeight - this.Bar.offsetHeight) / (this.Body.offsetHeight - this.Clipper.offsetHeight)) * parseInt(this.Body.style.top)) + intZero);
				if (intY < intZero) intY = intZero;
				if (intY > (this.BarCont.offsetHeight - this.Bar.offsetHeight) + intZero) intY = (this.BarCont.offsetHeight - this.Bar.offsetHeight) + intZero;
				this.Bar.style.top = (this.intBarY = intY) + "px";
			}
		}
	}

	Scroller.prototype.Stop = function()
	{
		var bolStopEvent = arguments.length > 0 ? arguments[0] : false;
		clearTimeout(this.ScrollTimeout);
		if (bolStopEvent) document.onmousemove = null;
		return true;
	}

	Scroller.prototype.Scroll = function(strDir)
	{
		clearTimeout(this.ScrollTimout);
		if (this.Clipper && this.Body)
		{
			if
				(
					(this.strDirection == "h" && this.Body.offsetWidth > this.Clipper.offsetWidth)
					|| (this.strDirection == "v" && this.Body.offsetHeight > this.Clipper.offsetHeight)
				)
			{
				var Self = this;
				if (this.strDirection == "h")
				{
					var intX = this.CheckPosition(parseInt(this.Body.style.left) + (strDir == "up" ? this.intSteps : -(this.intSteps)));
					this.Body.style.left = intX + "px";
				} else {
					var intY = this.CheckPosition(parseInt(this.Body.style.top) + (strDir == "up" ? this.intSteps : -(this.intSteps)));
					this.Body.style.top = intY + "px";
				}
				this.PositionScrollbar();
				this.ScrollTimeout = setTimeout(function()
				{
					Self.Scroll(strDir);
				}, this.intSpeed);
			}
		}
	}

	Scroller.prototype.Move = function(Event)
	{
		if (Event && this.BarCont && this.Bar && this.Clipper && this.Body)
		{
			if (this.strDirection == "h")
			{
				var intX = Event.clientX - this.intDragStart;
				var intZero = Utils.GetOffsetX(this.BarCont) - (this.Holder ? Utils.GetOffsetX(this.Holder) : 0);
				if (intX < intZero) intX = intZero;
				if (intX > (this.BarCont.offsetWidth - this.Bar.offsetWidth) + intZero) intX = (this.BarCont.offsetWidth - this.Bar.offsetWidth) + intZero;
				this.Body.style.left = Math.round(-(((this.Body.offsetWidth / (this.BarCont.offsetWidth - this.Bar.offsetWidth)) - (this.Clipper.offsetWidth / (this.BarCont.offsetWidth - this.Bar.offsetWidth))) * (intX - intZero))) = "px";
				this.Bar.style.left = (this.intBarX = intX) + "px";
			} else {
				var intY = Event.clientY - this.intDragStart;
				var intZero = Utils.GetOffsetY(this.BarCont) - (this.Holder ? Utils.GetOffsetY(this.Holder) : 0);
				if (intY < intZero) intY = intZero;
				if (intY > (this.BarCont.offsetHeight - this.Bar.offsetHeight) + intZero) intY = (this.BarCont.offsetHeight - this.Bar.offsetHeight) + intZero;
				this.Body.style.top = Math.round(-(((this.Body.offsetHeight / (this.BarCont.offsetHeight - this.Bar.offsetHeight)) - (this.Clipper.offsetHeight / (this.BarCont.offsetHeight - this.Bar.offsetHeight))) * (intY - intZero))) + "px";
				this.Bar.style.top = (this.intBarY = intY) + "px";
			}
		}
	}

	Scroller.prototype.MoveBody = function(Event)
	{
		if (Event && this.Clipper && this.Body)
		{
			if (this.strDirection == "h")
			{
				var intX = Event.clientX - this.intDragStart;
				var intZero = 0;
				if (intX > intZero) intX = intZero;
				if (intX < (this.Clipper.offsetWidth - this.Body.offsetWidth) + intZero) intX = (this.Body.offsetWidth - this.Body.offsetWidth) + intZero;
				this.Body.style.left = intX + "px";
			} else {
				var intY = Event.clientY - this.intDragStart;
				var intZero = 0;
				if (intY > intZero) intY = intZero;
				if (intY < (this.Clipper.offsetHeight - this.Body.offsetHeight) + intZero) intY = (this.Clipper.offsetHeight - this.Body.offsetHeight) + intZero;
				this.Body.style.top = intY + "px";
			}
			this.PositionScrollbar();
		}
	}

	Scroller.prototype.MakeMoveable = function(AEvent)
	{
		if (this.Bar)
		{
			var Event = AEvent ? AEvent : event;
			var Self = this;
			if (this.strDirection == "h")
			{
				this.intDragStart = Event.clientX - parseInt(this.Bar.style.left);
			} else {
				this.intDragStart = Event.clientY - parseInt(this.Bar.style.top);
			}
			document.onmousemove = function(AEvent)
			{
				var Event = AEvent ? AEvent : event;
				Self.Move(Event);
				return false;
			}
		}
		document.onmouseup = function()
		{
			Self.Stop(true);
		}
		return false;
	}

	Scroller.prototype.MakeBodyMoveable = function(AEvent)
	{
		if (this.Body)
		{
			var Event = AEvent ? AEvent : event;
			var Self = this;
			if (this.strDirection == "h")
			{
				this.intDragStart = Event.clientX - parseInt(this.Body.style.left);
			} else {
				this.intDragStart = Event.clientY - parseInt(this.Body.style.top);
			}
			document.onmousemove = function(AEvent)
			{
				var Event = AEvent ? AEvent : event;
				Self.MoveBody(Event);
				return false;
			}
		}
		document.onmouseup = function()
		{
			Self.Stop(true);
		}
		return false;
	}


	Scroller.prototype.ScrollByWheel = function(AEvent)
	{
		var Event = AEvent ? AEvent : event;
		if (this.Clipper && this.Body && Event.wheelDelta)
		{
			//if (this.strDirection == "h")
			//{
				//var intX = this.CheckPosition(parseInt(this.Body.style.left) + (strDir == "up" ? this.intSteps : -(this.intSteps)));
				//this.Body.style.left = intX + "px";
			//} else {
				var intY = this.CheckPosition(parseInt(this.Body.style.top) + Event.wheelDelta);
				this.Body.style.top = intY + "px";
			//}
			this.PositionScrollbar();
		}
		return false;
	}