var heightShifterScroller = new scrollHandler();

function elementHeightShifter(idOfElementToSlideArg, targetHeightArg, effectArg, slideTimeArg, callbackFuncsArg, idOfElementToScrollToArg) {
	
	/**
	* Vars thet we get from constructorcall
	*/
	this.idOfElementToSlide = idOfElementToSlideArg;
	this.targetHeight = targetHeightArg;
	this.effect = effectArg;
	this.slideTime = slideTimeArg;
	this.callbackFuncs = callbackFuncsArg;
	this.idOfElementToScrollTo = idOfElementToScrollToArg;
	
	/**
	* Vars initiated when creating new object
	*/
	var thisObj = this;
	this.elmToSlide = element(idOfElementToSlideArg);	
	this.startTime = new Date().getTime();

	/**
	* Static vars
	*/
	this.miliSecsBetweenChanges = 10;	
	
	/**
	* Class vars set later on	
	*/
	this.heightToCalculateSpeedOn;	
	this.slideTimeout;	
	this.effect;	
	this.elapsedTime;
	this.distancePercent;
	this.scrollPageOnElementClose = true;
	this.followClosingElement = false;
	
	this.start = function() {
		
		// Make sure that element exists
		if(document.getElementById(this.idOfElementToSlide)) {
	
			this.heightToCalculateSpeedOn = this.getHeightToCalculateSpeedOn();
			
			// We need to set this again because of some bug in element.
			this.elmToSlide = element(this.idOfElementToSlide);
			
			this.changeHeight();
			
		} // Element does not exist, do nothing
		
	}
	
	/**
	*
	*/
	this.setScrollPageOnElementClose = function(val) {
		
		this.scrollPageOnElementClose = val;
		
	}
	
	/**
	*
	*/
	this.getHeightToCalculateSpeedOn = function() {
		
		var heightToCalculateSpeedOn = this.elmToSlide.getH();
			
		// If the element is closed
		if(heightToCalculateSpeedOn == 0 || heightToCalculateSpeedOn == 1) {
			
			// Get the height from the inner element
			heightToCalculateSpeedOn = element(this.idOfElementToSlide + 'Inner').getH();
			
		}
		
		return heightToCalculateSpeedOn;
		
	}
	
	/*
	*
	*/
	this.getCurveIncrement = function(percent) {
		
		return (1-Math.cos(percent*Math.PI)) / 2;
		
	}
	
	/**
	* Change the height of an element
	*/
	this.changeHeight = function() {
		
		var elapsedTime = new Date().getTime() - this.startTime;
		
		// If we are opening the element
		if(this.effect == 'open') {
			
			distancePercent = this.getCurveIncrement(elapsedTime/this.slideTime);
			
		} else {
			
			if(this.followClosingElement) {
				
				// If the bottom y position of the element that we are closing is 
				// smaller than the top y position of the body
				if(parseInt(getYPos(document.getElementById(this.elmToSlide.id))) + parseInt(this.elmToSlide.getH()) < getYOfBodyTop()) {
				
					// Scroll to the position we get when adding the top y position of the closing element
					// to the height of the closing element. This will cause the page to scroll up with the element.
					scrollTo(0, parseInt(getYPos(document.getElementById(this.elmToSlide.id))) + parseInt(this.elmToSlide.getH()) );
						
				}
				
			}
			
			distancePercent = 1 - this.getCurveIncrement(elapsedTime/this.slideTime);
			
		}
		
		var newHeight = distancePercent * this.heightToCalculateSpeedOn;
		
		// Change the height of the element
		this.elmToSlide.setH(distancePercent * this.heightToCalculateSpeedOn + 'px');
		
		// Debug
		//window.status = distancePercent + ' ' + newHeight;
	
		// If we have not reached the end of the script execution time
		if(elapsedTime < this.slideTime) {
			
			this.slideTimeout = setTimeout(function() { thisObj.changeHeight(); }, this.miliSecsBetweenChanges);
			
		} else {		
			
			// Kill the timeout
			clearTimeout(this.slideTimeout);
	
			// 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])();
					
				}
			
			}
			
			// If we are supposed to open the element
			if(this.effect == 'open') {
				
				// In case the script has been stalled in any way, lets completely open the element
				this.elmToSlide.setH(this.targetHeight + 'px');
				
			} else { // Closing the element
				
				// If there is an element to scroll to and the element is above the current y of the body
				if(this.idOfElementToScrollTo != false && parseInt(getYPos(document.getElementById(this.idOfElementToScrollTo))) < getYOfBodyTop()) {

					heightShifterScroller.scrollToElement(this.idOfElementToScrollTo); // Scroll to it

				}
				
				// In case the script has been stalled in any way, lets completely close the element			
				this.elmToSlide.setH(1 + 'px');
				
			}		
			
		}
	
	}

}
