/*****************************************************
 * ypSlideOutMenu - heavily modified
 * 6/10/2001
 * 
 * a nice little script to create exclusive, slide-out
 * menus for standards compliant browsers.
 
 Updated to dynamically find menus instead of having them written out.  Adds additional code that it needs by itself, so no extra modifications to the HTML should be needed other then identifying the parent element of the menu with a "ypMenu" classname..  Also added the ability to pass additional paramaters via className if desired.
- Aaron Barker
 *
 * Licensed under AFL 2.0
 * http://www.opensource.org/licenses/afl-2.0.php
 *
 * Revised: 
 * - 08/29/2002 : added .hideAll()
 * - 04/15/2004 : added .writeCSS() to support more 
 *                than 30 menus.
 * - 06/10/2004 : major rewrire (AB)
 * 
 * --youngpup--
 
 *--------------------------------------------------*
 *  Updated to work with jQuery rather than Prototype.
 *  - Jon Cazier
 * 
 *  Fixed the ie8 rect(0,0,0,0) issue
 *  - Jon Cazier - 5.18.09
 *--------------------------------------------------*
 
 Available classname variables to pass:
 ypClick = change to onclick instead of onmouseover
 ypHo_(##) = Horizontal Offset
 ypVo_(##) = Vertical Offset
 ypPl_(tr|tl|br|bl) = Which corner to place the slideout at. (tr default)
 ypSf_(id name) = Start From... if you would like it to slide out from a different element
 ypDir_(down|up|left|right) = which way to slide?
 ypMi = Move Inside - For use when on the far right edge (or whenver you want).  Moves the slideout in the width of the slideout so it ends at the ypPl corner instead of starts there.
 *****************************************************/

ypSOM.r = [];
ypSOM.aniLen = 375;
ypSOM.hideDelay = 800;
ypSOM.minCPUResolution = 10;

// constructor
function ypSOM(id, dir, width, height)
{
		this.id			 = id;
		this.dir		 = dir;
		this.orientation = dir == "left" || dir == "right" ? "h" : "v";
		this.dirType	 = dir == "right" || dir == "down" ? "-" : "+";
		this.dim		 = this.orientation == "h" ? width : height;
		this.hideTimer	 = false;
		this.aniTimer	 = false;
		this.open		 = false;
		this.over		 = false;
		this.startTime	 = 0;

		// global reference to this object
		this.gRef = "ypSOM_"+id.replace(/\-/,"_"); // can't have "-" characters as they cause an equation, so replace with "_"
		eval(this.gRef+"=this");

		// add this menu object to an internal list of all menus
		ypSOM.r[id] = this;
		this.load();
};

ypSOM.prototype.load = function() {
	var d = document;
	var lyrId1 = this.id + "Container";
	var lyrId2 = this.id + "Content";
	var obj1 = d.getElementById(lyrId1);
	if (obj1) var obj2 = d.getElementById(lyrId2);
	var temp;

	if (!obj1 || !obj2){ window.setTimeout(this.gRef + ".load()", 100)}
	else {
		this.container	= obj1;
		this.menu		= obj2;
		this.style		= this.menu.style;
		this.homePos	= eval("0" + this.dirType + this.dim);
		this.outPos		= 0;
		this.accelConst	= (this.outPos - this.homePos) / ypSOM.aniLen / ypSOM.aniLen ;
		//set initial state
		this.endSlide();
	}
};
	
ypSOM.showMenu = function(id){
	placeMenu(document.getElementById(id));
	var reg = ypSOM.r;
	var obj = ypSOM.r[id];
	
	if (obj.container) {
		obj.over = true;

		// close other menus.
		for (var menu in reg) if (id != menu) ypSOM.hide(menu);
		//for (menu in reg) if (id != menu) ypSOM.hide(menu);

		// if this menu is scheduled to close, cancel it.
		if (obj.hideTimer) { reg[id].hideTimer = window.clearTimeout(reg[id].hideTimer); }

		// if this menu is closed, open it.
		if (!obj.open && !obj.aniTimer) reg[id].startSlide(true);
	}
};

