// JavaScript Document



function Scroller(up, track, drag, down, trackDim)
{
	this._dom = document.getElementById;
	if (!this._dom)
	{
		alert("Scroller: DOM is not supported by the browser. The scrolls will not function.");
		return;
	}
	
	var _this = this;
	this._isVisible = true;
	
	this._funcPtrScrollJump = function(e) { _this.ScrollJump(e) };
	this._funcPtrStartDrag = function(e) { _this.StartDrag(e) };
	this._funcPtrOnDrag = function(e) { _this.OnDrag(e) };
		
	this._scrollFrame = null;
	this._contentFrame = null;
	
	this._scrollElemUp = null;
	this._scrollElemDown = null;
	this._scrollElemDrag = null;
	this._scrollElemTrack = null;
	this._scrollElemTrackDim = null;
	
	this._contentElem = null;
	this._contentMaskElem = null;
	
	//____
	this._scrollSpeed = null; // scrolling speed
	this._dragHeight = null; // Height of scrollbar drag
	this._trackHeight = null; // Height of scrollbar track	
	this._trackTop = null; // Scrollbar top contraint
	this._trackLength = null; // Adjusted track height
	this._trackBottom = null; // Scrollbar bottom contraint
	this._contentMaskHeight = null;// Height of the div that masks the content div
	this._contentHeight = null; // Height of the content div
	this._contentLength = null; // Adjusted content height
	this._scrollLength = null; // Height difference between the scrollbar track and the content
	this._scrollTimer = null;
	
	this._dragStartMouse = null; // Holds the starting y mouse position
	this._dragStartOffset = null; // Holds the starting top position of the scrollbar drag
}

Scroller.prototype.GetTrackElem = function()
{
	//alert("Scroller::GetTrackElem");
	if ( this._scrollElemTrack != null)
		return this._scrollElemTrack;
	else
	{
		alert("Scroller::GetTrackElem: No up element set");
		return null;
	}
}

Scroller.prototype.SetScrollerFrame = function(scrollFrame)
{
	this._scrollFrame = scrollFrame;
	var _this = this;
	this._scrollFrame.document.getThisScroller = function() { return _this; };
}

Scroller.prototype.SetContentFrame = function(contentFrame)
{
	this._contentFrame = contentFrame;
	//var _this = this;
	//this._contentFrame.onload = _this.Init;	
}

Scroller.prototype.SetScrollIds = function(up, down, drag, track, trackDim)
{
	if (!this._dom)
		return;
		
	var _this = this;
		
	if (this._scrollFrame == null)
	{
		alert("Scroller::SetScrollIds: Scroll frame must be set before calling SetScrollIds.");
		return;
	}
	
	this._scrollElemUp = this._GetElem(up, this._scrollFrame);
	this._scrollElemDown = this._GetElem(down, this._scrollFrame);
	this._scrollElemDrag = this._GetElem(drag, this._scrollFrame);
	this._scrollElemTrack = this._GetElem(track, this._scrollFrame);
	this._scrollElemTrackDim = this._GetElem(trackDim, this._scrollFrame);

	

}

Scroller.prototype.SetContentIds = function(contentMask, content)
{
	if (this._contentFrame == null)
	{
		alert("Scroller::SetScrollIds: Content frame must be set before calling SetContentIds.");
		return;
	}
	
	this._contentElem = this._GetElem(content, this._contentFrame);
	this._contentMaskElem = this._GetElem(contentMask, this._contentFrame);
}

Scroller.prototype._GetElem = function(id, frame)
{
	var elem = frame.document.getElementById(id);
	
	if (elem == null)
		alert("Scroller: Could not find scroll element with id: " + id + ".\nEither id or scroll frame is invalid."); 
	else
	{		
		elem.getTop = function() 
		{
			//alert(elem + " " + parseInt(elem.style.top));
			if (isNaN(parseInt(elem.style.top)))
			{
				alert("Top has not been set for element: " + elem.id);
				return 0;
			}
			else
				return parseInt(elem.style.top);			
		};
		elem.setTop = function(y) { elem.style.top = y + "px"; };
		elem.getHeight = function() 
		{
			//alert(elem.id +"::getHeight, ret: " + elem.offsetHeight);
			return elem.offsetHeight; //style.height wont work because it is not set since hight depends on the amount of text
		};
		elem.getClipHeight = function() { return elem.offsetHeight; };
		var _this = this;
		elem.getThisScroller = function() { return _this; };
	}
	return elem;
}

