/*
 * ScrollingDetection, Animation and Tween objects
 * Objects used to slide the menu according to the scroll offset
 * 
 * Author:	myXpass.com
 * Date:	Novembre 2008
 * 
 * Copyritgh (c) 2008 - myxpass.com - All rights reserved
 * 
 */

var ScrollingDetection = function(callback,checktime)
{
	var self = this;
	this.checktime = (checktime == null ? 200 : checktime);
	this.callback = callback;
	this.offsetTop = 0;
	this.scrolling = false;
	this.direction = null;
	
	this.check_resize = function() {
		var oldOffset = self.offsetTop;
		self.offsetTop = window.pageYOffset ? window.pageYOffset : (document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop);
		if(self.offsetTop != oldOffset) {
			self.scrolling = true;
			self.direction = self.offsetTop > oldOffset ? "down" : "up";
		}
	
		if(self.scrolling) {
			self.scrolling  = false;
			self.callback(self);
		}
		
		setTimeout(self.check_resize, self.checktime);
	}
	
	this.check_resize();
}

var Animation = function(obj)
{
	var self = this;
	
	this.getOffsetTop = function(obj) {
		var top = obj.offsetTop;
		while(obj.offsetParent) {
			top += obj.offsetParent.offsetTop;
			if(document.body == obj.offsetParent) break;
			obj = obj.offsetParent;
		}
		return top
	}
	
	this.obj = obj;
	this.objHeight = parseInt(this.obj.offsetHeight);
	this.objOffsetTop = this.getOffsetTop(this.obj);
	this.minTop = this.obj.currentStyle ? parseInt(this.obj.currentStyle['top']) : (window.getComputedStyle ? parseInt(document.defaultView.getComputedStyle(this.obj,null).getPropertyValue('top')) : parseInt(this.obj.style.top));
	this.obj.style.top = this.minTop + 'px';
	this.maxTop = parseInt(this.obj.offsetParent.offsetHeight) - parseInt(this.obj.offsetHeight);
	this.animating = false;

	this.i = 0;
	this.max =  100;
	this.delta = 0;
	this.startpos = this.minTop;

	this.animate = function(scrollData) {
		var i = 0;
		var was_animating = self.animating;
		var do_animation = true;
		self.animating = true;

		var windowHeight = parseInt(window.innerHeight ? window.innerHeight : (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight));
		var scrollPos	= scrollData.offsetTop;
		var curpos		= parseInt(self.obj.style.top);
		var realScroll	= scrollPos - self.objOffsetTop;
		var newpos 		= realScroll;
	
		/*
		 * Handle the case where menu is higher than the window
		 * Menu need to be scrolled without any sliding effect !
		 */
		if(self.objHeight > windowHeight) {
			if(scrollData.direction == "down") {
				var objectBottom = self.objOffsetTop + curpos + self.objHeight;
				var windowBottom = scrollPos + windowHeight;
				
				if(windowBottom < objectBottom) {
					do_animation = false;
					self.animating = false;
				} else {
					newpos -= (self.objHeight - windowHeight);
				}
			} else {
				if(curpos < newpos) {
					do_animation = false;
					self.animating = false;
				}
			}
		}
		
		// Apply changes
		if(do_animation) {
			if(newpos > self.maxTop) newpos = self.maxTop;
			if(newpos < self.minTop) newpos = self.minTop;
			
			self.i = 0;
			self.delta = newpos - curpos;
			self.startpos = curpos;
	
			if(!was_animating) self.fanimating();
		}
	}

	this.fanimating = function() {
		if(self.i > self.max) {
			self.animating = false;
			return;
		}
		var newval = Tween.strongEaseOut(self.i, self.startpos, self.delta, self.max);
		self.update(newval);
		self.i++;
		setTimeout(self.fanimating, 10)
	}

	this.update = function(value) {
		self.obj.style.top = value + 'px';
	}
}

var Tween = new Object();
Tween.strongEaseOut = function(t,b,c,d) {
	return c*((t=t/d-1)*t*t*t*t + 1) + b;	
}	
Tween.backEaseOut = function(t,b,c,d) {
	return -c *(t/=d)*(t-2) + b;
}