ypSOM.hideMenu = function(id){
	// schedules the menu to close after <hideDelay> ms, which
	// gives the user time to cancel the action if they accidentally moused out
	var obj = ypSOM.r[id];
	if (obj.container) {
		if (obj.hideTimer) window.clearTimeout(obj.hideTimer);
		obj.hideTimer = window.setTimeout("ypSOM.hide('" + id + "')", ypSOM.hideDelay);
	}
};

ypSOM.hideAll = function(){
	var reg = ypSOM.r;
	for (var menu in reg) {
		ypSOM.hide(menu);
		if (menu.hideTimer) window.clearTimeout(menu.hideTimer);
	}
};

ypSOM.hide = function(id){
	var obj = ypSOM.r[id];
	obj.over = false;

	if (obj.hideTimer) window.clearTimeout(obj.hideTimer);
	
	// flag that this scheduled event has occured.
	obj.hideTimer = 0;

	// if this menu is open, close it.
	if (obj.open && !obj.aniTimer) obj.startSlide(false);
};

ypSOM.prototype.startSlide = function(open) {
	this[open ? "onactivate" : "ondeactivate"]();
	this.open = open;
	if (open) this.setVisibility(true);
	this.startTime = (new Date()).getTime();
	this.aniTimer = window.setInterval(this.gRef + ".slide()", ypSOM.minCPUResolution);
};

ypSOM.prototype.slide = function() {
	var elapsed = (new Date()).getTime() - this.startTime;
	if (elapsed > ypSOM.aniLen) this.endSlide();
	else {
		var d = Math.round(Math.pow(ypSOM.aniLen-elapsed, 2) * this.accelConst);
		if (this.open && this.dirType == "-")		d = -d;
		else if (this.open && this.dirType == "+")	d = -d;
		else if (!this.open && this.dirType == "-")	d = -this.dim + d;
		else										d = this.dim + d;

		this.moveTo(d);
	}
};

ypSOM.prototype.endSlide = function() {
	this.aniTimer = window.clearTimeout(this.aniTimer);
	this.moveTo(this.open ? this.outPos : this.homePos);
	if (!this.open){
		this.setVisibility(false);
	}
	if ((this.open && !this.over) || (!this.open && this.over)) {
		this.startSlide(this.over);
	}
};

ypSOM.prototype.setVisibility = function(bShow) { 
	var s = this.container.style;
	s.display = bShow ? "block" : "none";
};
ypSOM.prototype.moveTo = function(p) { 
	this.style[this.orientation == "h" ? "left" : "top"] = p + "px";
};
ypSOM.prototype.getPos = function(c) {
	return parseInt(this.style[c]);
};

// events
ypSOM.prototype.onactivate		= function() { };
ypSOM.prototype.ondeactivate	= function() { };


function findPosX(obj){
	var curleft = 0;
	if (obj.offsetParent){
		while (obj.offsetParent){
			curleft += obj.offsetLeft;
			obj = obj.offsetParent;
		}
	}
	return curleft;
};

function findPosY(obj){
	var curtop = 0;
	if (obj.offsetParent){
		while (obj.offsetParent){
			curtop += obj.offsetTop;
			obj = obj.offsetParent;
		}
	}
	return curtop;
};

function getStyle(oElm, strCssRule){
    var strValue = "";
    if(document.defaultView && document.defaultView.getComputedStyle){
        strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
    }
    else if(oElm.currentStyle){
        strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
            return p1.toUpperCase();
        });
        strValue = oElm.currentStyle[strCssRule];
    }
    return strValue;
}