Scroller.prototype.Init = function()
{
	this._scrollElemDrag.setTop(this._scrollElemTrack.getTop());
	
	this._scrollSpeed = 6; // scrolling speed
	this._dragHeight = this._scrollElemDrag.getHeight(); // Height of scrollbar drag
	this._trackHeight = this._scrollElemTrack.getHeight(); // Height of scrollbar track	
	
	this._trackTop = this._scrollElemDrag.getTop(); // Scrollbar top contraint
	this._trackLength = this._trackHeight - this._dragHeight; // Adjusted track height
	this._trackBottom = this._trackTop + this._trackLength; // Scrollbar bottom contraint
	this._contentMaskHeight = this._contentMaskElem.getClipHeight();// Height of the div that masks the content div
	this._contentHeight = this._contentElem.getHeight(); // Height of the content div
	this._contentLength = this._contentHeight - this._contentMaskHeight; // Adjusted content height
	this._scrollLength = this._trackLength / this._contentLength; // Height difference between the scrollbar track and the content
	this._scrollTimer = null;
	
	
	
	if(this._contentHeight > this._contentMaskHeight)
	{
		//Show scrollbar
		this._scrollElemUp.style.visibility = "visible";
		this._scrollElemTrack.style.visibility = "visible";
		this._scrollElemDown.style.visibility = "visible";
		this._scrollElemDrag.style.visibility = "visible";
		this._isVisible = true;
		
		if (document.all)
		{
			this._scrollElemTrack.attachEvent('onmousedown', this._funcPtrScrollJump );
			this._scrollElemDrag.attachEvent('onmousedown', this._funcPtrStartDrag );
			this._scrollElemDrag.ondragstart = function(){ return false }; // for ie4.5 compatibility			
		}
		else
		{				
			this._scrollElemTrack.addEventListener("mousedown", this._funcPtrScrollJump, false);
			this._scrollElemDrag.addEventListener("mousedown", this._funcPtrStartDrag, false);	
			
			//var _this = this;
			//this._scrollElemDrag.onmousedown = _this.StartDrag;
		}
		
		var _this = this;		
		this._scrollElemUp.onmousedown = function(){ _this.StartScroll(1); return false };
		this._scrollElemDown.onmousedown = function(){ _this.StartScroll(-1); return false};
	}
	else
	{
		//Content height is less than the height of contentMask, hence, no scrollbar needed
		//this._scrollElemTrackDim.style.visibility = 'visible';
		this._isVisible = false;
	}
}

Scroller.prototype.IsVisible = function()
{
	return this._isVisible;
}

Scroller.prototype.StartDrag = function(e)
{	
	//window.status = "StartDrag";
	var scroller = this;
	
	//___________________________________________________________
	//if (!document.all)
	//	scroller = this.getThisScroller();
	//___________________________________________________________
	
	if (document.all)
		scroller._dragStartMouse = event.clientY;
	else
		scroller._dragStartMouse = e.pageY; //pageY
	
	scroller._dragStartOffset = scroller._scrollElemDrag.getTop(); // Holds the starting top position of the scrollbar drag
	
	//alert(scroller._dragStartOffset + " " + scroller._dragStartMouse);
	//alert(scroller._scrollFrame + " " + scroller._scrollFrame.document);

	var _this = this;
	if (document.all)
	{		
		this._scrollFrame.document.attachEvent('onmousemove', this._funcPtrOnDrag );
		this._scrollFrame.document.onmouseup = function() { _this.StopDrag(); };
		//This maybe solves problem with 
		//this._scrollFrame.document.onmouseout = function() { _this.StopDrag(); };
	}
	else
	{
		this._scrollFrame.document.addEventListener("mousemove", this._funcPtrOnDrag, false);
		this._scrollFrame.document.onmouseup = function() { _this.StopDrag(); };
		
		//scroller._scrollFrame.document.onmousemove = scroller.OnDrag;
		//document.onmouseup = function() { scroller.StopDrag(); };		
	}	

	return false;
}

