/* --------------------------------------------------------------- 
   Author : Remi Palard
   october 2006
   remi.palard@gmail.com
   
   Warning - no borders or padding on content, container, etc. => todo 
--------------------------------------------------------------- */

function scrollbar(whoAmI) {
	var content;
	var container;
	var scrollArea;
	var scroller;
	var scrollH, docH, contH, scrollAreaH, scrollDist;
	var useScroll;
	var timer;
	var mainDelta;
	var refreshSpeed;
	var draggable;
	var whoAmI;
	
	this.timer = true;
	this.useScroll = true;	
	this.mainDelta = 20;
	this.refreshSpeed = 50;	
	this.whoAmI = whoAmI;

	/* ----- Public --------- */
	
	scrollbar.prototype.init = function(content,container,scroller,scrollArea) {	
		// Init
		this.content = content;
		this.container = container;
		this.scroller = scroller;	
		this.scrollArea = scrollArea;	

		// Get Size
		this.docH = this.getHeight(this.content);
		this.contH = this.getHeight(this.container);
		this.scrollAreaH = this.getHeight(this.scrollArea);				

		// Usefull scrollbar ?
		if (this.contH >= this.docH) {

			// Hide scroller
			Element.hide(this.scroller);
			
			// Stop
			this.useScroll = false; 
			return;
		}

		//RT143980
		//Ensuring the variable is set to its initial state ==> true 
        //IE seems to be unable to set this variable to the proper state 
        this.useScroll = true; 
		 
		// Set scroll Size - calculate height of scroller and resize the scroller div
		this.scrollH = (this.contH * this.scrollAreaH) / this.docH;
		if(this.scrollH < 15) this.scrollH = 15;
		
		// Apply 
		$(this.scroller).style.height = parseInt(this.scrollH) + 'px';		
		
		// What is the effective scroll distance once the scoller's height has been taken into account
		this.scrollDist = parseInt(this.scrollAreaH - this.scrollH) -6;	// Scrollarea padding - todo	
		
		// Start
		this.dragScrolling();	
	}
	
	/* --------------------- */
	
	scrollbar.prototype.dragScrolling = function() {
		var delta;
		
		// This... pb => value backup	
		delta = this.scrollDist;
		
		// Just in case
		if (this.draggable) this.draggable.destroy();
		
		// Start draggable
		this.draggable = new Draggable($(this.scroller),{
			moveAction:true,	
			constraint:'vertical',
			starteffect:false,
			endeffect:false,	
			zindex:false,
			snap: function(x,y) {return[x, y < delta ? (y > 0 ? y : 0) : delta];}	
		}); 
		
		// Extend draggable action
		this.draggable.scroller = this.scroller;
		this.draggable.docH = this.docH;
		this.draggable.contH = this.contH;
		this.draggable.content = this.content;		
		this.draggable.scrollDist = this.scrollDist;
		
  	this.draggable.addBehavior = function() {
  		var d, scrollY, docY;  
  		
  		// Draggable value
			d = this.currentDelta(); 							
			
			// Apply
			docY = 0 - parseInt(((d[1]) * ((this.docH - this.contH) / this.scrollDist)));
			$(this.content).style.top = docY + "px" ;   	
		}  			 		
	}
	
	/* --------------------- */
	
	scrollbar.prototype.startScrolling = function(dir,specialDelta) {		
		var textY, scrollY;
		var delta, scrollDelta;
		
		// Fixed or specified delta
		if (specialDelta != null) delta = specialDelta;
		else delta = this.mainDelta; 
		
		// Text mouvement => Scroll mouvement
		scrollDelta = parseInt( (delta * this.scrollDist) / (this.docH - this.contH) );
		
		// Start scolling
		if (this.timer) {
					
			// Finding nemo
			if (dir == 'up') {	
							
				// Get positions					
				textY = this.getTop(this.content) + delta; 
				scrollY = this.getTop(this.scroller) - scrollDelta;	
				
				// Last step ? => min position	
				if ( textY > 0 ) {
					textY = 0;
					scrollY = 0;			
					
					// Stop scrolling for next step
					this.timer = false;					
				}					
						
			} else {		
				
				// Get positions
				textY = this.getTop(this.content) - delta;
				scrollY = this.getTop(this.scroller) + scrollDelta;					
				
				// Last step ? => max position	
				if ( (this.docH - this.contH) < Math.abs(textY) ) {
					textY = 0 - (this.docH - this.contH);
					scrollY = parseInt(this.scrollDist);				
					
					// Stop scrolling for next step
					this.timer = false;						
				}		
			}	
				
			// Apply styles
			$(this.content).style.top = textY + "px" ;
			$(this.scroller).style.top = scrollY + "px" ;	
			
			// Re-launch
			if (specialDelta == null) setTimeout(this.whoAmI + ".startScrolling('" + dir + "')",this.refreshSpeed);
		}
	}
	
	/* --------------------- */
	
	scrollbar.prototype.btnScrolling = function(dir) {		
		this.timer = true;
		if (this.useScroll) this.startScrolling(dir);
	}		
	
	/* --------------------- */
	
	scrollbar.prototype.scrollToDiv = function(id) {		
		var elH, posCont, posDiv, posScroll, dir;
		
		// Init Timer
		this.timer = true;
		
		// Find positions
		posDiv = findPos($(id));
		posCont = findPos($(this.container));
		posScroll = findPos($(this.scroller));

		// Distance
		elH = Math.abs(posDiv[1] - posCont[1]);
		
		// Direction
		dir = posDiv[1] - posScroll[1] > 0 ? 'dn' : 'up';

		// Start Scrolling
		this.startScrolling(dir,elH);
	}	
	
	/* --------------------- */
	
	scrollbar.prototype.scrollToTop = function() {		
		this.scrollToDiv(this.content);
	}				
	
	/* --------------------- */
	
	scrollbar.prototype.stopScrolling = function() {		
		this.timer = false;
	}	
	
	/* --------------------- */
	
	scrollbar.prototype.start = function(content,container,scroller,scrollArea) {		
		
		// Vars
		this.content = content;
		this.container = container
		this.scroller = scroller;
		this.scrollArea = scrollArea;
			
		// Start	
		this.restart();
	}		
	
	/* --------------------- */
	
	scrollbar.prototype.restart = function() {		
		
		// Global var
		this.timer = true;
		this.useScroll = true;		
		
		// Scroller
		Element.show(this.scroller);
		$(this.scroller).style.top = 0;
		$(this.content).style.top = 0;
		
		// Reset draggable
		if (this.draggable) this.draggable.destroy();
			
		// Start	
		this.init(this.content,this.container,this.scroller,this.scrollArea);
	}	

	
	/* ----- Private -------- */

	scrollbar.prototype.getHeight = function(id) {
		var contentSize = Element.getDimensions(id);
		return contentSize.height <= 0 ? $(id).clientHeight : contentSize.height;		
	}	
	
	scrollbar.prototype.getTop = function(id) {
		return parseInt(Element.getStyle(id,'top').replace(/px/g,''));		
	}		
	
}

/* --------------------------------------------------------------- */