//=======================================================
// Stealthmenu v4.0
// A script by: Michael van Ouwerkerk - 13thparallel.org
//=======================================================

// Netscape 4 must reload on resize to restore the css.
if( document.layers && !document.getElementById ) {
	var winWidth = window.innerWidth;
	var winHeight = window.innerHeight;
	window.onresize = function() {
		if( winWidth != window.innerWidth || winHeight != window.innerHeight ) history.go( 0 );
	}
}

var Stealthmenu = {
	align : "center",				// Choose between "left" "center" and "right" for the alignment of the popups.
	solidWidth :  900,			// The non-liquid width of the page, in pixels.
	
	useFading : false,			// Use true for a fade-in effect (IE5/Win and all platforms Gecko engine) and false for no effect.
	fadeDuration : 250,			// The duration of the fade-in effect, in milliseconds.
	maxOpacity : 100,			// A number between 0 and 100. This is the percentage where the fade-in stops.
	fadeTimer : null,			// private variable
	fadeElm : null,				// private variable
	
	useOpenAnimation : false,	// Choose true to use an opening animation for the submenus, false for no effect.
	useCloseAnimation : false,	// Choose true to use a closing animation for the submenus, false for no effect.
	animDuration : 300,			// The duration of the animations in milliseconds.

	floaters : [ "select" ],	// An array of the windowed html elements to check for collision when popping up a submenu.
	
	showDelay : 200,			// The number of milliseconds to wait before showing the submenu.
	hideDelay : 200,			// The number of milliseconds to wait before hiding the submenu.
	sub : [],					// private variable
	lastSub : null,				// private variable
	zIndex : 100,				// private variable
	loaded : false,				// private variable
	
	init : function() {
		if( !this.loaded && (document.getElementById || document.all || document.layers) ) {
			var elm = true;
			var id = null;
			var i = 0;
			while( elm ) {	
				id = "divSub" + i;
				elm = document.getElementById ? document.getElementById( id ) : document.all ? document.all[ id ] : document.layers[ id ];
				if( elm ) {
					this.sub[ i ] = new this.makeSub( elm, i );
					if( this.useFading && elm.filters ) elm.style.filter = "progid:DXImageTransform.Microsoft.Alpha( Opacity=100, Style=0 )";
				}
				i++;
			}
			this.loaded = true;
		}
	},
	
	show : function( num ) {
		if( this.loaded && this.sub[ num ] ) {
			window.clearTimeout( this.sub[ num ].hideTimer );
			this.sub[ num ].showTimer = setTimeout( "Stealthmenu.doShow(" + num + ")" , Stealthmenu.showDelay );
		}
	},

	hide : function( num ) {
		if( this.loaded && this.sub[ num ] ) {
			window.clearTimeout( this.sub[ num ].showTimer );
			this.sub[ num ].hideTimer = setTimeout( "Stealthmenu.doHide(" + num + ")" , Stealthmenu.hideDelay );
		}
	},

	doShow : function( num ) {
		if( this.loaded && this.sub[ num ] ) {
			window.clearTimeout( this.sub[ num ].showTimer );
			if( this.lastSub != null ) {
				window.clearTimeout( this.sub[ this.lastSub ].hideTimer );
				if( this.lastSub != num ) this.doHide( this.lastSub );
			}
			this.lastSub = num;
			this.sub[ num ].css.zIndex = this.zIndex++;
			if( !this.sub[ num ].open ) {
				// Hide and refresh the submenu.
				this.sub[ num ].hide();
				if( this.useCloseAnimation ) this.sub[ num ].setClip( 0, this.sub[ num ].w, this.sub[ num ].h, 0 );
				this.positionSub( this.sub[ num ] );
				
				// Hide nasty elements.
				if( window.showModalDialog || window.opera ) {
					for( var i = 0; i < this.floaters.length; i++ ) {
						this.hideCollidingElements( this.sub[ num ].elm, this.floaters[ i ] );
					}
				}
				
				// Show the submenu.
				this.sub[ num ].open = true;
				var elm = this.sub[ num ].elm;
				if( this.useFading && elm.style && (typeof elm.style.MozOpacity != "undefined" || elm.filters) ) {
					this.fadeElm = elm;
					this.sub[ num ].show();
					this.doFade();
				}
				else if( this.useOpenAnimation ) this.sub[ num ].startSlide( true );
				else this.sub[ num ].show();
			}
			
			// Netscape 4 workaround, the conflicting timers must be stopped after a timeout.
			if( document.layers && !document.getElementById && this.lastSub != null ) {
				window.setTimeout( "window.clearTimeout( Stealthmenu.sub[ " + this.lastSub + " ].showTimer )", 10 );
				window.setTimeout( "window.clearTimeout( Stealthmenu.sub[ " + this.lastSub + " ].hideTimer )", 10 );
			}
		}
	},
	
	doHide : function( num ) {
		if( this.loaded && this.sub[ num ] ) {
			window.clearTimeout( this.sub[ num ].hideTimer );
			if( this.useCloseAnimation && this.sub[ num ].open ) {
				this.sub[ num ].startSlide( false );
			}
			else {
				this.sub[ num ].hide();
				this.sub[ num ].open = false;
			}
			
			clearTimeout( Stealthmenu.fadeTimer );
			this.fadeElm = null;
			
			this.doActions( num );
			if( window.showModalDialog || window.opera ) {
				for( var i = 0; i < this.floaters.length; i++ ) {
					this.showElements( this.floaters[ i ] );
				}
			}
		}
	},

	positionSub : function( sub ) {
		var viewport = this.getViewport();
		var setX = sub.originalX;
		var setY = sub.originalY;
		
		// Adjusting horizontal position if center or right aligned layout is used.
		if( viewport.width > this.solidWidth ) {
			if( this.align == "center" ) setX += ( viewport.width - this.solidWidth ) / 2;
			if( this.align == "right" ) setX += viewport.width - this.solidWidth;
		}

		// Make sure the submenu is placed inside the viewport.
		if( setX + sub.w > viewport.width + viewport.scrollX ) {
			setX = viewport.width + viewport.scrollX - sub.w;
		}
		if( setY + sub.h > viewport.height + viewport.scrollY ) {
			setY = viewport.height + viewport.scrollY - sub.h;
		}
		if( setX < viewport.scrollX ) setX = viewport.scrollX;
		if( setY < viewport.scrollY ) setY = viewport.scrollY;
		
		// Move the submenu.
		sub.moveTo( setX, setY );
	},	

	doFade : function( startTime ) {
		if( !startTime ) var startTime = new Date().valueOf();
		var fraction = (new Date().valueOf() - startTime) / this.fadeDuration;
		if( fraction >= 1 ) this.setOpacity( this.fadeElm, this.maxOpacity );
		else {
			var opacity = Math.round( fraction * this.maxOpacity );
			this.setOpacity( this.fadeElm, opacity );
			this.fadeTimer = setTimeout( "Stealthmenu.doFade(" + startTime + ")", 10 );
		}
	},
	
	setOpacity : function( elm, opacity ) {
		if( elm ) {
			if( typeof elm.style.MozOpacity != "undefined" ) elm.style.MozOpacity = opacity / 100;
			if( elm.filters && elm.filters[ "DXImageTransform.Microsoft.Alpha" ] ) {
				elm.filters[ "DXImageTransform.Microsoft.Alpha" ].opacity = opacity;
			}
		}
	},
	
	makeSub : function( elm, num ) {
		this.elm = elm;
		this.css = this.elm.style ? this.elm.style : this.elm;
		this.obj = elm.id + 'Obj';
		eval( this.obj + ' = this' );
		this.originalX = elm.offsetLeft ? elm.offsetLeft : elm.style && elm.style.left ? parseInt( elm.style.left ) : elm.left ? elm.left : 0;
		this.originalY = elm.offsetTop ? elm.offsetTop : elm.style && elm.style.top ? parseInt( elm.style.top ) : elm.top ? elm.top : 0;
		this.x = this.originalX;
		this.y = this.originalY;
		this.w = elm.offsetWidth ? elm.offsetWidth : elm.style && elm.style.width ? parseInt( elm.style.width ) : elm.clip && elm.clip.width ? elm.clip.width : 0;
		this.h = elm.offsetHeight ? elm.offsetHeight : elm.style && elm.style.height ? parseInt( elm.style.height ) : elm.clip && elm.clip.height ? elm.clip.height : 0;
		this.elm.onmouseout = function(){ Stealthmenu.hide( num ) };
		this.elm.onmouseover = function(){ window.clearTimeout( Stealthmenu.sub[ num ].hideTimer ) };
		this.hideTimer = null;
		this.showTimer = null;
		this.actionStorage = [];
		return this;
	},
	
	storeAction : function( num, strAction ) {
		var storage = this.sub[ num ].actionStorage;
		storage[ storage.length ] = strAction;
	},
	
	doActions : function( num ) {
		var storage = this.sub[ num ].actionStorage;
		while( storage.length ) {
			eval( storage[ storage.length - 1 ] );
			storage.length--;
		}
	},
	
	hideCollidingElements : function( elm, tagName ) {
		if( document.getElementsByTagName && elm.offsetWidth && elm.offsetHeight ) {;
			var elements = document.getElementsByTagName( tagName );
			var x = 0;
			var y = 0;
			for( var i = 0; i < elements.length; i++ ) {
				x = this.getPageLeft( elements[ i ] );
				y = this.getPageTop( elements[ i ] );
				if( x + elements[ i ].offsetWidth > elm.offsetLeft 
				&& x < elm.offsetLeft + elm.offsetWidth 
				&& y + elements[ i ].offsetHeight > elm.offsetTop 
				&& y < elm.offsetTop + elm.offsetHeight ) {
					elements[ i ].style.visibility = "hidden";
				}
			}
		}
	},
	
	showElements : function( tagName ) {
		if( document.getElementsByTagName ) {
			var floaters = document.getElementsByTagName( tagName );
			for( var i = 0; i < floaters.length; i++ ) {
				floaters[i].style.visibility = "visible";
			}
		}
	},
	
	getPageLeft : function( elm ) {
		var x = 0;
		while( elm.offsetParent && typeof elm.offsetLeft != "undefined" ) {
			x += elm.offsetLeft;
			elm = elm.offsetParent;
		}
		return x;
	},
	
	getPageTop : function( elm ) {
		var y = 0;
		while( elm.offsetParent && typeof elm.offsetTop != "undefined" ) {
			y += elm.offsetTop;
			elm = elm.offsetParent;
		}
		return y;
	},

	getViewport : function() {
		var viewport = { width: 0, height: 0, scrollX: 0, scrollY: 0 };
		
		// viewport width
		if( document.documentElement && document.documentElement.clientWidth ) viewport.width = document.documentElement.clientWidth;
		else if( document.body && document.body.clientWidth ) viewport.width = document.body.clientWidth;
		else if( window.innerWidth ) viewport.width = window.innerWidth - 18;
		
		// viewport height
		if( document.documentElement && document.documentElement.clientHeight ) viewport.height = document.documentElement.clientHeight;
		else if( document.body && document.body.clientHeight ) viewport.height = document.body.clientHeight;
		else if( window.innerHeight ) viewport.height = window.innerHeight - 18;
		
		// viewport scrollX
		if( document.documentElement && document.documentElement.scrollLeft ) viewport.scrollX = document.documentElement.scrollLeft;
		else if( document.body && document.body.scrollLeft ) viewport.scrollX = document.body.scrollLeft;
		else if( window.pageXOffset ) viewport.scrollX = window.pageXOffset;
		else if( window.scrollX ) viewport.scrollX = window.scrollX;
		
		// viewport scrollY
		if( document.documentElement && document.documentElement.scrollTop ) viewport.scrollY = document.documentElement.scrollTop;
		else if( document.body && document.body.scrollTop ) viewport.scrollY = document.body.scrollTop;
		else if( window.pageYOffset ) viewport.scrollY = window.pageYOffset;
		else if( window.scrollY ) viewport.scrollY = window.scrollY;
		
		return viewport;
	}
};