Scroller.prototype.OnDrag = function(e)
{
	var scroller = this; 	
	var currentMouse = 0;
	
	//___________________________________________________________
	//if (!document.all)
	//	scroller = this.getThisScroller();
	//___________________________________________________________
	
	//window.status = "OnDRAG: " + this + ", " + scroller + " " + scroller.GetTrackElem().id;

	if (document.all)
		currentMouse = event.clientY;
	else
		currentMouse = e.pageY; //pageY
		
	var mouseDifference = currentMouse - scroller._dragStartMouse;

	var newDragTop = scroller._dragStartOffset + mouseDifference;

	//Check so that it does not move out of the track
	if (newDragTop < scroller._scrollElemTrack.getTop())
		newDragTop = scroller._scrollElemTrack.getTop();
	else if (newDragTop > (scroller._scrollElemTrack.getTop() + scroller._scrollElemTrack.getHeight() - scroller._scrollElemDrag.getHeight()))
		newDragTop = scroller._scrollElemTrack.getTop() + scroller._scrollElemTrack.getHeight() - scroller._scrollElemDrag.getHeight(); 																									  
	scroller._scrollElemDrag.setTop(newDragTop);

	// move content
	var scrollLength = (scroller._contentElem.getHeight() - scroller._contentMaskElem.getClipHeight()) / (scroller._scrollElemTrack.getHeight() - scroller._scrollElemDrag.getHeight()); // Height difference between the scrollbar track and the content
	var newContentTop = - (newDragTop - scroller._scrollElemTrack.getTop()) * scrollLength;
	scroller._contentElem.setTop(newContentTop);

	return false;
}

Scroller.prototype.StopDrag = function()
{
	//window.status = "StopDrag";
	
	if (document.all)
	{
		this._scrollFrame.document.detachEvent('onmousemove', this._funcPtrOnDrag );
		this._scrollFrame.document.onmouseup = null; 
	}
	else
	{
		this._scrollFrame.document.removeEventListener("mousemove", this._funcPtrOnDrag, false);
		this._scrollFrame.document.onmouseup = null;
		
		//this._scrollFrame.document.onmousemove = null;
		//document.onmouseup = null;
	}
}

Scroller.prototype.ScrollJump = function(e)
{
//	window.status = "scroll jump";
	
	var currentMouse = 0;
	
	if (document.all)
		//Sets or retrieves the y-coordinate of the mouse pointer's position relative to the object firing the event.
		currentMouse = event.offsetY;
	else
		currentMouse = e.layerY; //pageY
		
	var scroller = this;
	// move drag
	var newDragTop = currentMouse - (scroller._scrollElemDrag.getHeight()/2);
	
	//Since we use offsetY above we need to add 
	newDragTop += scroller._scrollElemTrack.getTop();
	

	//Check so that it does not move out of the track
	if (newDragTop < scroller._scrollElemTrack.getTop())
		newDragTop = scroller._scrollElemTrack.getTop();
	else if (newDragTop > (scroller._scrollElemTrack.getTop() + scroller._scrollElemTrack.getHeight() - scroller._scrollElemDrag.getHeight()))
		newDragTop = scroller._scrollElemTrack.getTop() + scroller._scrollElemTrack.getHeight() - scroller._scrollElemDrag.getHeight(); 																									  
	scroller._scrollElemDrag.setTop(newDragTop);

	// move content
	var scrollLength = (scroller._contentElem.getHeight() - scroller._contentMaskElem.getClipHeight()) / (scroller._scrollElemTrack.getHeight() - scroller._scrollElemDrag.getHeight()); // Height difference between the scrollbar track and the content
	var newContentTop = - (newDragTop - scroller._scrollElemTrack.getTop()) * scrollLength;
	scroller._contentElem.setTop(newContentTop);
	
	//window.status = "mouse: " + currentMouse + ", newDragTop: " + newDragTop + ", track top: " + scroller._scrollElemTrack.getTop() + ", drag height: " + scroller._scrollElemDrag.getHeight();

	return false;
}



Scroller.prototype.StartScroll = function(dir)
{
	var _this = this;
	document.onmouseup = function() { _this.StopScroll() };
	this._Scroll(dir);
}

Scroller.prototype.StopScroll = function()
{
	if(this._scrollTimer)
	{
		window.clearTimeout(this._scrollTimer);
		this._scrollTimer = null;
	}
	document.onmouseup = null;
}	

Scroller.prototype._Scroll = function(dir)
{
	var contentMovement = this._contentElem.getTop() + this._scrollSpeed * dir;
	var contentLength = this._contentElem.getHeight() - this._contentMaskElem.getClipHeight(); // Adjusted content height
	
	if(contentMovement > 0)
	{
		contentMovement = 0;
	}
	else if(contentMovement < -contentLength)
	{
		contentMovement = -contentLength;
	}

	this._contentElem.setTop(contentMovement);

	// move drag
	var trackLength = this._scrollElemTrack.getHeight() - this._scrollElemDrag.getHeight();
	var trackBottom = this._scrollElemTrack.getTop() + trackLength;
	var dragMovement = this._contentElem.getTop() * (trackLength/contentLength);

	dragMovement = this._scrollElemTrack.getTop() - Math.round(dragMovement);

	if (dragMovement < this._scrollElemTrack.getTop())
	{
		dragMovement = this._scrollElemTrack.getTop();
	}
	else if (dragMovement > trackBottom)
	{
		dragMovement = trackBottom;
	}

	this._scrollElemDrag.setTop(dragMovement);

	// repeat
	var _this = this;
	this._scrollTimer = window.setTimeout( function() { _this._Scroll(dir) }, 25);
/*
	scrollTimer = window.setTimeout('scroll('+speed+')',25);
*/
	return false;
}
	
