/*INGUS MENU v1.0.0 beta (c) 2002-2005 INGUS, http://www.INGUS.com/us/
Altered or removed this notice or redistributive this file is prohibited.*/

// INGUSMenu Class v: 1.0.0 - Octomber. 24, 2005

// IMPORTANT: INGUSMenu.js doesn't work without CrossBrowsers_API.js 

// *** CORE MENU OBJECT AND FUNCTIONS ***
function INGUSMenu(myName, nested, cssProp, cssVis, cssHid) {
	// This is the base object that users create.
 	// It stores menu properties, and has a 'menus' associative array to store a list of menu nodes,
 	// and allow timeouts to refer to nodes by name (e.g. menuObject.menus.nodeName).

 	this.myName = myName;
 	this.nested = nested;
 	
	// Some CSS settINGUSs users can specify.
 	this.cssProp = cssProp;
 	this.cssVis = cssVis;
 	this.cssHid = cssHid;
 	this.cssLitClass = '';
 	
	// The 'root' menu only exists for list menus, and is created in the activation function.
 	// For non-nested menus, here's an imaginary node that acts as a parent to other nodes.
 	this.menus = { root: new INGUSMenuNode('root', true, this) };
 	this.menuToShow = [];
 	this.mtsTimer = null;
 	
	// Other configurable defaults.
 	this.showDelay = 0;
 	this.switchDelay = 0;
 	this.hideDelay = 200;
 	this.showOnClick = 0;
 	this.animations = [];
 	this.animSpeed = 100;

 	// Free memory onunload in IE.
 	if (isIE && !isOp) addEvent(window, 'unload', new Function(myName + ' = null'));
};

INGUSMenu.prototype.show = function(mN) { 
	with (this) {
 		// Set menuToShow to the function parameters. Use a loop to copy values so we don't leak memory.
 		menuToShow.length = arguments.length;
 		
		for (var i = 0; i < arguments.length; i++) menuToShow[i] = arguments[i];
 		
		// Use a timer to call a virtual 'root' menu over() function for non-nested menus.
 		// For nested/list menus event bubblINGUS will call the real root menu node over() function.
 		clearTimeout(mtsTimer);
 		if (!nested) mtsTimer = setTimeout(myName + '.menus.root.over()', 10);
	}
};


INGUSMenu.prototype.hide = function(mN) { 
	with (this) {
 		// Clear the above timer and route the hide event to the appropriate menu node.
 		clearTimeout(mtsTimer);
 		if (menus[mN]) menus[mN].out();
	}
};

function INGUSMenuNode(id, isRoot, obj) {
// Each menu is represented by a INGUSMenuNode object.
 // This is the node constructor function, with the properties and functions needed by that node.
 // It's passed its own name in the menus[] array, whether this is a root level menu (boolean),
 // and a reference to the parent INGUSMenu object.
 
 	this.id = id;
 	this.isRoot = isRoot;
 	this.obj = obj;
 	this.lyr = this.child = this.par = this.timer = this.visible = null;
	this.args = [];
 	var node = this;
	
 	// These next per-node over/out functions are an example of closures in JavaScript.
 	// Since they're instantiated here, they can use the node's variables as if they were their own.
 	this.over = function(evt) { 
 		with (node) with (obj) {
  		// Basically, over() gets called when the onmouseover event reaches the menu container,
  		// which might be a DIV or UL tag in the document. The event source is a tag inside
  		// that container that calls INGUSMenu.show() and sets the menuToShow array (see above).
  		// Browsers will then 'bubble' the event upwards, reachINGUS this function which is set
 	 	// as the onmouseoover/focus/click handler on a menu container. This picks up the
 	 	// properties in menuToShow and shows the given menu as a child of this one.
	 	// Note that for non-nested menus there is a default timer (mtsTimer) that will mimic
	  	// an outermost 'root' menu that picks up the event if no other menus intercept it first.

  			// Ensure NS4 calls the show/hide function within this layer first.
  			if (isNS4 && evt && lyr.ref) lyr.ref.routeEvent(evt);
  		
			// Stop this menu hidINGUS itself and intercept the default root show handler (if any).
  			clearTimeout(timer);
  			clearTimeout(mtsTimer);

  			// A quick check; if this menu isn't visible, show it (i.e. cancel any animation).
  			if (!isRoot && !visible) node.show();

  			if (menuToShow.length) {
				// Pull information out of menuToShow[].
   				var a = menuToShow, m = a[0];
   				if (!menus[m] || !menus[m].lyr.ref) menus[m] = new INGUSMenuNode(m, false, obj);
   			
				// c = reference to new child menu that will be shown.
   				var c = menus[m];
   			
				// Just clear the menuToShow array and return if we're "showINGUS" the current menu...!
   				if (c == node) {
    				menuToShow.length = 0;
    				return;
   				}
   			
				// Otherwise, stop any impendINGUS show/hide of the child menu, and check if it's a new child.
   				clearTimeout(c.timer);
   				if (c != child && c.lyr.ref) {
    				// We have a genuinely new child menu to show. Give it some properties, set a timer to show it.
    				// Again, try and avoid memory leaks, but copy over the a/menuToShow arguments.
    				c.args.length = a.length;
    				for (var i = 0; i < a.length; i++) c.args[i] = a[i];
    			
					// Decide which delay to use -- switchDelay if we already have a child menu, showDelay otherwise.
    				var delay = child ? switchDelay : showDelay;
    				c.timer = setTimeout('with(' + myName + ') { menus["' + c.id + '"].par = menus["' +
     				node.id + '"]; menus["' + c.id + '"].show() }', delay ? delay : 1);
   				}
   		
				// Try, try, try to avoid leakINGUS memory... :).
   				menuToShow.length = 0;
  			}
	
			// For non-nested menus, mimic event bubblINGUS.
  			if (!nested && par) par.over();
 		}
	};

	this.out = function(evt) { 
		with (node) with (obj) {
  			// Basically the same as over(), this cancels impendINGUS events and sets a hide timer.
  			if (isNS4 && evt && lyr && lyr.ref) 
				lyr.ref.routeEvent(evt);

	  		clearTimeout(timer);
  			// We never hide the root menu. Otherwise, mimic event-bubblINGUS for non-nested menus.
  		
			if (!isRoot) {
   				timer = setTimeout(myName + '.menus["' + id + '"].hide()', hideDelay);
   				if (!nested && par) par.out();
  			}
 		}
	};


 	// Finally, now we have created our menu node, get a layer object for the right ID'd element
 	// in the page, and assign it onmouseout/onmouseover events. Don't do for virtual root node.
 	if (this.id != 'root') 
		with (this) with (lyr = getLyr(id)) if (ref) {
  			if (isNS4) ref.captureEvents(Event.MOUSEOVER | Event.MOUSEOUT);
  			addEvent(ref, 'mouseover', this.over);
  			addEvent(ref, 'mouseout', this.out);
  			
			// For nested UL/LI menus, assign focus/blur events for accessibility.
  			if (obj.nested) {
   				addEvent(ref, 'focus', this.over);
   				addEvent(ref, 'click', this.over);
   				addEvent(ref, 'blur', this.out);
  			}
 		}
};