function placeMenu(foo){
	sf = foo;
	//do we need to slide the menu from a different ID?
	ypSf = foo.className.match(/ypSf_([a-zA-Z0-9_\-]*)/); // sf = start from
	if(ypSf)sf = document.getElementById(ypSf[1]);
	
	//find position of sf element
	theY = findPosY(sf);
	theX = findPosX(sf);
	cn = foo;
	while(cn.parentNode){ // walk parent nodes looking for any 
		strValue = getStyle(cn, 'position');
		if (strValue=='relative' || strValue=='absolute'){
			theY = 0;
			theX = 0;
			break;
		}
		cn = cn.parentNode; // move up a node
	}
	
	//find outter slideout wrapper
	bar = document.getElementById(foo.id+"Container");
	bar.style.display = "block"; // needed so a h/w can be detected
	
	//find the offset
	vo = foo.className.match(/ypVo_([\-0-9]*)/); // vertical offset
	if(vo){vo=parseInt(vo[1]);} else {vo = 0;}
	ho = foo.className.match(/ypHo_([\-0-9]*)/); // horizontal offset
	if(ho){ho=parseInt(ho[1]);} else {ho = 0;}
	
	//find the placement
	thePl = foo.className.match(/ypPl_([tblr]*)/);
	if(thePl){thePl=thePl[1];}else{thePl='tr';}

	if(thePl.charAt(0) == "t")newTop = theY + vo; // from top
	if(thePl.charAt(0) == "b")newTop = theY + sf.offsetHeight+vo; // from bottom
	if(thePl.charAt(1) == "l")newLeft = theX + ho; // from left
	if(thePl.charAt(1) == "r")newLeft = theX + sf.offsetWidth+ho; // from right
	
	// if moveInside is "r" then the sliding layer needs to "end" at the above corner insted of start there
	if(foo.className.match(/ypMi/))newLeft = newLeft-bar.offsetWidth; 	
	//alert(bar.offsetWidth);
	if(thePl == "right"){
		bar.style.left = newLeft+"px";
		bar.style.top = newTop+"px";
	} else {
		bar.style.left = newLeft+"px";
		bar.style.top = newTop+"px";
	}
};

var curMenu, ypClick;
function delayOpen(foo){
	if(curMenu == foo)	ypSOM.showMenu(foo);
}

function delayClose(foo){
	if(curMenu != foo){
		ypSOM.hideMenu(foo);
		if(ypClick){
			ypOc = setTimeout("document.getElementById('"+foo+"').onmouseover = ''; ypClick = '';",250);
		};
		document.body.onmouseover = "";
	}
}

var ypOc;
function initSlides(foo){
	bar = foo.getElementsByTagName('ul')[0];	

	ypSt = foo.className.match(/ypSt_([a-zA-Z0-9_\-]*)/); // st = slide this
	if(ypSt)bar = document.getElementById(ypSt[1]);
	if(bar){
		if(!foo.id) foo.id = "ypMenu_"+(Math.round((Math.random()*1000)+1));
		
		if(foo.className.match(/ypClick/)){
			foo.onclick = function(){
				setTimeout("delayOpen('"+foo.id+"');",250);
				curMenu = foo.id;
				ypClick = 'true';
				foo.onmouseover = function(){
					if(ypOc){clearTimeout(ypOc);}
					if (ypSOM.r[foo.id].hideTimer) window.clearTimeout(ypSOM.r[foo.id].hideTimer);
					if(curMenu != foo.id){
						curMenu = foo.id;
					}
				};
				foo.onmouseout = function(){ ypOc = setTimeout("delayClose('"+foo.id+"');",500); curMenu = '';};
				//return false;
			};
		} else {
			addEvent(foo, 'mouseover', killBubble);
			foo.onmouseover = function(){
				killBubble;
				setTimeout("delayOpen('"+foo.id+"');",250);  curMenu = foo.id;
				document.body.onmouseover = function(){ setTimeout("delayClose('"+foo.id+"');",100); curMenu = '';};

			};
			//foo.onmouseout = function(){ setTimeout("delayClose('"+foo.id+"');",100); curMenu = '';};
		}

	
		// set height/width	
		theW = bar.offsetWidth;
		theH = bar.offsetHeight;
		
		// lets find the direction we want to go
		theDir = foo.className.match(/ypDir_(down|up|left|right)/);
		if(theDir){theDir=theDir[1];}else{theDir='down';}
		var blah = new ypSOM(foo.id, theDir, theW, theH);
		blah.onactivate = new Function("document.getElementById('" + foo.id + "').className +=' ypActive';");
		blah.ondeactivate = new Function("var a = document.getElementById('" + foo.id + "'); a.className = a.className.replace(/ ypActive/i,'');");
		
	
		// add two container divs
		// create outter wrapper
		var o = document.createElement('DIV');
		o.id = foo.id+'Container';
		o.style.position = "absolute";
		o.className = 'ypContainer';
		o.style.left = "0";
		o.style.height = theH+"px";
		o.style.width = theW+"px";
		o.style.clip = 'rect(0px, ' + theW + "px," + ' ' + theH + "px," + ' 0px)';
	
		o.style.overflow = "hidden";
		o.style.zIndex = "1000000";
		o.style.textAlign = "left";
	
			
		// create inner wrapper
		var i = document.createElement('DIV');	
		i.id = foo.id+'Content';
		
		i.style.height = theH+"px";
		i.style.width = theW+"px";
		i.style.clip = 'rect(0px, ' + theW + "px," + ' ' + theH + "px," + ' 0px)';
		i.style.position = "absolute";
		i.style.clear = 'both';
		i.style.overflow = 'hidden';
		// move it into the inner wrapper
		i.appendChild(bar);
		o.appendChild(i);
		foo.appendChild(o);
	
		o.style.display = "none"; // must be done AFTER all the appending
		
		/*if(bClassChanged == true){
			// closing the nav if we opened it before
			//alert(bClass);
			document.body.className = document.body.className.replace(/navOpen/,"navClosed");

		}*/
		
		// stop clicks on links inside the sliding element from bubbling up and firing other functions (such as toggleNav)
		theAs = bar.getElementsByTagName('a');
		for(var x=0; x<theAs.length; x++){
			addEvent(theAs[x], 'click', killBubble);
			//theAs[x].onclick = function(){ theAs[x].onclick; killBubble; }
		}
		bar.className = bar.className.replace(/yp_theMenu/,''); // remove the class that hides the menus initially
		return true;
	} else {
		return false;
	}
};

