/*
====================================================================== 
 This source code and all contained content and modules are		 		
 Copyright © 2004-2005, The Igneous Group, Inc. All Rights Reserved. 		
====================================================================== 
$Header: /IGTemplates/IGComponents/JS/IGXECfunctions.js 4     9/02/05 12:13p Kevin $ 
$History: IGXECfunctions.js $ 
 * 
 * *****************  Version 4  *****************
 * User: Kevin        Date: 9/02/05    Time: 12:13p
 * Updated in $/IGTemplates/IGComponents/JS
 * added a keyword pop up window function
 * 
 * *****************  Version 3  *****************
 * User: Kristi       Date: 7/07/05    Time: 6:40p
 * Updated in $/IGTemplates/IGComponents/JS
 * For vertical plus/minus menu, add space in front of items that do NOT
 * have a plus or minus, for slightly better alignment.
 * 
 * *****************  Version 2  *****************
 * User: Kristi       Date: 7/01/05    Time: 5:28p
 * Updated in $/IGTemplates/IGComponents/JS
 * in progress
 * 
 * *****************	Version 1	*****************
 * User: Kristi			 Date: 6/07/05		Time: 5:28p
 * Created in $/USC-SIG-Core/IGComponents/JS
 * Created a standard igxec javascript file that will include functions
 * that can be used on every page.	The first javascript function is used
 * an open window for glossary items.
*/
// This file is sourced from inside custom tag Preamble.cfm

// common function for opening a glossary window.	
// Glossary term passed in should be NOT previously url encoded.
function fnc_OpenGlossaryWindow( var_Term ) {
	var_URLEncodedTerm = escape(var_Term);
	GlossaryWindow=window.open('/Glossary/GlossaryTermDisplay.cfm?q_GlossaryTerm=' + var_URLEncodedTerm + '&NavTemplate=Glossary','GlossaryWindow','width=495,height=500,scrollbars=yes,dependent=yes,resizable=yes');
	GlossaryWindow.focus();
}

// common function for opening a glossary window.	
// Glossary term passed in should be NOT previously url encoded.
function fnc_OpenKeywordWindow( var_URL ) {
	KeywordWindow=window.open(var_URL,'KeywordWindow','width=640,height=500,scrollbars=yes,dependent=yes,resizable=yes');
	KeywordWindow.focus();
}

