/**
 * jjjMenu -beta
 * @version 1.2
 * @author Jason John Jaeger
 * last modified May 28th 2007
 * 
 * 
 * ---<[ changeLog ]>---
 * May 28th 2007:
 * 		Added getOrSetId function which will assign a random but meaninful id to any object that does not have an id
 * 		Added getHighestZindex function to find the highest zIndex of any element on a page
 * 		Added zIndex as one of the attributes that fethThing retrieves
 * 		Set zIndex of any subMenu being shown to be on top		
 * 		Made createLiveLog function so that the livelog div is inserted into the page programmatically to make it easier to debug jjjMenu with any design
 * 		Added debug option which will show the liveLog when set to true
 * 		Added slideOut and slideIn functions (mostly from my old MegaMenu)
 * 		Improved interruptability of all slide transitions
 * 
 * May 12th 2007:
 * 		Added slideDown and slideDown_slider functions (mostly from my old MegaMenu)
 * May 7th 2007:
 * 		Made it so that the main shadow div is inserted via javascipt
 * May 6th 2007: 
 * 		Created initMenu function to set submenu maxOpacity, fix button widths, and create submenu dropshadows
 * 		Made it so that the inner shadow divs are inserted via javascript
 * May 5th 2007: 
 * 		Added shadowOpacity option
 * 		Changed the way the drop shadows work. (changed the whole structure of it to use pure css and no tables)
 * 		Removed options.shadowDistanceX and options.shadowDistanceY
 * April 21st 2007: Added function to make all subMenu buttons in a given sub menu as wide as the widest one in Firefox in OSX
 */

var options = Array();
options.hideDelay = 250;//<--delay before subMenus disappear after you take mouse off of them (in milliseconds, 500 == half second)
options.vertOffset = 0;
options.initalSubMenuXoffset = 0;
options.initalSubMenuYoffset = -22;
options.subsequentSubMenuXoffset = 0;
options.maxOpacity = 98;
options.shadow = true;
options.shadowOpacity = 40;
options.transitions = Array();
options.transitions.slide = true;
options.slideSpeed = 15;//<-- bigger number == slower
options.increment = 5;//helps determine speed of wipe transitions. A smaller number will look choppier in ie and slower computers but smoother on faster computers and in browsers that process it better like firefox and opera.
options.debug = false;
options.topZ = 0;

//~~~~No Need to Edit below this line :)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if(is_safari){options.transitions.slide = false; options.shadow = false;}//<-- shadows and slide transitions don't work right in safari for now
if(is_opera){options.shadow = false;}//<-- shadows transitions don't work right in opera for now

var timeOuts = Array();
var vCorrect = Array();
var hCorrect = Array();
var slideDown_slider_timeOuts = Array();
var slideUp_timeOuts = Array();
var slideUp_slider_timeOuts = Array();
var hideOuterWrapper_timeOuts = Array();
var slideOut_slider_timeOuts = Array();
var slideIn_timeOuts = Array();
var slideIn_slider_timeOuts = Array();

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function call_slideUp(id, millisec){
	if(options.transitions.slide === true){
		if(slideUp_timeOuts[id]){clearTimeout(slideUp_timeOuts[id]);}//end if
		slideUp_timeOuts[id] = setTimeout('slideUp("'+id+'")',options.hideDelay);
	}//end if
}//function

function cancell_slideUp(id){
	if(hideOuterWrapper_timeOuts[id]){clearTimeout(hideOuterWrapper_timeOuts[id]);}
	if(slideUp_timeOuts[id]){clearTimeout(slideUp_timeOuts[id]);}//end if
	if(slideUp_slider_timeOuts[id]){clearTimeout(slideUp_slider_timeOuts[id]);}//end if
	
}//end function

function slideUp(id) {
	if(options.transitions.slide === true){
		var timer = 0;
		var obj = xDOM(id);		
		//cancell_hideMe(id);
		//if(slideUp_slider_timeOuts[id]){ clearTimeout(slideUp_slider_timeOuts[id]);	}//end if
		cancell_slideUp(id);
		cancell_slideDown(id);
		
		var height = findObjHeight(obj);
		
		//-------------------------------------------
		var startY = findPosY(obj)-vCorrect[id];
		
		var endY = -height;
		//-------------------------------------------
			
			
		if(startY >= endY ){	
			for(i = startY; i >= (endY-options.increment); i=i-options.increment) {
				slideUp_slider_timeOuts[id] = setTimeout("slideUp_slider(" + i + ",'" + id + "','" + endY + "')",(timer * options.slideSpeed));
				
				if(i <= endY+options.increment ){
					//alert('ow-'+ getIdNumber(id) );
					cancell_slideUp(id);
					hideOuterWrapper_timeOuts[id] = setTimeout("hideOuterWrapper('ow-" + getIdNumber(id) + "')",(timer * options.slideSpeed));
				
				}
				timer++;
				
			}//end for
		}//end if 
	}//end if
}//end function

function slideUp_slider(Y, id, endY) {
	//alert(id+'is being slid up');
	var obj = xDOM(id);
	obj.style.top = Y+'px';
	//obj.style.visibility = 'visible';
	//showShadow(id);
}//end function

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

