/***********************************************************
*	Collapsible Menu script
*	Author: Jay Quibodeaux
*	Last modified: 10/07
/***********************************************************/

var d = document;
/*
var isIE = true;
if((document.getElementById && !document.all))
	isIE = false;
*/

/* The MenuTracker class is used merely for the sake of encapsulation.
    It uses a global array to track menu selections. */
var MenuTracker = function() {
	this.state = 0; // Keeps track of whether menu is expanded or collapsed.
	this.expanded = 0; // 1 = expanded menu, 0 = collapsed.
	this.arr = [[,],[,]]; // Store id of current and previous menu selections.
}

/* fillArray populates the array upon the onclick of each menu item.
    It then calls fadeMenuPre. */
MenuTracker.prototype.fillArray = function(obj) {
	if(this.expanded == 1)
		return false;
	var objSibling = obj;
	// Get reference to UL element which contains sub-menu.
	do{
		objSibling = objSibling.nextSibling;
	}while(objSibling.nodeName != "UL");
	// Determine where to store.
	if(typeof(this.arr[0][0]) == "undefined"){ // arr[0] is empty.
		this.arr[0][0] = obj.id;
		this.arr[0][1] = objSibling.id;
	}else if(typeof(this.arr[1][0]) == "undefined"){ // arr[1] is empty, arr[0] is full.
		this.arr[1][0] = obj.id;
		this.arr[1][1] = objSibling.id;
	}else{ // Both are full.
		// Move items to the "left".
		this.arr[0][0] = this.arr[1][0];
		this.arr[0][1] = this.arr[1][1];
		this.arr[1][0] = obj.id;
		this.arr[1][1] = objSibling.id;
	}
	// Determine which item(s) need to be toggled.
	if(this.arr[0][0] == this.arr[1][0]){ // They're the same, so just toggle arr[1].
		fadeMenuPre(d.getElementById(this.arr[1][0]));
	}else{ // They're different.
		if(typeof(this.arr[1][0]) == "undefined"){ // If true, it's the first click; all we do is show arr[0].
			this.toggleIcon(d.getElementById(this.arr[0][0]));
			if(objSibling.style.display == "block") { // Handle expanded menu item.
				fadeMenuHide(d.getElementById(this.arr[0][0]), d.getElementById(this.arr[0][1]), d.getElementById(this.arr[0][1]).offsetHeight, .03);
			}else{
				objSibling.style.display = "block";
				fadeMenuShow(d.getElementById(this.arr[0][0]), d.getElementById(this.arr[0][1]), d.getElementById(this.arr[0][1]).offsetHeight, d.getElementById(this.arr[0][0]).offsetHeight);
			}
		}else{ // Hide arr[0], show arr[1].
			if(d.getElementById(this.arr[0][0]).state == 1) {
				this.toggleIcon(d.getElementById(this.arr[0][0]));
				fadeMenuHide(d.getElementById(this.arr[0][0]), d.getElementById(this.arr[0][1]), d.getElementById(this.arr[0][1]).offsetHeight, .03);
			}
			if(d.getElementById(this.arr[1][0]).state == 0 || typeof(d.getElementById(this.arr[1][0]).state) == "undefined") {
				this.toggleIcon(d.getElementById(this.arr[1][0]));
				objSibling.style.display = "block";
				fadeMenuShow(d.getElementById(this.arr[1][0]), d.getElementById(this.arr[1][1]), d.getElementById(this.arr[1][1]).offsetHeight, d.getElementById(this.arr[1][0]).offsetHeight);
			}
		}
	}
}
MenuTracker.prototype.getNextSibling = function() {
	do{ // Get reference to UL element which contains sub-menu.
		this.objSibling = obj.nextSibling;
	}while(this.objSibling.nodeName != "UL");
}
MenuTracker.prototype.toggleIcon = function(obj) {
	// Toggle +/- sign.
	if(obj.childNodes[0].innerHTML.indexOf('[+]') != -1){
		obj.childNodes[0].innerHTML = '[&minus;]';
	}else{
		obj.childNodes[0].innerHTML = '[+]';
	}
}

// Create MenuTracker objects!!
var objMenuItem = new MenuTracker();
var objSubMenuItem = new MenuTracker();