function killBubble(e){
	if (!e) var e = window.event;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
};

var doInit;
function setMenus(){
//	return;
	// use your gatherer of choice, like the jQuery class selector, to get 
	menuArray = $('.ypMenu');
	var menus2 = new Array();
	for(var x=0; x<menuArray.length; x++){
		var foo2 = menuArray[x];
		if(!doInit){
			initSlides(foo2);
		}
	}
	doInit = true;
};

//d = document;
ndc = new Array();
coc = new Array();
kg = true;
function zelph_onDOMload(dtw,ctr){
	es = $('".'+dtw+'"'); // get all elements that match what we are looking for
	var doTo = new Array();
	for(var x = 0; x< es.length; x++){
		if(es[x].className.indexOf('odmdone') == '-1'){
			doTo.push(es[x]);
		}
	}
	
	if(coc[dtw] == null){
		coc[dtw] = "zelph_onDOMload('" + dtw + "', '" + ctr + "')"; // copy off the code
	}
	
	if(doTo){ // if available elments then lets do them
		nes = es.length;
		for(var x=0; x<doTo.length; x++){ // loop through all elements that have not been done yet
			// do what we need to do
			theTarget = doTo[x];
			var res = eval(ctr);
			if(res) doTo[x].className = doTo[x].className+' odmdone';
		}
	}
	
	if(kg == true){
		// play it again sam
		setTimeout("zelph_onDOMload('" + dtw + "', '" + ctr + "')", 200);
	}
	return true;
}


//zelph_onDOMload('ypMenu', 'initSlides(theTarget)')


function zelph_stopIt(){
	kg = ""; // stop the flash loop
	for(x=0; x<coc.length; x++){ // one last check of each script
		eval(coc[x]);
	}
}

// not needed if you already have your own onload function or if you just want to use onload.  Just call the "zelph_stopIt" function however you want to.

/*
addEvent function found at http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html
*/
function addEvent( obj, type, fn )
{
	if (obj.addEventListener)
		obj.addEventListener( type, fn, false );
	else if (obj.attachEvent)
	{
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
		obj.attachEvent( "on"+type, obj[type+fn] );
	}
}
function removeEvent( obj, type, fn )
{
	if (obj.removeEventListener)
		obj.removeEventListener( type, fn, false );
	else if (obj.detachEvent)
	{
		obj.detachEvent( "on"+type, obj[type+fn] );
		obj[type+fn] = null;
		obj["e"+type+fn] = null;
	}
}
addEvent(window, 'load', zelph_stopIt); 