function cancell_slideDown(id){
	
	//if(slideDown_timeOuts[id]){clearTimeout(slideDown_timeOuts[id]);}//end if
	if(slideDown_slider_timeOuts[id]){clearTimeout(slideDown_slider_timeOuts[id]);}//end if
	//alert(id);
}//end function

function slideDown(id){
	


	//alert(id);
	if(options.transitions.slide === true){
		if(slideDown_slider_timeOuts[id]){
			//return;
			//clearTimeout(slideDown_slider_timeOuts[id]);
		}//end if
//cancell_slideUp(thing);

//~~~~~~~~

var owObj = xDOM('ow-'+getIdNumber(id)) ;
owObj.style.visibility = 'visible';
//~~~~~~~~

		var timer = 0;
		
		var obj = xDOM(id);
		var height = findObjHeight(obj);
		
		if (!vCorrect[id]){ 
			//alert('test');
			obj.style.top = 0+'px';
			vCorrect[id] = findPosY(obj);
			obj.style.top = -height+'px';
			
		}//end if
		
		//obj.style.top = findPosY(obj)-vCorrect[id];
		
		//-------------------------------------------
		var startY = findPosY(obj)-vCorrect[id];
		//var startY = -height;
		var endY = 0;
		//-------------------------------------------
		//alert('startY = '+startY+' || endY = '+endY);
		if(startY < endY ){
			
			for(i = startY; i <= endY; i=i+options.increment) {
				//alert(i);
				cancell_slideUp(id);
				slideDown_slider_timeOuts[id] = setTimeout("slideDown_slider(" + i + ",'" + id + "','" + endY + "')",(timer * options.slideSpeed));
				timer++;
			}//end for
		}else{
			//alert('beep');
			var obj = xDOM(id);
			obj.style.top = endY+'px';
			var owObj = xDOM('ow-'+getIdNumber(id)) ;
			owObj.style.visibility = 'visible';
			cancell_slideUp(id);
			cancell_slideDown(id);
			
		}//end if */
	}//end if
}

function slideDown_slider(Y, id, endY) {
	
	
	var obj = xDOM(id);
	obj.style.top = Y+'px';

	if(Y >= (endY - options.increment)){
		obj.style.top = endY+'px';
		//showShadow(id);
	}//end if
}//end function

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


function slideOut(id){
	//alert(id);
	if(options.transitions.slide === true){
		if(slideOut_slider_timeOuts[id]){
			//return;
			//clearTimeout(slideDown_slider_timeOuts[id]);
		}//end if
cancell_slideIn(id);
		var timer = 0;
		
		var obj = xDOM(id);
		var width = findObjWidth(obj);
		
		if (!hCorrect[id]){ 
			//alert('test');
			obj.style.left = 0+'px';
			hCorrect[id] = findPosX(obj);
			obj.style.left = -width+'px';
			
		}//end if
		
		obj.style.left = findPosX(obj)-hCorrect[id];
		
		//-------------------------------------------
		var startX = findPosX(obj)-hCorrect[id];
		var endX = 0;
		//-------------------------------------------
		//alert('startY = '+startY+' || endY = '+endY);
		if(startX < endX ){
			
			for(i = startX; i <= endX; i=i+options.increment) {
				//alert(i);
				slideOut_slider_timeOuts[id] = setTimeout("slideOut_slider(" + i + ",'" + id + "','" + endX + "')",(timer * (options.slideSpeed/2)));
				timer++;
			}//end for
		}else{
			//alert('beep 2');
			
			var obj = xDOM(id);
			obj.style.left = endX+'px';
			var owObj = xDOM('ow-'+getIdNumber(id)) ;
			owObj.style.visibility = 'visible';
			cancell_slideIn(id);
			cancell_slideOut(id);
			
		}//end if */
	}//end if
}

function slideOut_slider(X, id, endX) {
	var obj = xDOM(id);
	obj.style.left = X+'px';

	if(X >= (endX - options.increment)){
		obj.style.left = endX+'px';
		//showShadow(id);
	}//end if
}//end function

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

function call_slideIn(id){
	if(options.transitions.slide === true){
		if(slideIn_timeOuts[id]){clearTimeout(slideIn_timeOuts[id]);}//end if
		slideIn_timeOuts[id] = setTimeout('slideIn("'+id+'")',options.hideDelay);
	}//end if
}//function

function cancell_slideIn(id){
	if(hideOuterWrapper_timeOuts[id]){clearTimeout(hideOuterWrapper_timeOuts[id]);}
	if(slideIn_timeOuts[id]){clearTimeout(slideIn_timeOuts[id]);}//end if
	if(slideIn_slider_timeOuts[id]){clearTimeout(slideIn_slider_timeOuts[id]);}//end if
}//end function