Stealthmenu.makeSub.prototype.show = function(){
	this.css.visibility = "visible";
};

Stealthmenu.makeSub.prototype.hide = function(){
	this.css.visibility = "hidden";
};

Stealthmenu.makeSub.prototype.moveTo = function( x, y ){
	if( x != null ) {
		this.x = x;
		this.css.left = this.elm.style ? x + "px" : x;
	}
	if( y != null ) {
		this.y = y;
		this.css.top = this.elm.style ? y + "px" : y;
	}
};

Stealthmenu.makeSub.prototype.getLeft = function() {
	var num = 0;
	if( this.elm.offsetLeft ) num = this.elm.offsetLeft;
	else if( this.elm.left ) num = this.elm.left;
	else if( this.elm.style && this.elm.style.left ) num = parseInt( this.elm.style.left );
	return num;
};

Stealthmenu.makeSub.prototype.getTop = function() {
	var num = 0;
	if( this.elm.offsetTop ) num = this.elm.offsetTop;
	else if( this.elm.top ) num = this.elm.top;
	else if( this.elm.style && this.elm.style.top ) num = parseInt( this.elm.style.top );
	return num;
};

Stealthmenu.makeSub.prototype.setClip = function( top, right, bottom, left ){
	if( this.elm.style ) {
		var clip = "rect(" + top + "px, " + right + "px, " + bottom + "px, " + left + "px)";
		this.elm.style.clip = clip;
	}
	else if( this.elm.clip ) {
		this.elm.clip.top = top;
		this.elm.clip.right = right;
		this.elm.clip.bottom = bottom;
		this.elm.clip.left = left;
	}
};

Stealthmenu.makeSub.prototype.startSlide = function( open ) {
	window.clearInterval( this.animTimer );
	this.open = open;
	this.accelConstant = this.w / Stealthmenu.animDuration / Stealthmenu.animDuration;
	this.startTime = new Date().getTime();	
	this.animTimer = window.setInterval( this.obj + ".slide()", 10 );
};

Stealthmenu.makeSub.prototype.slide = function() {
	if( this.css.visibility != "visible" ) this.show();
	var elapsed = new Date().getTime() - this.startTime;
	if( elapsed > Stealthmenu.animDuration ) this.endSlide();
	else {
		var distance = Math.pow( Stealthmenu.animDuration - elapsed, 2 ) * this.accelConstant;
		if( !this.open ) distance = this.w - distance;
		this.moveTo( this.originalX - distance, null );
		this.setClip( 0, this.w, this.h, distance );
	}
};

Stealthmenu.makeSub.prototype.endSlide = function() {
	window.clearInterval( this.animTimer );
	if( this.open ) {
		this.moveTo( this.originalX, null );
		this.setClip( 0, this.w, this.h, 0 );
	}
	else this.hide();
};

Stealthmenu.init();
// end