/***************************************************************************
* Description: fadeMenuPre handles the non-recursive part of fading a menu item.
*   Set sub-menu's display to "block", then pass its offsetHeight to either
*   fadeMenuHide or fadeMenuShow.
***************************************************************************/
function fadeMenuPre(obj){
	if(objMenuItem.expanded == 1)
		return false;
	var objSibling = obj;
	var objOffsetHeight = obj.offsetHeight;
	var objSiblingOffsetHeight = obj.offsetHeight;
	var heightVar = .03;

	do{ // Get reference to UL element which contains sub-menu.
		objSibling = objSibling.nextSibling;
	}while(objSibling.nodeName != "UL"); // objSibling is now UL element.
	objSiblingOffsetHeight = objSibling.offsetHeight;
	// Toggle +/- sign.
	if(obj.childNodes[0].innerHTML.indexOf('[+]') != -1){
		obj.childNodes[0].innerHTML = '[&minus;]';
	}else{
		obj.childNodes[0].innerHTML = '[+]';
	}

	// Determine offsetHeight of obj & objSibling
	if(objSibling.style.display == "block"){
		fadeMenuHide(obj, objSibling, objSiblingOffsetHeight, heightVar);
	}else{
		objSibling.style.display = "block";
		objSiblingOffsetHeight = objSibling.offsetHeight; // Must set *after* display is changed to "block".
		fadeMenuShow(obj, objSibling, objSiblingOffsetHeight, obj.offsetHeight);
	}
}

/***************************************************************************
* Description: fadeMenuHide shrinks/hides a menu section.
***************************************************************************/
function fadeMenuHide(obj, objSibling, height, heightVar){
	if(obj.expanded == 1)
		return false;
	var objDiv = obj.parentNode; // Store containing element.
	objTEST = objSibling;
	height = height * (.97 - heightVar);
	if(height <= 20){
		objDiv.style.height = '';  // MUST USE EMPTY VALUE!!
		objTEST.style.height = '';  // MUST USE EMPTY VALUE!!
		objTEST.style.display = "none";
		obj.state = 0;
		return;
	}else{
		objDiv.style.height = height + "px";
		objDiv.style.overflow = "hidden";
		objTEST.style.height = height + "px";
		setTimeout(function () { fadeMenuHide(obj, objSibling, height, heightVar+.03); }, 8); // Must use this format when passing Objects!
	}
}

/***************************************************************************
* Description: fadeMenuShow expands/shows a menu section.
***************************************************************************/
function fadeMenuShow(obj, objSibling, objOffsetHeight, height){
	var objDiv = obj.parentNode; // Store containing element.

	height = height * 1.4;
	if(height > (objOffsetHeight/* - 22*/)){
		objDiv.style.height = '';  // MUST USE EMPTY VALUE!!
		objSibling.style.height = '';  // MUST USE EMPTY VALUE!!
		obj.state = 1;
		return;
	}else{
		objDiv.style.height = height + "px";
		objDiv.style.overflow = "hidden";
		objSibling.style.height = height + "px";
		setTimeout(function(){ fadeMenuShow(obj, objSibling, objOffsetHeight, height); }, 8); // Must use this format when passing Objects!
	}
}

/***********************************************************************************************
*  #######-->   MAKE THIS A prototype OF MenuTracker!
***********************************************************************************************/
function expandOrCollapseAll(root, boolExpand){
	var nodeRoot = root;

	if(nodeRoot.hasChildNodes()){
	 	for(var i = 0; i < nodeRoot.childNodes.length; i++){ // Loop thru root's children.
			if(nodeRoot.childNodes[i].hasChildNodes()){
				for(var j = 0; j < nodeRoot.childNodes[i].childNodes.length; j++){
					var nodePlusMinus;
					if(nodeRoot.childNodes[i].childNodes[j].nodeName == "DIV"){ // If node is a DIV, it must contain a +/-, so store it for toggling.
						nodePlusMinus = nodeRoot.childNodes[i].childNodes[j];
					}						
					if(nodeRoot.childNodes[i].childNodes[j].nodeName == "UL"){ // We only care about ULs.
						var nodeRootNew = nodeRoot.childNodes[i].childNodes[j]; // Set root's grandchild as new root!

						// Assume expand...
						var displayMode = "block";
						var expand = 1;
						objMenuItem.expanded = 1;
						objSubMenuItem.expanded = 1;
						objMenuItem.state = 1;
						objSubMenuItem.state = 1;
						nodePlusMinus.childNodes[0].innerHTML = '[&minus;]';
						// ... END Assume expand
						
						if(boolExpand == 0){ // Collapse.
							displayMode = "none";
							expand = 0;
							objMenuItem.expanded = 0;
							objSubMenuItem.expanded = 0;
							objMenuItem.state = 0;
							objSubMenuItem.state = 0;
							nodePlusMinus.childNodes[0].innerHTML = '[+]';
						}
						if(nodeRootNew.style.display != "inline"){ // We use "inline" to mark selected menu items, so if item is NOT "inline", we set its display normally.
							nodeRootNew.style.display = displayMode;
						}else{
							nodeRootNew.style.display = "block";
							objMenuItem.expanded = 1;
							objSubMenuItem.expanded = 1;
							objMenuItem.state = 1;
							objSubMenuItem.state = 1;
							nodePlusMinus.childNodes[0].innerHTML = '[&minus;]';
						}
						expandOrCollapseAll(nodeRootNew, expand); // Recurse.
					}else{ // There are no ULs.
						objMenuItem.expanded = 0;
						objSubMenuItem.expanded = 0;
						objMenuItem.state = 0;
						objSubMenuItem.state = 0;
					}
				}
			}
		}
	}
}