function slideIn(id) {
	if(options.transitions.slide === true){
		var timer = 0;
		var obj = xDOM(id);		
		//cancell_hideMe(id);
		if(slideIn_slider_timeOuts[id]){ clearTimeout(slideIn_slider_timeOuts[id]);	}//end if
		var width = findObjWidth(obj);
		
		//-------------------------------------------
		var startX = findPosX(obj);
		if(hCorrect[id]){startX = startX-hCorrect[id];}
		var endX = -width;
		//-------------------------------------------
			
			
		if(startX >= endX ){	
			for(i = startX; i >= (endX-options.increment); i=i-options.increment) {
				slideIn_slider_timeOuts[id] = setTimeout("slideIn_slider(" + i + ",'" + id + "','" + endX + "')",(timer * options.slideSpeed));
				
				if(i <= endX+options.increment ){
					//alert('ow-'+ getIdNumber(id) );
					cancell_slideIn(id);
					hideOuterWrapper_timeOuts[id] = setTimeout("hideOuterWrapper('ow-" + getIdNumber(id) + "')",(timer * options.slideSpeed));
				
				}
				timer++;
				
			}//end for
		}//end if 
	}//end if
}//end function

function slideIn_slider(X, id, endX) {
	//alert(id+'is being slid up');
	var obj = xDOM(id);
	obj.style.left = X+'px';
	//obj.style.visibility = 'visible';
	//showShadow(id);
}//end function

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


function smShow(idNumber, mySMid){

//alert('idNumber = '+idNumber+' | mySubMenuId = '+mySMid);
	
	fixBtnWidths(idNumber);
	//setShadow(idNumber);
	
	var btnId = "b-" + idNumber;
	//var btnObj = getObject(btnId);
	var btnObj = xDOM(btnId);
	var btnClass = btnObj.className;
	
	var owObj = xDOM('ow-'+idNumber);
	//options.topZ = options.topZ+2;
	//owObj.style.zIndex = options.topZ;
	
	//owObj.style.zIndex = 1;
	
	if(btnClass == "mButtonParent" || btnClass == "mButtonParentOver"){
		
		//setClass(btnId, "mButtonParentOver");
		cancell_hideAllSubMenus();
		hideTheChildren('ow-'+idNumber);
		hideAllSubMenus('ow-'+idNumber);
		smShowInitial(idNumber,btnId);
		//when there are transitions, they will be triggered here
	}else if(btnClass == "smButtonParent" || btnClass == "smButtonParentOver"){
		
		if(btnClass == "smButtonParent" && mySMid){hideTheChildren(mySMid);}
		smShowSubsequent(idNumber,btnId);
		//alert('smButtonParent');
		setClass(btnId, "smButtonParentOver");
		//when there are transitions, they will be triggered here
		
	}
	
	
}
var btnWidthsAreFixed = Array();
function fixBtnWidths(idNumber){
	//this function makes the widths of all buttons in a sub menu as wide as the widest one
	//so far as I know this is only needed for Firefox in OSX
	
	var soWrapperId = "ow-" + idNumber;
	if(!btnWidthsAreFixed[soWrapperId]  ){
		var soWrapper = fetchThing(soWrapperId);
		var soWrapperObj = soWrapper.obj;
		var widest = 0;
		var btnArray = getElementsByClassName(soWrapperObj,"a","smButton");
		for(var i=0; i< btnArray.length; i++){
			var width = findObjWidth(btnArray[i]);
			if(width > widest){widest = width;}
		}
		var parentBtnArray = getElementsByClassName(soWrapperObj,"a","smButtonParent");
		for(var i=0; i< parentBtnArray.length; i++){
			var width = findObjWidth(parentBtnArray[i]);
			if(width > widest){widest = width;}
		}
	
		var btnPaddingWidth = 0;
		var btnBorderWidth = 0;
		//if(parentBtnArray.length + btnArray.length >1){
			for(var i=0; i< btnArray.length; i++){	
				btnArray[i].style.width = widest+'px';
				var btn = fetchThing(btnArray[i].id);
				btnPaddingWidth = btn.paddingWidth;
				btnBorderWidth = btn.borderWidth;
				
			}
			if(parentBtnArray.length >0){
				for(var i=0; i< parentBtnArray.length; i++){ 
					parentBtnArray[i].style.width = widest+'px';	
					var pBtn = fetchThing(parentBtnArray[i].id);
					btnPaddingWidth = pBtn.paddingWidth;
					btnBorderWidth = pBtn.borderWidth;
				}
			}
			var sMenu = fetchThing('sm-'+idNumber);
			var newWidth = widest+btnPaddingWidth+sMenu.borderWidth+soWrapper.borderWidth;
			soWrapperObj.style.width = newWidth+'px';
		//}
		btnWidthsAreFixed[soWrapperId]= true;
		
	}
}

function initMenu(){
	
	setOpacity();
	
	var owArray = getElementsByClassName(document, "div", "soWrapper");
	for(var i=0; i<owArray.length; i++){ 
		var idArr = owArray[i].id.split("-");
		var idNumber = idArr[idArr.length-1];
		//alert(idNumber);
		fixBtnWidths(idNumber);
		//setShadow(idNumber);
	}
	
	hideAllSubMenus();
	
	createLiveLog();	
	//options.topZ = getHighestZindex();
	
	
	
}



