// immediately change opacity. Works in different browsers.
// exposed globally rather than inside the fade animation function
// cuz we want to call it separately, too. 
function changeOpac (src, opacity) { 
	var elemStyle = src.style;
	elemStyle.opacity = (opacity / 100); 
	elemStyle.MozOpacity = (opacity / 100); 
	elemStyle.KhtmlOpacity = (opacity / 100); 
	elemStyle.filter = "alpha(opacity=" + opacity + ")"; 
}

function animateFade(elem,startOpac,endOpac, callback) {
	var steps = 10;
	var intervals = 30;
	var powr = 0.5;
	genericAnimator(elem, startOpac, endOpac, changeOpac, steps, intervals, powr, callback);
}

function animateScroll(elem, startScroll, endScroll) {
	var steps = 10;
	var intervals = 30;
	var powr = 0.5;	
	scrollObj = function (obj, scrollLevel) {
    obj.scrollTop = scrollLevel;
	};
	genericAnimator(elem, startScroll, endScroll, scrollObj, steps, intervals, powr, null);
}

function animateHeight(elem, startHeight, endHeight, callback) {
	var steps = 10;
	var intervals = 30;
	var powr = 1;
	changeHeight = function(obj, newHeight) {
		obj.style.height = newHeight + "px"; 
	};
	genericAnimator(elem, startHeight, endHeight, changeHeight, steps, intervals, powr, callback);
}

function animateBgColor(elem, startRGB,endRGB,finalColor) {
	var steps = 10;
	var intervals = 30;
	var powr = 1;
	
	changeBackgroundColor = function(elem, bgRGBArray) {
		elem.style.backgroundColor = "rgb(" + bgRGBArray[0] +"," + bgRGBArray[1] + "," + bgRGBArray[2] + ")";
	};
	setFinalBackgroundColor = function() {
		elem.style.backgroundColor = finalColor;
	};
	genericAnimator(elem, startRGB, endRGB, changeBackgroundColor, steps,intervals, powr, setFinalBackgroundColor);
}


/*
Technique from http://www.hesido.com/web.php?page=javascriptanimation

elem: element that we're going to animate
startHeight: starting height of animation
endHeight: target height of animation
steps: total steps of animation
intervals: intervals the animation will be done in miliseconds
powr: value used for determining ease-in and out.
----
elem.animationMemInt: The interval animation value for self inhibition.
elem.currentAnimationValue: The objects 'memory' of its last set animated value
actstep: actual step of the animation, increased 1 per every execution.
callback: function to call after animation is done.
*/
function genericAnimator(elem, startValue, endValue, changeFunction, steps,intervals, powr, callback) {
  if (elem.animationMemInt) {	
  	window.clearInterval(elem.animationMemInt);
  }
  var actStep = 0;
  elem.animationMemInt = window.setInterval(
		function() { 
	  	elem.currentAnimationValue = easeInOut(startValue, endValue, steps, actStep, powr);
	  	changeFunction(elem, elem.currentAnimationValue); 
	  	actStep++;
	  	if (actStep > steps) {
	  		window.clearInterval(elem.animationMemInt);
	  		if (callback) {
	  			callback();
	  		}
	  	}
		} 
		,intervals);	
}

function easeInOut(minValue,maxValue,totalSteps,actualStep,powr) { 
	if (realtypeof(minValue) == 'array') { 
			// we are dealing with an array input; recursively process its contents
//			console.log("easeInOut dealing with arrays", minValue, maxValue);
			var result = [];
			for(var i = 0; i < minValue.length; i++) {
				result[result.length] = easeInOut(minValue[i],maxValue[i],totalSteps,actualStep,powr);
			}
			return result;
	}
    var delta = maxValue - minValue; 
    var stepp = minValue+(Math.pow(((1 / totalSteps) * actualStep), powr) * delta); 
    return Math.ceil(stepp);
}