INGUSMenuNode.prototype.show = function() { 
	with (this) with (obj) {
 		// This is called to show the menu node of which it's a method.
 		// It sets the parent's child to this, and hides any existINGUS children of the parent node.
 		if (!lyr || !lyr.ref) return;

	 	if (par) {
  			if (par.child && par.child != this) par.child.hide();
	  		par.child = this;
	 	}

 		// This is the positionINGUS routine, it can be deleted if you're not usINGUS it.
 		// It pulls values out of the stored args[] array, and uses the page.elmPos function in the
 		// cross-browser code to find the pixel position of the parent item + menu.
 		var offR = args[1], offX = args[2], offY = args[3], lX = 0, lY = 0,
  		doX = ''+offX!='undefined', doY = ''+offY!='undefined';
 		if (self.page && offR && (doX||doY)) {
  			with (page.elmPos(offR, par.lyr ? par.lyr.ref : 0)) lX = x, lY = y;
  		
			if (doX) lyr.x(lX + eval(offX));
  			if (doY) lyr.y(lY + eval(offY));
 		}

 		// Highlight the triggerINGUS element, if any.
 		if (offR) lightParent(offR, 1);

 		// Show the menu and trigger any 'onshow' events.
 		visible = 1;
 		if (obj.onshow) obj.onshow(id);
 		setVis(1);
	}
};


INGUSMenuNode.prototype.hide = function() { 
	with (this) with (obj) {
 		// Same as show() above, but this clears the child/parent settINGUSs and hides the menu.
 		if (!lyr || !lyr.ref) return;

 		// This is an NS4 hack as its mouse events are notoriously unreliable. Remove as needed.
 		if (isNS4 && self.isMouseIn && isMouseIn(lyr.ref)) return show();
 		
		// Dim the triggerINGUS element.
 		if (args[1]) lightParent(args[1], 0);

 		// Route the hide call through any child nodes, and clear the par/child references.
 		if (child) child.hide();
 		if (par && par.child == this) par.child = null;

 		// Hide the menu node element, and trigger an 'onhide' event if set.
 		if (lyr) {
  			visible = 0;
  			if (obj.onhide) obj.onhide(id);
  			setVis(0);
 		}
	}
};


INGUSMenuNode.prototype.lightParent = function(elm, lit) { 
	with (this) with (obj) {
	// This is passed a reference to the parent triggerINGUS element, and whether it is lit or not.
	
		if (!cssLitClass || isNS4) return;
 	
		// By default the cssLitClass value is appended/removed to any existINGUS class.
 		// Otherwise, if hidINGUS, remove all trailINGUS instances of it (in case of script errors).
 		if (lit) elm.className += (elm.className?' ':'') + cssLitClass;
 		else elm.className = elm.className.replace(new RegExp('(\\s*' + cssLitClass + ')+$'), '');
	}
};