function createLiveLog(){
	if(options.debug){
		var liveLogDivOW = document.createElement('div');
		liveLogDivOW.setAttribute('id', "liveLogOW");
		document.body.appendChild(liveLogDivOW);
		var lldowObj = xDOM('liveLogOW'); 
		var liveLogDiv = document.createElement('div');
		liveLogDiv.setAttribute('id', "liveLog");
		lldowObj.appendChild(liveLogDiv);
	}
}

function getHighestZindex(){
	var highestIndex = 0;
	var elementArr = getElementsByClassName(document, "*", "*");
	for(var i=0; i<elementArr.length; i++){
		var layer = 0;
		var id = getOrSetId(elementArr[i]);
		layer = fetchStyle(id,'z-index',true); 
		if(layer > highestIndex){ 
			highestIndex = layer;	
			//liveLog(elementArr[i].id+'  |  '+layer+'  |  ');
		}	
	}
	//liveLog('highest index = '+highestIndex);
	return(highestIndex);
}

 function setOpacity(){
 	if(is_ie && is_major < 7 && options.shadow){ options.maxOpacity = options.maxOpacity-10;}
	var btnArray = getElementsByClassName(document, "a", "smButton");
	for(var i=0; i<btnArray.length; i++){ changeOpac(options.maxOpacity,btnArray[i].id); }
	var pBtnArray = getElementsByClassName(document, "a", "smButtonParent");
	for(var i=0; i<pBtnArray.length; i++){ changeOpac(options.maxOpacity,pBtnArray[i].id); }
 }