Scroller.prototype.ReInit = function()
{
	//alert ("Scroller::ReInit");
	//this._scrollElemDrag.setTop(this._scrollElemTrack.getTop());
	
	this._scrollSpeed = 6; // scrolling speed
	this._dragHeight = this._scrollElemDrag.getHeight(); // Height of scrollbar drag
	this._trackHeight = this._scrollElemTrack.getHeight(); // Height of scrollbar track	
	
	this._trackTop = this._scrollElemDrag.getTop(); // Scrollbar top contraint
	this._trackLength = this._trackHeight - this._dragHeight; // Adjusted track height
	this._trackBottom = this._trackTop + this._trackLength; // Scrollbar bottom contraint
	this._contentMaskHeight = this._contentMaskElem.getClipHeight();// Height of the div that masks the content div
	this._contentHeight = this._contentElem.getHeight(); // Height of the content div
	this._contentLength = this._contentHeight - this._contentMaskHeight; // Adjusted content height
	this._scrollLength = this._trackLength / this._contentLength; // Height difference between the scrollbar track and the content
	this._scrollTimer = null;
	
	//alert (this._contentHeight + " " +  this._contentMaskHeight);
	
	//if (this._isVisible)
	//	return;
	
	// Reset stuff
		//Event listeners
		if (document.all)
		{
			this._scrollElemTrack.detachEvent('onmousedown', this._funcPtrScrollJump );
			this._scrollElemDrag.detachEvent('onmousedown', this._funcPtrStartDrag );
			this._scrollElemDrag.ondragstart = null;
		}
		else
		{				
			this._scrollElemTrack.removeEventListener("mousedown", this._funcPtrScrollJump, false);
			this._scrollElemDrag.removeEventListener("mousedown", this._funcPtrStartDrag, false);	
			
			//var _this = this;
			//this._scrollElemDrag.onmousedown = _this.StartDrag;
		}

		this._scrollElemUp.onmousedown = null;
		this._scrollElemDown.onmousedown = null;
	
		//If dragging, stop
		this.StopDrag();
		
		//Scroll to top
		this._scrollElemDrag.setTop(this._scrollElemTrack.getTop());
		this._contentElem.setTop(0);
	
	//Now add event listeners if they are needed
	if(this._contentHeight > this._contentMaskHeight)
	{
		//Show scrollbar
		this._scrollElemUp.style.visibility = "visible";
		this._scrollElemTrack.style.visibility = "visible";
		this._scrollElemDown.style.visibility = "visible";
		this._scrollElemDrag.style.visibility = "visible";
		this._isVisible = true;
		
		if (document.all)
		{
			this._scrollElemTrack.attachEvent('onmousedown', this._funcPtrScrollJump );
			this._scrollElemDrag.attachEvent('onmousedown', this._funcPtrStartDrag );
			this._scrollElemDrag.ondragstart = function(){ return false }; // for ie4.5 compatibility			
			//This maybe solves problem with 
			//this._scrollFrame.document.onmouseout = function() { _this.StopDrag(); };
		}
		else
		{				
			this._scrollElemTrack.addEventListener("mousedown", this._funcPtrScrollJump, false);
			this._scrollElemDrag.addEventListener("mousedown", this._funcPtrStartDrag, false);	
			
			//var _this = this;
			//this._scrollElemDrag.onmousedown = _this.StartDrag;
		}
		
		var _this = this;		
		this._scrollElemUp.onmousedown = function(){ _this.StartScroll(1); return false };
		this._scrollElemDown.onmousedown = function(){ _this.StartScroll(-1); return false};
	}
	else
	{
		//Content height is less than the height of contentMask, hence, no scrollbar needed
		//this._scrollElemTrackDim.style.visibility = 'visible';
		
		//Show scrollbar
		this._scrollElemUp.style.visibility = "hidden";
		this._scrollElemTrack.style.visibility = "hidden";
		this._scrollElemDown.style.visibility = "hidden";
		this._scrollElemDrag.style.visibility = "hidden";		
		this._isVisible = false;
	}
}