/***************************************************************************
* checkLength(): Alerts user if value is greater than specified number of chars.
***************************************************************************/
function checkLength(obj, maxLength){
	if(obj.value.length > maxLength){
		alert("Entries cannot be more than " + maxLength + " characters in length.\nPlease shorten your entry by " + (obj.value.length - maxLength) + " characters.");
		return false;
	}
}

/* ----------------------------------------------------------------------------
----------------------------------------------------------------------------*/

function setRadio(obj) {
	switch (obj.name) {
		case "rdSort1": {
			d.forms[1].rd1.value = obj.value;
			break;
		}
		case "rdSort2": {
			d.forms[1].rd2.value = obj.value;
			break;
		}
		case "rdSort3": {
			d.forms[1].rd3.value = obj.value;
			break;
		}
		default: {}
	}
}

function clearSelects() {
	// *** Use the following if there're NON-SORT form elements on the page that
	// ***  should not be reset:
	/*
	d.forms[1].sort1.selectedIndex = 0;
	d.forms[1].sort2.selectedIndex = 0;
	d.forms[1].sort3.selectedIndex = 0;
	*/
	d.forms[1].reset();
	// Must reset values set by "setRadio()"
	d.forms[1].rd1.value = 1;
	d.forms[1].rd2.value = 1;
	//d.getElementById("rdSort2").checked = true;
	d.forms[1].rd3.value = 1;
}