function aTest(style){
	/*var styleArr = style.split("-");
	var newString = "";
	for(x in styleArr){
		newString = newString + styleArr[x].replace(styleArr[x].charAt(0), styleArr[x].charAt(0).toUpperCase() );
	}
	alert(newString);*/
	
}
 function smbOver(smId){
 	hideTheChildren(smId);
	//liveLog('you just hovered over a not parent button');
 }
 
 function hideTheChildren(smId){
 	notOver(smId);
 	//var smObj = getObject(smId);	
	var smObj = xDOM(smId);
 	var parentBtnArray = getElementsByClassName(smObj, "a", "smButtonParent");
	for(var i=0; i<parentBtnArray.length; i++){
		var menuId = "ow-" + getIdNumber(parentBtnArray[i].id);
		//liveLog('hideTheChildred just ran on:'+menuId);
		notOver(menuId);
		//when there are transitions, they will be called here and the hideMenu function will be called at the end of them
		hideMenu(menuId);
		hideTheChildren(menuId);
	}
 }
 var shadowSized = Array();
 function setShadow(idNumber){
 	if(options.shadow && !shadowSized[idNumber]){
		
		
		
		//create shadow div
		var sMenuIW_Obj = xDOM("iw-"+idNumber);
		var shadowDiv = document.createElement('div');
		shadowDiv.setAttribute('id', "shadow-" + idNumber);
		shadowDiv.setAttribute('class', "shadow");
		sMenuIW_Obj.appendChild(shadowDiv);//<--adds shadow inside innerWrappper AFTER sMenu div
		//----------------
		
		var sMenu = fetchThing("sm-" + idNumber);
		var shadow = fetchThing("shadow-" + idNumber);
		
		
		shadow.obj.style.width = sMenu.width+'px';
		shadow.obj.style.height = sMenu.height+'px';
		
		
		if(is_ie ){
			
			if(options.shadowOpacity){
				var ieOpacity = (options.shadowOpacity -25)/100;
				shadow.obj.style.backgroundColor = "white";
				shadow.obj.style.filter= "progid:DXImageTransform.Microsoft.blur(pixelradius=2.2, makeshadow='true', ShadowOpacity="+ ieOpacity +")";
				shadow.obj.style.position = "absolute";
				shadow.obj.style.top="0px";
			}

		}else{
			
					
			shadow.obj.innerHTML =  '<div class="shadow_trc" id="trc-'+ idNumber +'" ></div>'+
									'<div class="shadow_rm" id="rm-'+ idNumber +'" ></div>'+
									'<div class="shadow_brc" id="brc-'+ idNumber +'" ></div>'+
									'<div class="shadow_bm" id="bm-'+ idNumber +'" ></div>'+
									'<div class="shadow_blc" id="blc-'+ idNumber +'" ></div>';
								
			var trc = fetchThing("trc-" + idNumber);
			var rm = fetchThing("rm-" + idNumber);
			var brc = fetchThing("brc-" + idNumber);
			var bm = fetchThing("bm-" + idNumber);
			var blc = fetchThing("blc-" + idNumber);
			
			var newHeight = sMenu.height - trc.height;
			var newWidth = sMenu.width - blc.width - brc.width;
			
			
			rm.obj.style.height = newHeight +'px';
			rm.obj.style.top = trc.height+'px'; 
			bm.obj.style.width =  newWidth+'px';
			bm.obj.style.left = blc.width + brc.width +'px';
			
			
			if(options.shadowOpacity){ 	changeOpac(options.shadowOpacity,shadow.id); }
			
		}
		//shadow.obj.style.border = "1px dotted orange";
		
	}
 }
 
 var spacerAdded = Array();
 
 function smShowInitial(idNumber, btnId){
 	//alert('btnId = '+btnId+' | idNumber = '+idNumber);
	//var btnObj = getObject(btnId);
	
	//fixBtnWidths(idNumber);
	
	if(!spacerAdded[idNumber]){
		var sMenuObj = xDOM('sm-'+idNumber);
		sMenuObj.innerHTML = "<div class='menuSpacer'></div>" + sMenuObj.innerHTML;
		spacerAdded[idNumber] = true;
		setShadow(idNumber);
	}
	
	
	
	var btnObj = xDOM(btnId);
	var btnLeft = findPosX(btnObj);
	var btnTop = findPosY(btnObj);
	var btnHeight = findObjHeight(btnObj);
	var soWrapperId = "ow-" + idNumber;
	// soWrapperObj = getObject(soWrapperId);
	var soWrapperObj = xDOM(soWrapperId);
	var vertOffset = 0;
	if(options.vertOffset && isNaN(options.vertOffset) === false){ vertOffset = options.vertOffset;	}
	if(is_ie){
		//vertOffset = vertOffset +35;
		//vertOffset = 0;
	}
	
	if(is_ie && is_major > 6){
		//btnTop = (btnTop/2) + 77;
	}
	
	var newTop = btnTop + btnHeight + vertOffset + options.initalSubMenuYoffset
	
	
	if(is_gecko){
		//options.initalSubMenuXoffset = -98;
	}
	
	
	soWrapperObj.style.left = btnLeft+ options.initalSubMenuXoffset +'px';
	soWrapperObj.style.top = newTop+'px';
	soWrapperObj.style.visibility = "visible";
	slideDown("iw-"+idNumber);
		
	
}
 
 var sizeSet = Array();
 function smShowSubsequent(idNumber, btnId){
	
	//fixBtnWidths(idNumber);
	//alert('idNumber= '+idNumber+' | btnId= '+btnId);
 	var btn = fetchThing(btnId);
	var sow = fetchThing(("ow-" + idNumber));
	if(!sizeSet[sow.id]){
		// this is done so the sub menus don't get squished since they are elasticy via css to expand for inner content
		sow.obj.style.width = sow.width+'px';
		sizeSet[sow.id] = true;
	}
	//if(is_gecko){options.subsequentSubMenuXoffset = 1;}
	var newLeft = btn.right+options.subsequentSubMenuXoffset;
	if((btn.right + sow.width) > posRight()){
		//if the subsequent submenu would go off the right edge, appear on the other side of the parent submenu		
		
		newLeft = btn.left - sow.width + sow.paddingRight;
	}
	var newTop = btn.top;
	if(btn.top + sow.height > posBottom()){
		//if the subsequent submenu would go off the bottom edge, appear above the parent submenu btn
		newTop = btn.bottom - sow.height + sow.paddingBottom + sow.borderHeight + options.subsequentSubMenuYoffset;
	}
	
	
	//alert(newLeft);
	
	if(is_safari){newLeft = newLeft-5;}
	
	sow.obj.style.left = newLeft+'px';
	sow.obj.style.top = newTop+'px';
	sow.obj.style.visibility = "visible";
	
	//slideDown("iw-"+idNumber);
	slideOut("iw-"+idNumber);
	
 }
 
 function smHide(idNumber){
 	call_hideAllSubMenus();
	//alert(idNumber);
	//Note to self: see what is calling this function and why
 }
 
 function overSOwrapper(idNumber){
 	cancell_hideAllSubMenus();
	
	/*var owObj = xDOM("ow-"+idNumber);
	var topZ = getHighestZindex();
	owObj.style.zIndex = topZ++;*/
	
	if(options.transitions.slide ){
		/*
		cancell_slideIn('iw-'+idNumber);
		cancell_slideOut('iw-'+idNumber);
		cancell_slideUp('iw-'+idNumber);
		cancell_slideOut('iw-'+idNumber);
		var obj = xDOM("iw-"+idNumber);
		obj.style.visibility = "visible";
		obj.style.top = 0+'px';
		obj.style.left = 0+'px';
		*/
	}
	
 }
 
 
 function outSOwrapper(){
	call_hideAllSubMenus();
 }
 
function call_hideAllSubMenus(){
	cancell_hideAllSubMenus();
	timeOuts.hideAllSubMenus = setTimeout('hideAllSubMenus()',options.hideDelay);
	//liveLog('<b>hideAllSubMenus <span style="color:green;">called</span></b>');
}//end function

function cancell_hideAllSubMenus(){
	if(timeOuts.hideAllSubMenus){
		clearTimeout(timeOuts.hideAllSubMenus);
		//liveLog('<b>hideAllSubMenus <span style="color:red;">cancelled</span></b>');
	}//end if
}//end function