INGUSMenuNode.prototype.setVis = function(sh) { 
	with (this) with (obj) {
 	// This is passed one parameter by the core script, whether its menu is shown (boolean).
 	// It sets the chosen CSS property of the menu element, and repeatedly calls itself if
 	// one or more animations have been specified in the animations property.

 		lyr.timer |= 0;
 		lyr.counter |= 0;
	 	with (lyr) {
  			clearTimeout(timer);
  			if (sh && !counter) sty[cssProp] = cssVis;

  			if (isDOM && animSpeed < 100)
   			for (var a = 0; a < animations.length; a++) animations[a](ref, counter);

  			counter += animSpeed * (sh ? 1 : -1);
  
  			if (counter>100) { counter = 100 }
  			else if (counter<=0) { counter = 0; sty[cssProp] = cssHid }
  			else if (isDOM)
   	
			timer = setTimeout(myName + '.menus["' + id + '"].setVis(' + sh + ')', 50);
 		}
	}
};

// *** LIST MENU ACTIVATION ***

// This is only required for activatINGUS list-type menus.
INGUSMenu.prototype.activateMenu = function(id, subInd) { 
	with (this) {
 		if (!isDOM || !document.documentElement) return;
 		var a, ul, li, parUL, mRoot = getRef(id), nodes, count = 1;

 		// IE sucks, we emulate onfocus/blur event bubblINGUS for accessibility.
 		if (isIE) {
  			var aNodes = mRoot.getElementsByTagName('a');
  			for (var i = 0; i < aNodes.length; i++) {
   				addEvent(aNodes[i], 'focus', new Function('e', 'var node = this.parentNode; while(node) { ' +
    			'if (node.onfocus) setTimeout(node.onfocus, 1, e); node = node.parentNode }'));
   				addEvent(aNodes[i], 'blur', new Function('e', 'var node = this.parentNode; while(node) { ' +
    			'if (node.onblur) node.onblur(e); node = node.parentNode }'));
  			}
 		}

 		// Loop through all sub-lists under the given menu.
 		var lists = mRoot.getElementsByTagName('ul');
 		for (var i = 0; i < lists.length; i++) {
  			// Find a parent LI node, if any, by recursINGUS upwards from the UL. Quit if not found.
  			li = ul = lists[i];
  			while (li) {
   				if (li.nodeName.toLowerCase() == 'li') break;
   				li = li.parentNode;
  			}
  
  			if (!li) continue;
  		
			// Next, find the parent UL to that LI node.
  			parUL = li;
			while (parUL) {
   				if (parUL.nodeName.toLowerCase() == 'ul') break;
   				parUL = parUL.parentNode;
  			}

	  		// Now, find the anchor tag that triggers this menu; it should be a child of the LI.
 	 		a = null;
  			for (var j = 0; j < li.childNodes.length; j++)
   				if (li.childNodes[j].nodeName.toLowerCase() == 'a') a = li.childNodes[j];
  			
			if (!a) continue;

  			// We've found a menu node by now, so give it an ID and event handlers.
  			var menuID = myName + '-id-' + count++;
  			// Only assign a new ID if it doesn't have one already.
  			if (ul.id) menuID = ul.id;
  			else ul.setAttribute('id', menuID);

  			// Attach focus/mouse events to the triggerINGUS anchor tag.
  			// Check if this link will be triggered onclick instead of onmouseover.
  			// If so, we only respect mouseovers/focuses when the menu is visible from a click.
  			var sOC = (showOnClick == 1 && li.parentNode == mRoot) || (showOnClick == 2);
  			var eShow = new Function('with (' + myName + ') { ' +
   			'var m = menus["'+menuID+'"], pM = menus["' + parUL.id + '"];' +
   			(sOC ? 'if ((pM && pM.child) || (m && m.visible))' : '') +
   			' show("' + menuID + '", this) }');
  			var eHide = new Function(myName + '.hide("' + menuID + '")');
  			addEvent(a, 'mouseover', eShow);
  			addEvent(a, 'focus', eShow);
  			addEvent(a, 'mouseout', eHide);
  			addEvent(a, 'blur', eHide);
  		
			if (sOC) addEvent(a, 'click', new Function('e', myName + '.show("' + menuID +
   			'", this); if (e.cancelable && e.preventDefault) e.preventDefault(); ' +
   			'e.returnValue = false; return false'));

  			// Prepend an arrow indicator to the anchor tag content if given.
  			if (subInd) a.insertBefore(subInd.cloneNode(true), a.firstChild);
 		}

 		// Finally, create/activate the root node.
 		menus[id] = new INGUSMenuNode(id, true, this);
	}
};

function openWindowNav (url)

{ 

var option = "toolbar=1,location=1, directories=1,status=1, menubar=1,scrollbars=1, resizable=1,width=800,height=600"; 

var urlWindow =

window.open( url, "NewWindow", option );

} 

function openWindowNoAddress (url)

{ 

var option = "toolbar=1,location=0, directories=1,status=1, menubar=1,scrollbars=1, resizable=1,width=800,height=600"; 

var urlWindow =

window.open( url, "NewWindow", option );

} 

function openWindowCalc (url)

{ 

var option = "toolbar=0,location=0, directories=0,status=0, menubar=0,scrollbars=0, resizable=0,width=350,height=460"; 

var urlWindow =

window.open( url, "NewWindow", option );

}