// following functions used to implement HorizCssDD type menu.
// code developed from ??
function initNavBar(menuID)
{
	cssjsmenu(menuID);
	/*     if (document.getElementById)
	{
		var kill = document.getElementById('hoverJS'); 
		kill.disabled = true;
	} */
}
function elementContains(elmOuter, elmInner)
{
	while (elmInner && elmInner != elmOuter)
	{
		elmInner = elmInner.parentNode;
	}
	if (elmInner == elmOuter)
	{
		return true;
	}
	return false;
}
function getPageXY(elm)
{
	var point = { x: 0, y: 0 };
	while (elm)
	{
		point.x += elm.offsetLeft;
		point.y += elm.offsetTop;
		elm = elm.offsetParent;
	}
	return point;
}
function setPageXY(elm, x, y)
{
	var parentXY = {x: 0, y: 0 };
	if (elm.offsetParent)
	{
		parentXY = getPageXY(elm.offsetParent);
	}
	elm.style.left = (x - parentXY.x) + 'px';
	elm.style.top	= (y - parentXY.y) + 'px';
}
function cssjsmenu(menuid)
{
	var i;
	var j;
	var node;
	var child;
	var parent;
	
	// if the browser doesn't even support
	// document.getElementById, give up now.
	if (!document.getElementById)
	{
		return true;
	}
	
	// check for downlevel browsers
	// Opera 6, IE 5/Mac are not supported
	var version;
	var offset;
	offset = navigator.userAgent.indexOf('Opera');
	if (offset != -1)
	{
		version = parseInt('0' + navigator.userAgent.substr(offset + 6), 10);
		if (version < 7)
		{
			return true;
		}
	}
	offset = navigator.userAgent.indexOf('MSIE');
	if (offset != -1)
	{
		if (navigator.userAgent.indexOf('Mac') != -1)
		{
			return true;
		}
	}
	
	// walk down the menu object tree
	var menudiv = document.getElementById(menuid);
	// ul
	var ul = new Array();

	for (i = 0; i < menudiv.childNodes.length; i++)
	{
		node = menudiv.childNodes[i];
		if (node.nodeName == 'UL')
		{
			ul[ul.length] = node;
		}
	}
	// ul > li
	var ul_gt_li = new Array();
	for (i = 0; i < ul.length; i++)
	{
		node = ul[i];
		for (j = 0; j < node.childNodes.length; j++)
		{
			child = node.childNodes[j];
			if (child.nodeName == 'LI')
			{
				ul_gt_li[ul_gt_li.length] = child;
				child.style.display = 'inline';
				child.style.listStyle = 'none';
				child.style.position = 'static';
			}
		}
	}
	// ul > li > ul
	var ul_gt_li_gt_ul = new Array();
	for (i = 0; i < ul_gt_li.length; i++)
	{
		node = ul_gt_li[i];
		for (j = 0; j < node.childNodes.length; j++)
		{
			child = node.childNodes[j];
			if (child.nodeName == 'UL')
			{
				ul_gt_li_gt_ul[ul_gt_li_gt_ul.length] = child;
				child.style.position = 'absolute';
				child.style.left = '-13em';
				child.style.visibility = 'hidden';

				// attach hover to parent li
				parent = child.parentNode;
				parent.onmouseover = function (e)
				{
					var i;
					var child;
					var point;
					// stop the pure css hover effect
					this.style.paddingBottom = '0';

					for (i = 0; i < this.childNodes.length; i++)
					{
						child = this.childNodes[i];
						if (child.nodeName == 'UL')
						{
							point = getPageXY(this);
							setPageXY(child, point.x, point.y + this.offsetHeight);
							child.style.visibility = 'visible';
						}
					}
					return false;
				};
				parent.onmouseout = function (e)
				{
					var relatedTarget = null;
					if (e)
					{
						relatedTarget = e.relatedTarget;
						// work around Gecko Linux only bug where related target is null
						// when clicking on menu links or when right clicking and moving
						// into a context menu.
			if (navigator.product == 'Gecko' && navigator.platform.indexOf('Linux') != -1 && !relatedTarget)
			{
				relatedTarget = e.originalTarget;
			}
					}
					else if (window.event)
					{
						relatedTarget = window.event.toElement;
					}

					if (elementContains(this, relatedTarget))
					{
						return false;
					}

					var i;
					var child;
					for (i = 0; i < this.childNodes.length; i++)
					{
						child = this.childNodes[i];
						if (child.nodeName == 'UL')
						{
								child.style.visibility = 'hidden';
						}
					}
					return false;
				};
			}
		}
	}
	return true;
}

// following functions used to implement VertPlusMinus type menu.
/*
 * Expandable list implementation.
 * by David Lindquist <first name><at><last name><dot><net>
 * See:
 * http://www.gazingus.org/html/DOM-Scripted_Lists_Revisited.html
 * Modifies lists so that sublists can be hidden and shown by means of
 * a switch. The switch is a node inserted into the DOM tree as the
 * first child of the list item containing the sublist.
 */

// The script will only be applied to lists containing this class name,
// e.g.: <ul class="foo VertPlusMinusNav">...</ul>.
var CLASS_NAME = "VertPlusMinusNav";

// This value is the assumed initial display style for a sublist when it cannot
// be determined by other means. See below.
var DEFAULT_DISPLAY = "none";

// The namespace to use when using this script in an XML context.
var XMLNS = "http://www.w3.org/1999/xhtml";

// The beginning of the title text for the switch when the sublist is collapsed.
var CLOSED_PREFIX = "Expand list: ";

// The beginning of the title text for the switch when the sublist is expanded.
var OPENED_PREFIX = "Collapse list: ";

/******************************************************************************/

// Returns a copy of a string with leading and trailing whitespace removed.
String.prototype.trim = function() {
    return this.replace(/^\s+/, "").replace(/\s+$/, "");
}

// Walks the DOM tree starting at a given root element. Returns an
// array of nodes of the specified type and conforming to the criteria
// of the given filter function. The filter should return a boolean.
function getNodesByType(root, type, filter) {
    var node = root;
    var nodes = [];
    var next;

    while (node != null) {
        if (node.hasChildNodes())
            node = node.firstChild;
        else if (node != root && null != (next = node.nextSibling))
            node = next;
        else {
            next = null;
            for ( ; node != root; node = node.parentNode) {
                next = node.nextSibling;
                if (next != null) break;
            }
            node = next;
        }
        if (node != null && node.nodeType == type && filter(node))
            nodes.push(node);
    }
    return nodes;
}