function hideAllSubMenus(exceptThisId){
	var smArray = getElementsByClassName(document, "div", "soWrapper");
	for(var i=0; i<smArray.length; i++){
		notOver(smArray[i].id, exceptThisId);
		if(exceptThisId != smArray[i].id){
			hideMenu(smArray[i].id);	
		}
		
		//when there are transitions, they will be called here and the hideMenu function will be called at the end of them
	}//end for
	
	notOver('mw', exceptThisId);//<-- main menu
	clearTimeout(timeOuts.hideAllSubMenus);
}//end function

function hideMenu(menuId){
	//alert(menuId);
	
	if(options.transitions.slide){
		var menuBtn = xDOM("b-"+getIdNumber(menuId));
		if(!menuBtn){return;}
		//alert(menuBtn.className);
		if(menuBtn.className == "mButtonParent" || menuBtn.className == "mButtonParentOver"){
			//alert(menuId+" is a initial submenu");
			slideUp('iw-'+ getIdNumber(menuId));
		}else if(menuBtn.className == "smButtonParent" || menuBtn.className == "smButtonParentOver"){
			//alert(menuId+" is NOT a initial submenu");
			slideIn('iw-'+ getIdNumber(menuId));
		}else{
			//alert(menuId+" beep 1");
			//hideOuterWrapper(menuId);
		}
	}else{
		hideOuterWrapper(menuId);
	}
	
	
}

function hideOuterWrapper(menuId){
	//alert(menuId);
	
	if(!slideDown_slider_timeOuts["iw-"+menuId]){

	
		var menuObj = xDOM(menuId);
		//liveLog('hideMenu just ran on:'+menuObj+" || "+menuId);
		menuObj.style.visibility = "hidden";
		var smHeight = findObjHeight(menuObj);
		menuObj.style.top = "-" + smHeight + "px";
	
	}
	
	
}

function getIdNumber(id){
	var idArray = id.split("-");
	var idNumber = idArray[idArray.length-1];
	return idNumber;	
}

function getOrSetId(obj){
	if(!obj.id){
		var d = new Date();
		var milli = d.getMilliseconds().toString();
		var randomNumber = Math.floor(Math.random()*1000);
		obj.id = obj.nodeName.toString() + '-' + milli + randomNumber.toString();
		//liveLog(obj.id);
	}
	return obj.id;
}

function notOver(menuId, exceptThisMenuId){
	var exceptThisId = null;
	if(exceptThisMenuId){ 
		exceptThisId = 'b-'+ getIdNumber(exceptThisMenuId);
	}
	//var menuObj = getObject(menuId);
	var menuObj = xDOM(menuId);
	var mButtonParentOverArray = getElementsByClassName(menuObj, "td", "mButtonParentOver");
	for(var i=0; i<mButtonParentOverArray.length; i++){
		//alert(mButtonParentOverArray[i].id+' | '+exceptThisId);
		if(exceptThisId != mButtonParentOverArray[i].id ){
			setClass(mButtonParentOverArray[i].id, 'mButtonParent');
		}
	}//end for
	var smButtonParentOverArray = getElementsByClassName(menuObj, "a", "smButtonParentOver");
	for(var i=0; i<smButtonParentOverArray.length; i++){
		if(exceptThisId != smButtonParentOverArray[i].id){
			setClass(smButtonParentOverArray[i].id, 'smButtonParent');
		}
	}//end for
}
 

function liveLog(message){
	if(options.debug){
		//var liveLogObj = getObject('liveLog');
		var liveLogObj = xDOM('liveLog');
		var currentContent = liveLogObj.innerHTML;
		liveLogObj.innerHTML = message.toString()+" --> "+Date().toString()+'<br />'+currentContent;
	}
}//end function

function createLiveLog(){
	if(options.debug){
		var liveLogDivOW = document.createElement('div');
		liveLogDivOW.setAttribute('id', "liveLogOW");
		document.body.appendChild(liveLogDivOW);
		var lldowObj = xDOM('liveLogOW'); 
		var liveLogDiv = document.createElement('div');
		liveLogDiv.setAttribute('id', "liveLog");
		lldowObj.appendChild(liveLogDiv);
	}
}
 
 
 
 //--[ common ]--------------------------------------------------------------------------------------------------------------------------
 function fetchThing(id){
 	var arr = Array();
	arr.id = id;
	arr.obj = xDOM(id);
	arr.cssClass = arr.obj.className;
	
	arr.width = findObjWidth(arr.obj);
	arr.height = findObjHeight(arr.obj);
	
	arr.left = findPosX(arr.obj);
	arr.right = arr.left + arr.width;
	arr.top = findPosY(arr.obj);
	arr.bottom = arr.top + arr.height;
	
	arr.paddingRight = fetchStyle(id, 'padding-right', true);
	arr.paddingLeft = fetchStyle(id,'padding-left',true);
	arr.paddingBottom = fetchStyle(id,'padding-bottom', true);
	arr.paddingTop = fetchStyle(id,'padding-top',true);
	arr.paddingHeight = arr.paddingBottom + arr.paddingTop;
	arr.paddingWidth = arr.paddingLeft + arr.paddingRight;
	
	arr.marginTop = fetchStyle(id,'margin-top',true);
	arr.marginBottom = fetchStyle(id,'margin-bottom',true);
	arr.marginLeft = fetchStyle(id,'margin-left', true);
	arr.marginRight = fetchStyle(id,'margin-right',true);
	arr.marginWidth = arr.marginLeft + arr.marginRight;
	arr.marginHeight = arr.marginBottom + arr.marginTop;	
	
	arr.borderBottomWidth = fetchStyle(id, 'border-bottom-width', true);
	arr.borderTopWidth = fetchStyle(id,'border-top-width', true);
	arr.borderLeftWidth = fetchStyle(id,'border-left-width',true);
	arr.borderRightWidth = fetchStyle(id, 'border-right-width', true);
	arr.borderHeight = arr.borderBottomWidth + arr.borderTopWidth;
	arr.borderWidth = arr.borderLeftWidth + arr.borderRightWidth;
	
	arr.zIndex = fetchStyle(id,'z-index',true);
	
	/*for(x in arr){
		liveLog('arr.' + x + ' = ' + arr[x]);
	}*/
	return arr;
 }
 