/***************************************************************************
* writeTable(): Creates the product tables.
***************************************************************************/
function writeTable(f1, f2, f3) {
	var sorted = '<table id="sortTable">';
	var strLink = "";
	var strLinkBegin = "";
	var strLinkEnd = "";

	for(i=0; i<arr.length; i++){
		var shade = ""; // Set shading for selected sort column(s);
		/* Color rows */
		if(i%2 == 0){
			bgColor1 = ' class="rowColor"';
		}else{
			bgColor1 = '';
		}
		/* Put items in table */
		if(i==0){
			sorted += '<tr style="vertical-align:bottom; font-weight:bold; color: white; background-color:#369">';
		}else{
			sorted += '<tr' + bgColor1 + '>';
		}
		sortRow = '';
		for(j=0; j<arr[i].length; j++) {
			var strItem = arr[i][j];

				if(strItem.length == 0)
					strItem = "&nbsp;"; // Make table pretty
				if(i == 0){
					/* ### Dashes will line break in IE. Force cell padding to compensate. ### */
					stylePad = '';
					styleShade = '';
					eval(strDashColumns);
					if((j == f1 || j == f2 || j == f3)) {
						styleShade = 'background:#777777;';
					}
					sortRow += '<td style="' + stylePad + styleShade + '">' + strItem + '<div><a href="#" title="Sort ascending" onclick="javascript:clearSelects(); sortTable(' + j + ',1); return false"><img src="/images/arrow_up.gif" style="padding:2px; border:none"></a><br /><a href="#" title="Sort descending" onclick="javascript:clearSelects(); sortTable(' + j + ',2); return false"><img src="/images/arrow_down.gif" style="padding:2px; border:none"></a></div></td>';
				}else{
					styleAlign = ""; // Used for setting alignment on Features column.

					if((j == f1 || j == f2 || j == f3) && /* (i != 0) && */ (i%2 != 0)){
						shade = 'class="shade1"';
						strLinkBegin = "";
						strLinkEnd = "";
					}else if((j == f1 || j == f2 || j == f3) && /* (i != 0) && */ (i%2 == 0)){
						shade = 'class="shade2"';
						strLinkBegin = "";
						strLinkEnd = "";
					}else{
						shade = "";
						strLinkBegin = "";
						strLinkEnd = "";
					}
					if(j == 0) {  // Add Product Folder link.
						strLinkBegin = '<a href="prodfolder-' + strPage + '.asp?p=' + strItem + '">';
						strLinkEnd = '</a>';
					}
					// Align "Features" column
					if(typeof intColumnToAlign != "undefined") {
						if(j == intColumnToAlign)
							styleAlign = ' style="text-align:left;"';
					}

					sortRow += '<td ' + shade + styleAlign + '>' + strLinkBegin + strItem + strLinkEnd + '</td>';
				}
		}
		sorted += sortRow + '</tr>';
	}
	sorted += '</table>';
	document.getElementById('toSort').innerHTML = sorted;
}
// ~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!
// ~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!
function insertionSort(index, sortOrder, intSelectedIndex) {
//alert(index + " - " + sortOrder);
	for(i = 1; i < arr.length; i++) {
		var tempValue = ''; // Store "NaN"s.
		//insertItem(arr, 0, i);
		finished = false;
		current = i;
		moreToSearch = (current != 1 /*startIndex*/);
		
		if(sortOrder == 1 || sortOrder.length == 0) {  // Determine sort order
			strSort = "arr[current][index] < arr[current-1][index]";  // Ascending
			for(k = 0; k < intSelectedIndex.length; k++) {  // Determine if current index need parseInt().
				if(index == intSelectedIndex[k]) {
					strSort = "parseInt(arr[current][index]) < parseInt(arr[current-1][index])";
				}
				/*
				if(isNaN(parseInt(arr[current][index]))) { // If not an int, insert 0.
					strSort = "0 < parseInt(arr[current-1][index])";
				}
				*/
			}
		}else{
			strSort = "arr[current][index] > arr[current-1][index]";  // Descending
			for(k = 0; k < intSelectedIndex.length; k++) {  // Determine if current index need parseInt().
				if(index == intSelectedIndex[k]) {
					strSort = "parseInt(arr[current][index]) > parseInt(arr[current-1][index])";
				}
				/*
				if(isNaN(parseInt(arr[current][index]))) { // If not an int, insert large int.
					tempValue = arr[current][index];
					arr[current][index] = 99999999;
					strSort = "0 > parseInt(arr[current-1][index])";
				}
				*/
			}
		}
		
		while(moreToSearch && !finished) {
			//alert("before - " + arr[current][index]);
			if(eval(strSort)) {
				// Swap
				tempItem = "";
				tempItem = arr[current];
				arr[current] = arr[current-1];
				arr[current-1] = tempItem;
				current--;
				moreToSearch = (current != 1 /*startIndex*/);
				//alert("TRUE" + arr[current][index]);
			}else{
				//alert("FALSE" + arr[current][index]);
				finished = true;
				//arr[current][index] = tempValue;
			}
		}
	}
}
// ~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!
// ~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!~!

function sortTable(column, sortOrder){
	s1 = d.forms[1].sort1;
	s2 = d.forms[1].sort2;
	s3 = d.forms[1].sort3;
	f1 = s1.options[s1.selectedIndex].value;
	if(!(column == null))
		f1 = column;
//?? Use NEW way of selecting index below ??
	f2 = d.forms[1].sort2.selectedIndex - 1; //s2.options[s2.selectedIndex].value;
	f3 = s3.options[s3.selectedIndex].value;
	r1 = d.forms[1].rd1.value;
	if(!(sortOrder == null))
		r1 = sortOrder;
	r2 = d.forms[1].rd2.value;
	r3 = d.forms[1].rd3.value;

	if(f3 != -1)
		insertionSort(f3, r3, intSelectedIndex); //3rd column
	if(f2 != -1)
		insertionSort(f2, r2, intSelectedIndex); //2nd column
	if(f1 != -1)
		insertionSort(f1, r1, intSelectedIndex); //1st column
	
	if(f1 != -1 || f2 != -1 || f3 != -1)
		writeTable(f1, f2, f3);
}

/***************************************************************************
* imgLoaded(): Checks for existence of image.
***************************************************************************/
function imgLoaded(img) {
	// For IE.
	if (!img.complete) {
		return false;
	}
	// For non-IE.
	if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) {
		return false;
	}
	return true;
}
/***************************************************************************
* hideNonExistentImg(): Calls imgLoaded() and sets nonexisting images to display:none.
***************************************************************************/
//Call this function onLoad of body tag
function hideNonExistentImg() {
	for (var i = 0; i < document.images.length; i++) {
		if (!imgLoaded(document.images[i])) {
			document.images[i].style.display = "none";
		}
	}
}