/**
* requires utilities.js
*/

function scrollHandler() {
	
	var thisObj = this;
	
	this.timeout;
	this.scrollDirection;
	this.currentY;
	this.targetY;
	this.heightOfElementToScrollTo;
	this.callbackFuncs = false;
	this.idOfElementToScrollTo;
	this.scrollPastTopAllowed = true;

	this.pixelsPerScroll = 40;
	this.milisecsBetweenScrolls = 5;
	
	this.diff;
	
	/**
	*
	*/
	this.init = function(pixelsPerScrollVar, milisecsBetweenScrollsVar) {
		
		this.pixelsPerScroll = pixelsPerScrollVar;
		this.milisecsBetweenScrolls = milisecsBetweenScrollsVar;
		
	}
	
	
	/**
	*
	*/
	this.scrollToElement = function(idOfElementToScrollTo) {
		
		// Get the current y
		this.currentY = getYOfBodyTop();
		
		// Find where we want to go
		this.targetY = getYPos(document.getElementById(idOfElementToScrollTo));
		
		// Only continue if we are not at the exact same pixel that we want to get to... it could happen.
		if(this.targetY != this.currentY) {
		
			// Assume down since that will be the case in 99% of the cases
			this.scrollDirection = 'down';
			
			// If target is above the current position
			if(this.targetY < this.currentY) {
				
				this.scrollDirection = 'up';
				
			}
			
			// Call scrollfunction
			this.scroll();
		
		} else { // We are not scrolling but lets at least call the callback functions
			
			this.callCallbackFunctions();
			
		}
		
	}
	
	/**
	*
	*/
	this.scrollToBottomOfElement = function(idOfElementToScrollToVar, scrollUpIfNeeded, scrollPastTopAllowedVar, nrOfExtraPixels) {

		// Get the current y
		this.currentY = getYOfBodyTop();
		
		this.idOfElementToScrollTo = idOfElementToScrollToVar;
		
		this.heightOfElementToScrollTo = element(this.idOfElementToScrollTo).getH();
		
		this.scrollPastTopAllowed = scrollPastTopAllowedVar;
		
		// Find where we want to go by getting the y pos of the element and adding
		// the height of the element and then removing the height of the window
		this.targetY = (getYPos(document.getElementById(this.idOfElementToScrollTo)) + this.heightOfElementToScrollTo + nrOfExtraPixels) - (getWinHeight());
		
		// Only continue if we are not at the exact same pixel that we want to get to... it could happen.
		if(this.targetY != this.currentY) {
		
			// Assume down since that will be the case in 99% of the cases
			this.scrollDirection = 'down';
			
			// If target is above the current position
			if(this.targetY < this.currentY) {
				
				if(scrollUpIfNeeded) {
					
					this.scrollDirection = 'up';
					
				} else {
					
					return true;
					
				}
				
			}
			
			// Call scrollfunction
			this.bottomOfWindowScroll();
		
		} else { // We are not scrolling but lets at least call the callback functions
			
			this.callCallbackFunctions();
			
		}		
		
	}
	
	/**
	*
	*/
	this.setCallbackFuncs = function(callbackFuncs) {
		
		this.callbackFuncs = callbackFuncs;
		
	}
	
	/**
	*
	*/
	this.scroll = function() {
		
		var newY;
		
		// If we are moving on up
		if(this.scrollDirection == 'up') {
			
			// Calculate new scroll
			newY = this.currentY - this.pixelsPerScroll;
			
			// If the new y-value is above the target
			if(newY < this.targetY) {
				// Fall back to target
				newY = this.targetY;
			}
			
		} else { // We are moving down
			
			newY = this.currentY + this.pixelsPerScroll;
			
			// If the new y-value is below the target
			if(newY > this.targetY) {
				// Fall back to target
				newY = this.targetY;		
			}
			
		}
		
		// Scroll
		scrollTo(0, newY);
	
		// If we have not reached the target
		if(newY != this.targetY) {
			
			this.currentY = newY;	
			this.timeout = setTimeout(function() { thisObj.scroll(); }, this.milisecsBetweenScrolls);
			
		} else {
			
			clearTimeout(this.timeout);
			
			this.callCallbackFunctions();			
			
		}
		
	}
	
	/**
	* Scrolls by using bottom of window as 
	*/
	this.bottomOfWindowScroll = function() {
		
		var newY;
		
		// If we are moving on up
		if(this.scrollDirection == 'up') {
			
			// Calculate new scroll
			newY = this.currentY - this.pixelsPerScroll;
			
			// If the new y-value is above the target
			if(newY < this.targetY) {
				// Fall back to target
				newY = this.targetY;
			}
			
		} else { // We are moving down
			
			newY = this.currentY + this.pixelsPerScroll;
			
			// If the new y-value is below the target
			if(newY > this.targetY) {
				// Fall back to target
				newY = this.targetY;		
			}
			
		}
		
		// Scroll
		scrollTo(0, newY);
		
		window.status = newY + ' vs ' + this.targetY;
	
		// If we have not reached the target and its ok to scroll past top or not ok but newY is smaller than 
		// y of element to scroll
		if(newY != this.targetY && (this.scrollPastTopAllowed || (!this.scrollPastTopAllowed && newY <= getYPos(document.getElementById(this.idOfElementToScrollTo))))) {
			
			this.currentY = newY;	
			this.timeout = setTimeout(function() { thisObj.bottomOfWindowScroll(); }, this.milisecsBetweenScrolls);
			
		} else {
			
			clearTimeout(this.timeout);
			
			this.callCallbackFunctions();			
			
		}
		
	}	
	
	/**
	*
	*/
	this.callCallbackFunctions = function() {
		
		// If callbackfunctions is an array
		if(this.callbackFuncs != false) {
			
			var callbackFuncsLength = this.callbackFuncs.length;
			
			// Loop the callback functions
			for(var i = 0; i < callbackFuncsLength; i++) {
				
				// Call current callback
				eval(this.callbackFuncs[i])();
				
			}
			
			// Clear the callback functions
			this.callbackFuncs = false;
		
		}		
		
	}
	
	/*
	*
	*/
	this.getCurveIncrement = function(percent) {
		
		return (1-Math.cos(percent*Math.PI)) / 2;
		
	}	
	
}