function fetchStyle(id, style, convertToNumber){
	//enter styles all lowercase with hyphen between words. ie: "border-right-width"
	// see http://codepunk.hardwar.org.uk/css2js.htm for css to javascript reference conversion
	var value = null;
	if(getStyle(id,style)){ value = getStyle(id, style); }
	//if that does not work, we take out all hyphens and capitalize first letter of each word and try again
	var styleArr = style.split("-");
	var newStyle = "";
	for(var i=0; i<styleArr.length; i++){
		if(i === 0){//don't capitolize the first letter!
			newStyle += styleArr[i];
		}else{
			newStyle += (styleArr[i].replace(styleArr[i].charAt(0),styleArr[i].charAt(0).toUpperCase()));
		}
	}
	if(getStyle(id,newStyle)){ 	value = getStyle(id, newStyle); }
	if(convertToNumber){value = parseFloat(value);}
	if(convertToNumber && isNaN(value)){ value = 0;}
	return value;
} 

/*
function getPaddingRight(id){
	//requires getStyle function
	var paddingRight = 0;
	if(getStyle(id,'padding-right')){
		paddingRight = getStyle(id,'padding-right');
	}else if(getStyle(id,'paddingRight')){
		paddingRight = getStyle(id,'paddingRight');
	}
	return parseFloat(paddingRight);
}

function getPaddingBottom(id){
	//requires getStyle function
	var paddingBottom = 0;
	if(getStyle(id,'padding-bottom')){
		paddingBottom = getStyle(id,'padding-bottom');
	}else if(getStyle(id,'paddingBottom')){
		paddingBottom = getStyle(id,'paddingBottom');
	}
	return parseFloat(paddingBottom);
}
*/
function getStyle(id,styleProp){
	//http://www.quirksmode.org/dom/getstyles.html
	//liveLog(styleProp);
	var y = null;
	var x = xDOM(id);
	if (x.currentStyle){
		y = x.currentStyle[styleProp];
	}else if (window.getComputedStyle){
		y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);
	}
	return y;
}

function findObjHeight(thing){
	if(thing.offsetHeight){
		thing_height = thing.offsetHeight;
	}
	else if(thing.style.pixelHeight){
		thing_height = thing.pixelHeight;
	} 
	return thing_height;
}//end function
	
function findObjWidth(thing){
	//last modified March 04, 2007
	var thing_width = 0;
	if(thing.offsetWidth){
		thing_width = thing.offsetWidth;
	}
	else if(thing.style.pixelWidth){
		thing_width = thing.pixelWidth;
	} 
	return thing_width;
}//end function
	
function findPosY(obj)  {
	// by Peter-Paul Koch & Alex Tingle
	// http://blog.firetree.net/2005/07/04/javascript-find-position/
	// http://www.quirksmode.org/js/findpos.html
	var curtop = 0;
    
	if(obj.offsetParent){
        while(1)
        {
		//alert('curtop= '+curtop);
          curtop += obj.offsetTop;
          if(!obj.offsetParent)
		  {
            break;
		  }
          obj = obj.offsetParent;
        }
   } else if(obj.y){
        
		curtop += obj.y;
	}
    return curtop;
  }//end function
  
function findPosX(obj){
	// by Peter-Paul Koch & Alex Tingle
	// http://blog.firetree.net/2005/07/04/javascript-find-position/
	// http://www.quirksmode.org/js/findpos.html
    var curleft = 0;
    if(obj.offsetParent){
        while(1) 
        {
          curleft += obj.offsetLeft;
          if(!obj.offsetParent)
		  {
            break;
		  }
          obj = obj.offsetParent;
        }
   } else if(obj.x)
   	{
    	curleft += obj.x;
	}
    return curleft;
  }//end function
  
function getElementsByClassName(oElm, strTagName, strClassName){
	/* this awesome getElementsByClassName function was written by:
	Jonathan Snook, http://www.snook.ca/jonathan
	with add-ons by:
	Robert Nyman, http://www.robertnyman.com
	and be found at http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/
	*/
    var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = Array();
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for(var i=0; i<arrElements.length; i++){
        oElement = arrElements[i];      
        if(oRegExp.test(oElement.className)){arrReturnElements.push(oElement);}//end if 
    }//end for
    return (arrReturnElements);
}//end function