// Simulates the innerText property of IE and other browsers.
// Mozilla/Firefox need this.
function getInnerText(node) {
    if (node == null || node.nodeType != 1)
        return;
    var text = "";
    var textnodes = getNodesByType(node, 3, function() { return true; });
    for (var i = 0; i < textnodes.length; i++)
        text += textnodes[i].data;
    return text;
}

function initExpandableLists() {
    if (!document.getElementsByTagName) return;

    // Top-level function to accommodate browsers that do not register
    // a click event when a link is activated by the keyboard.
    switchNode = function(id) {
        var node = document.getElementById(id);
        if (node && /^switch /.test(node.className)) node.onclick();
    }

    // Top-level function to be assigned as the event handler for the
    // switch. This could have been bound to the handler as a closure,
    // but closures are associated with memory leak problems in IE.
    actuate = function() {
        var sublist = this.parentNode.getElementsByTagName("ul")[0] ||
                      this.parentNode.getElementsByTagName("ol")[0];
        if (sublist.style.display == "block") {
            sublist.style.display = "none";
            this.firstChild.data = "+";
            this.className = "switch off";
            this.title = this.title.replace(OPENED_PREFIX, CLOSED_PREFIX);
        } else {
            sublist.style.display = "block";
            this.firstChild.data = "-";
            this.className = "switch on";
            this.title = this.title.replace(CLOSED_PREFIX, OPENED_PREFIX);
        }
        return false;
    }

    // Create switch node from which the others will be cloned.
    if (typeof document.createElementNS == "function")
        var template = document.createElementNS(XMLNS, "a");
    else
        var template = document.createElement("a");
    template.appendChild(document.createTextNode(" "));

    var list, i = 0, j = 0;
    var pattern = new RegExp("(^| )" + CLASS_NAME + "( |$)");

    while ((list = document.getElementsByTagName("ul")[i++]) ||
           (list = document.getElementsByTagName("ol")[j++]))
    {
        // Only lists with the given class name are processed.
        if (pattern.test(list.className) == false) continue;

        var item, k = 0;
        while ((item = list.getElementsByTagName("li")[k++])) {
            var sublist = item.getElementsByTagName("ul")[0] ||
                          item.getElementsByTagName("ol")[0];
            // No sublist under this list item. Skip it, after adding a space in front.
            if (sublist == null) {
				//item.appendChild(document.createTextNode("&nbsp;"));
				//item.insertBefore(item.firstChild,document.createTextNode("&nbsp;"));
				item.innerHTML = "&nbsp;&nbsp;" + item.innerHTML;
				continue;
			}

            // Attempt to determine initial display style of the
            // sublist so the proper symbol is used.
            var symbol;
			switch (sublist.style.display) {
            case "none" : symbol = "+"; break;
            case "block": symbol = "-"; break;
            default:
                var display = DEFAULT_DISPLAY;
                if (sublist.currentStyle) {
                    display = sublist.currentStyle.display;
                } else if (document.defaultView &&
                           document.defaultView.getComputedStyle &&
                           document.defaultView.getComputedStyle(sublist, ""))
                {
                    var view = document.defaultView;
                    var computed = view.getComputedStyle(sublist, "");
                    display = computed.getPropertyValue("display");
                }
                symbol = (display == "none") ? "+" : "-";
                // Explicitly set the display style to make sure it is
                // set for the next read. If it is somehow the empty
                // string, use the default value from the (X)HTML DTD.
                sublist.style.display = display || "block";
                break;
            }

            // This bit attempts to extract some text from the first
            // child node of the list item to append to the title
            // attribute of the switch.
            var child = item.firstChild;
            var text = "";
            while (child) {
                if (child.nodeType == 3 && "" != child.data.trim()) {
                    text = child.data;
                    break;
                } else if (child.nodeType == 1 &&
                           !/^[ou]l$/i.test(child.tagName))
                {
                    text = child.innerText || getInnerText(child);
                    break;
                }
                child = child.nextSibling;
            }

            var actuator = template.cloneNode(true);
            // a reasonably unique ID
            var uid = "switch" + i + "-" + j + "-" + k;
            actuator.id = uid;
            actuator.href = "javascript:switchNode('" + uid + "')";
            actuator.className = "switch " + ((symbol == "+") ? "off" : "on");
            actuator.title = ((symbol == "+")
                              ? CLOSED_PREFIX : OPENED_PREFIX) + text.trim();
            actuator.firstChild.data = symbol;
            actuator.onclick = actuate;
            item.insertBefore(actuator, item.firstChild);
        }
    }
}