function setClass(id, className){
	// I made this function from David F. Miller's code (at A List apart) which can be found at:
	// http://www.alistapart.com/articles/jslogging
	// if the node's class already exists then replace its value
	//var obj = getObject(id);
	var obj = xDOM(id);
	if (obj.getAttributeNode("class")) {
	  for (var i = 0; i < obj.attributes.length; i++) {
		var attrName = obj.attributes[i].name.toUpperCase();
		if (attrName == 'CLASS') {
		  obj.attributes[i].value = className;
		}//end if
	  }//end for
	// otherwise create a new attribute
	} else {
	  obj.setAttribute("class", className);
	}//end if else
}//end function

//###V--[ Browser Window Size and Scroll Position functions ]##################################
// Browser Window Size and Position
// copyright Stephen Chapman, 3rd Jan 2005, 8th Dec 2005
// you may copy these functions but please keep the copyright notice as well
function pageWidth() {return window.innerWidth != null? window.innerWidth : document.documentElement && document.documentElement.clientWidth ?       document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : null;} 
function pageHeight() {return  window.innerHeight != null? window.innerHeight : document.documentElement && document.documentElement.clientHeight ?  document.documentElement.clientHeight : document.body != null? document.body.clientHeight : null;} 
function posLeft() {return typeof window.pageXOffset != 'undefined' ? window.pageXOffset :document.documentElement && document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ? document.body.scrollLeft : 0;} 
function posTop() {return typeof window.pageYOffset != 'undefined' ?  window.pageYOffset : document.documentElement && document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ? document.body.scrollTop : 0;} 
function posRight() {return posLeft()+pageWidth();} 
function posBottom() {return posTop()+pageHeight();}
                    

//~~~~~~~~~~[ xDOM ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Cross Browser DOM
// copyright Stephen Chapman, 4th Jan 2005
// you may copy this code but please keep the copyright notice as well
//http://javascript.about.com/library/blxdom.htm
var aDOM = 0, ieDOM = 0, nsDOM = 0; var stdDOM = document.getElementById;
if (stdDOM) aDOM = 1; else {ieDOM = document.all; if (ieDOM) aDOM = 1; else {
var nsDOM = ((navigator.appName.indexOf('Netscape') != -1)
&& (parseInt(navigator.appVersion) ==4)); if (nsDOM) aDOM = 1;}}
function xDOM(objectId, wS) {
	if (stdDOM) return wS ? document.getElementById(objectId).style:
	document.getElementById(objectId);
	if (ieDOM) return wS ? document.all[objectId].style: document.all[objectId];
	if (nsDOM) return document.layers[objectId];
}                  
// Object Functions
// copyright Stephen Chapman, 4th Jan 2005
//  you may copy these functions but please keep the copyright notice as well
//http://javascript.about.com/library/blobj2.htm
function objWidth(objectID) {
	var obj = xDOM(objectID,0); 
	if(obj.offsetWidth) return  parseFloat(obj.offsetWidth); if (obj.clip) return parseFloat(obj.clip.width); return 0;
}        
function objHeight(objectID) {
	var obj = xDOM(objectID,0); 
	if(obj.offsetHeight) return  parseFloat(obj.offsetHeight); if (obj.clip) return parseFloat(obj.clip.height); return 0;
}    
function objLeft(objectID) {
	var obj = xDOM(objectID,0);
	var objs = xDOM(objectID,1); 
	if(objs.left) return parseFloat(objs.left); if (objs.pixelLeft) return parseFloat(objs.pixelLeft); if (obj.offsetLeft) return parseFloat(obj.offsetLeft); return 0;
} 
function objTop(objectID) {
	var obj = xDOM(objectID,0);var objs = xDOM(objectID,1); if(objs.top) return parseFloat(objs.top); if (objs.pixelTop) return parseFloat(objs.pixelTop); if (obj.offsetTop) return parseFloat(obj.offsetTop); return 0;
} 
function objRight(objectID) {
	return parseFloat(objLeft(objectID))+parseFloat(objWidth(objectID));
} 
function objBottom(objectID) {
	return parseFloat(objTop(objectID))+parseFloat(objHeight(objectID));
} 
function objLayer(objectID) {
	var objs = xDOM(objectID,1); if(objs.zIndex) return objs.zIndex; return 0;
}
function objVisible(objectID) {
	var objs = xDOM(objectID,1); if(objs.visibility == 'hide' || objs.visibility == 'hidden') return 'hidden'; return 'visible';
}

function changeOpac(opacity, id) {//##########################################################
	// I did not write this function it can be found at:
	// http://brainerror.net/scripts_js_blendtrans.php
	var object = document.getElementById(id).style; 
	object.opacity = (opacity / 100);
	object.MozOpacity = (opacity / 100);
	object.KhtmlOpacity = (opacity / 100);
	object.filter = "alpha(opacity=" + opacity + ")";
}//end function
                    