var navMenuId = "ParentTabs1";
var linkClass = "navLink";
var selectedLinkClass= "SelectedNavItem";
var subMenuClass = "subMenu";

var liElementHeight = 26;
var allMenus = [];
var allMenusLength = 0;
var openMenus = [];
var openMenusLength = 0;
var parentMenus = [];
var parentMenusLength = 0;
var childMenus = [];
var childMenusLength = 0;
var myMenuLinks = [];
var myMenuLinksLength = 0;
var topLevelLinks = [];
var topLevelLinksLength = 0;

var thisUl;
var myParentNode;
var myParentUl;
var menusToSlideOpen =[];
var menusToSlideOpenLength = 0;
var menusToSlideShut = [];
var menusToSlideShutLength = 0;
var menusToSlideHeight = [];
var menusToSlideLimit = [];

var slideCurrent = false; // variable to show slide is in progress
var sliderIntervalId = 0;
var slideSpeed = 20;

var menusToSlideRate = [];
var ratio = 0;
var dif = [];


jQuery(document).ready( function() {
  	var myLinks = [];
	var mySelectedLinks = [];
	var myNonSelectedLinks = [];
	var myLinksLength;
	
	myNonSelectedLinks = getElementsByClassName(linkClass, "a", document.getElementById(navMenuId));
	mySelectedLinks = getElementsByClassName(selectedLinkClass, "a", document.getElementById(navMenuId));
	myLinks = myNonSelectedLinks.concat(mySelectedLinks);
	myLinksLength = myLinks.length;
	
	if (myLinksLength == 0) {
		return;
	}
	
	//for (var i=0; i<myLinksLength; i++) { 
		//myLinks[i].onclick = function(evt) {processNavLinkClick(this); return false};
	//}
	
}); 

	function resetArrays() {
		menusToSlideOpen = [];
		allMenus = [];
		allMenus = [];
		openMenus = [];
		parentMenus = [];
		childMenus = [];
		myMenuLinks = [];
		topLevelLinks = [];
		menusToSlideOpen =[];
		menusToSlideShut = [];
		menusToSlideHeight = [];
		menusToSlideLimit = [];
	}
	
var processNavLinkClick = function(clickedLink) {
		if (slideCurrent) {
			return false;
		}		
		resetArrays();
		
		myParentNode = clickedLink.parentNode;
		//alert("parentNode " + myParentNode.id);
		myParentUl = myParentNode.parentNode;
		//alert("parentUl " + myParentUl.id);
		
		allMenus = getAllMenus();
		allMenusLength = allMenus.length;
	//	alert("All Menus: " + allMenusLength);
		//for (var i=0; i<allMenusLength; i++) {
		//	alert("all + " + i + " = " + allMenus[i].id);
	//	}
		
		openMenus = getOpenMenus();
		openMenusLength = openMenus.length;
		//for (var i=0; i<openMenusLength; i++) {
		//	alert("open + " + i + " = " + openMenus[i].id);
		//}
		//alert("Open Menus: " + openMenusLength);
		
		parentMenus = getParentMenus(clickedLink);
		parentMenusLength = parentMenus.length;
	//	for (var i=0; i<parentMenusLength; i++) {
		//	alert("parent + " + i + " = " + parentMenus[i].id);
		//}
		//alert("Parent Menus: " + parentMenusLength);
		
		// check that option has a sub menu - if not redirect to url
		thisUl = myParentNode.getElementsByTagName("ul")[0];
		
		if (!thisUl) {
			//alert("no subMenu - redirecting");
			window.location = clickedLink;
			return;
		} else {
			//alert("this id is " + thisUl.id);
			myMenuLinks = getImmediateSubMenuItems(thisUl);
			myMenuLinksLength = myMenuLinks.length;
			//alert("immediate links " + myMenuLinksLength);
			if (myMenuLinksLength == 0) {
				//alert("no subMenu - redirecting");
				window.location = clickedLink;
				return;
			} 
		}
		
		// check whether menu is currently open
		thisUlHeight = getStyle(thisUl, "height");
		//alert("this ul height is " + thisUlHeight);
		var newHeight = (myMenuLinksLength * liElementHeight);
		//alert("new height q is " + newHeight);
		if (thisUlHeight == "1px") {
				//	alert("Open");
		
			// open menu - add extra height into each parent element equal to new menu height
			menusToSlideOpen[parentMenusLength] = thisUl;
			menusToSlideHeight[parentMenusLength] = 1; 
			menusToSlideLimit[parentMenusLength] = newHeight;
			menusToSlideOpenLength = menusToSlideOpen.length;
			parentMenus = parentMenus.reverse();
			
			if (!parentMenusLength == 0) {
				for (var i=0; i<parentMenusLength; i++) {
					//alert("parent menu " + i + " is " + parentMenus[i].id);
					//return;
					menusToSlideOpen[i] = parentMenus[i];
					currentMenuHeight = getStyle(menusToSlideOpen[i], "height");
					if (currentMenuHeight == "auto") {
						currentMenuHeight = (menusToSlideOpen[i].offsetHeight);
					} else {
						currentMenuHeight = parseFloat(currentMenuHeight.substring(0, (currentMenuHeight.length - 2)));
						currentMenuHeight = (Math.round(currentMenuHeight));
					}
					menusToSlideHeight[i] = currentMenuHeight;
					menusToSlideLimit[i] = menusToSlideHeight[i] + newHeight;
				}
						
			} 
			

			
			for (var i=0; i<menusToSlideOpen.length; i++) {
			//	alert("menusToSlideOpen[" + i + "]: id is " + menusToSlideOpen[i].id + ", height is " + menusToSlideHeight[i] + ", limit is " + menusToSlideLimit[i]);
			}
			
			slider(true);
			
		} else {
			//alert("shut");
		
			var heightToRemove = 0;
			var counter = 0;
			
			childMenus = getOpenChildMenus(thisUl);
			childMenusLength = childMenus.length;
			//alert("newHeight is " + newHeight);
			childMenus = childMenus.reverse();
			//alert("this ul " + thisUl.id);
			
			for (var i=0; i<childMenusLength; i++) {
				//alert("child menu " + i + " is " + childMenus[i].id);
				menusToSlideShut[counter] = childMenus[i];
				currentMenuHeight = getStyle(menusToSlideShut[counter], "height");
				if (currentMenuHeight == "auto") {
						currentMenuHeight = (menusToSlideOpen[i].offsetHeight);
				} else {
					currentMenuHeight = parseFloat(currentMenuHeight.substring(0, (currentMenuHeight.length - 2)));
					currentMenuHeight = (Math.round(currentMenuHeight));
				}
				menusToSlideHeight[counter] = currentMenuHeight;
				menusToSlideLimit[counter] = 1;
				counter++;
				//alert("child menu " + i + " is " + childMenus[i].id);
				//alert("child menu " + i + " height is " + currentMenuHeight);
				//alert("child menu " + i + " limit is " + menusToSlideLimit[counter]);
				//alert("Menu " + menusToSlideShut[i].id + " height is " + menusToSlideHeight[i]);
			}
			
			menusToSlideShut[counter] = thisUl;
			currentMenuHeight = getStyle(menusToSlideShut[counter], "height");
			if (currentMenuHeight == "auto") {
				currentMenuHeight = (menusToSlideOpen[i].offsetHeight);
			} else {
				currentMenuHeight = parseFloat(currentMenuHeight.substring(0, (currentMenuHeight.length - 2)));
				currentMenuHeight = (Math.round(currentMenuHeight));
			}
			menusToSlideHeight[counter] = currentMenuHeight;
			menusToSlideLimit[counter] = 1;
			newHeight = currentMenuHeight;
			counter++;
			
			//alert("parent length " + parentMenusLength);
			//alert("in between newHeight is " + newHeight);
			var parentOffset = newHeight;
			for (var i=0; i<parentMenusLength; i++) {
				//alert("parent menu " + i + " is " + parentMenus[i].id);
				menusToSlideShut[counter] = parentMenus[i];
				currentMenuHeight = getStyle(menusToSlideShut[counter], "height");
				if (currentMenuHeight == "auto") {
					currentMenuHeight = (menusToSlideOpen[i].offsetHeight);
				} else {
					currentMenuHeight = parseFloat(currentMenuHeight.substring(0, (currentMenuHeight.length - 2)));
					currentMenuHeight = (Math.round(currentMenuHeight));
				}
				menusToSlideHeight[counter] = currentMenuHeight;
				//alert("for parent " + parentMenus[i].id + " currentMenuHeight is " + currentMenuHeight + " and new height is " + newHeight);
				menusToSlideLimit[counter] = (currentMenuHeight - newHeight);
				counter++;
			}
			
			menusToSlideShutLength = menusToSlideShut.length;
			//for (var i = 0; i<menusToSlideShutLength; i++) {
			//	alert("shutMenu " + i + " is " + menusToSlideShut[i].id + ", currentHeight is " + menusToSlideHeight[i] + ", limit is " + menusToSlideLimit[i]); 
		//	}
			
			//return;
			slider(false);
			
		}
		
	}


	var slider = function(open) {
		
		
		var biggest = 0;
		if (slideCurrent) {
     		return;
		}
		
		slideCurrent = true;
		
		if (open == true) {
			sliderIntervalId = setInterval("slideOut()", 50);
		} else {
			for (var i=0; i<menusToSlideShutLength; i++) {
				dif[i] = menusToSlideHeight[i] - menusToSlideLimit[i];
				//alert("dif for " + i + " is " + dif[i]);
				if (dif[i] > biggest) {
					biggest = dif[i];
				}
			}
			
			for (var i=0; i<menusToSlideShutLength; i++) {
			
				menusToSlideRate[i] = slideSpeed / (biggest/dif[i]);
			//	alert("slide rate " + i + " is " + menusToSlideRate[i]);
			}
			//return;
			sliderIntervalId = setInterval("slideIn()", 50);
		
		
		}
		
	}
	
	var slideOut = function() {
		//alert("starting slide");
		if (menusToSlideHeight[0] >= menusToSlideLimit[0]) {

			slideCurrent = false;
			for (var i=0; i<menusToSlideOpenLength; i++) {
				menusToSlideHeight[i] = menusToSlideLimit[i];
				menusToSlideOpen[i].style.height = menusToSlideLimit[i] + "px";
				clearInterval(sliderIntervalId);
			

			}
		} else {
			for (var i=0; i<menusToSlideOpenLength; i++) {
				menusToSlideHeight[i] += slideSpeed;
				if (menusToSlideHeight[i] > menusToSlideLimit[i]) {
					menusToSlideHeight[i] = menusToSlideLimit[i];
				}
				
				menusToSlideOpen[i].style.height = menusToSlideHeight[i] + "px";
			}
		}	
	}	
		
	var slideIn = function() {
		//alert("starting slide in");
		//for (var i=0; i<menusToSlideShutLength; i++) {
		//	alert(i + " would be sliding " + menusToSlideShut[i].id + " from " + menusToSlideHeight[i] + " to " + menusToSlideLimit[i]);
	//	}
	//	clearInterval(sliderIntervalId);
	//	return;
	
		if (menusToSlideHeight[0] <= menusToSlideLimit[0]) {

			slideCurrent = false;
			for (var i=0; i<menusToSlideShutLength; i++) {
				menusToSlideHeight[i] = menusToSlideLimit[i];
				menusToSlideShut[i].style.height = menusToSlideLimit[i] + "px";
				clearInterval(sliderIntervalId);
				
			}
		} else {
			for (var i=0; i<menusToSlideShutLength; i++) {
				//alert("sliding " + menusToSlideShut[i].id);
				menusToSlideHeight[i] -= menusToSlideRate[i];
				if (menusToSlideHeight[i] < menusToSlideLimit[i]) {
					menusToSlideHeight[i] = menusToSlideLimit[i];
				}
				
				menusToSlideShut[i].style.height = menusToSlideHeight[i] + "px";
			}
		}	
	}
	

	
	
	// function to return all menus
	var getAllMenus = function() {
		var myAllMenus = [];
		myAllMenus = getElementsByClassName(subMenuClass, "ul", document.getElementById(navMenuId));
		return myAllMenus;
	}
	
	// function to return parent menus
	var getParentMenus = function(clickedLink) {
		var myParentMenus = [];
		var testNode = clickedLink;
		var arrayCounter = 0;
		
		do {
			//alert("testing " + testNode.id);
			if ((testNode.nodeType == 1) && (testNode.tagName == "UL" || testNode.nodeName == "UL")) {
				//alert("adding parent " + testNode.id);
				myParentMenus[arrayCounter] = testNode;
				arrayCounter++;
			}
			testNode = testNode.parentNode;
		//alert("test node is now " + testNode.id + " type is " + testNode.tagName + " navMenuId is " + navMenuId);
		} while(!(testNode.id == navMenuId));
		
		return myParentMenus;	
	}
	
	// function to return open menus
	var getOpenMenus = function() {
		var myOpenMenus = [];
		var arrayCounter = 0;
		var currentMenuHeight;
		
		for (var i=0; i<allMenusLength; i++) { 
			//alert("open menu test " + allMenus[i].id);
			currentMenuHeight = getStyle(allMenus[i], "height");
			if (!(currentMenuHeight == "1px")) {
				myOpenMenus[arrayCounter] = allMenus[i];
				arrayCounter++;
			}
		}
		
		return myOpenMenus;
	}
	
	var getChildMenus = function(myElement) {
		var myChildMenus = [];
		myChildMenus = getElementsByClassName(subMenuClass, "ul", myElement);
		return myChildMenus;
	}
	
	var getOpenChildMenus = function(myElement) {
		var myChildMenus = [];
		var myOpenChildMenus = [];
		var counter = 0;
		myChildMenus = getElementsByClassName(subMenuClass, "ul", myElement);
		//alert("child length is " + myChildMenus.length);
		var testHeight;
		
		for (var i=0; i<myChildMenus.length; i++) {
			//alert("child id is " + myChildMenus[i].id);
			testHeight = getStyle(myChildMenus[i], "height");	
			//alert("testing " + testHeight);
			if (!(testHeight == "1px")) {
				//alert("adding child " + myChildMenus[i].id);
				myOpenChildMenus[counter] = myChildMenus[i];
				counter++;
			}
		}
		
		return myOpenChildMenus;
	}
	var getImmediateSubMenuItems = function(ulElement) {

		var allSubLinks = [];
		var allSubLinksLength = 0;

		allSubLinks = ulElement.getElementsByTagName("li");
		allSubLinksLength = allSubLinks.length;

	var currentSubMenuClass = allSubLinks[0].className;
	var immediateSubMenuLinks = [];
	var immediateSubMenuCounter = 0;

	for (var i=0; i<allSubLinksLength; i++) { 
		if (allSubLinks[i].className == currentSubMenuClass) {
			immediateSubMenuLinks[immediateSubMenuCounter] = allSubLinks[i];
			immediateSubMenuCounter++;
		}
	}
	
	return immediateSubMenuLinks;
	
}

	var getTopLevelLinks = function() {
		var myTopLevelLinks = [];
		myTopLevelLinks = getElementsByClassName(topLevelClass, "li", document.getElementById(navMenuId));
		return myTopLevelLinks;
	}


	/*

	  excellent code for replicating getElementsByClassName for 
	  browsers that don't support it natively many thanks to Robert Nyman - 
	  Developed by Robert Nyman, http://www.robertnyman.com
	
	  Code/licensing: http://code.google.com/p/getelementsbyclassname/

	*/	

	var getElementsByClassName = function (className, tag, elm) {

		if (document.getElementsByClassName) {
		
			getElementsByClassName = function (className, tag, elm) {

				elm = elm || document;
			
				var elements = elm.getElementsByClassName(className),
				
					nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
				
					returnElements = [],

					current;

				for(var i=0, il=elements.length; i<il; i+=1){

					current = elements[i];

					if(!nodeName || nodeName.test(current.nodeName)) {

						returnElements.push(current);

					}

				}

				return returnElements;

			};

		}
	
	else if (document.evaluate) {

			getElementsByClassName = function (className, tag, elm) {

				tag = tag || "*";

				elm = elm || document;

				var classes = className.split(" "),

					classesToCheck = "",

					xhtmlNamespace = "http://www.w3.org/1999/xhtml",

					namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,

					returnElements = [],

					elements,

					node;

				for(var j=0, jl=classes.length; j<jl; j+=1){

					classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";

				}
 
				try {

					elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);

				}

				catch (e) {

					elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);

				}

				while ((node = elements.iterateNext())) {

					returnElements.push(node);

				}

				return returnElements;

			};

		}

		else {

			getElementsByClassName = function (className, tag, elm) {

				tag = tag || "*";

				elm = elm || document;

				var classes = className.split(" "),

					classesToCheck = [],

					elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),

					current,

					returnElements = [],

					match;

				for(var k=0, kl=classes.length; k<kl; k+=1){

					classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));

				}

				for(var l=0, ll=elements.length; l<ll; l+=1){

					current = elements[l];

					match = false;

					for(var m=0, ml=classesToCheck.length; m<ml; m+=1){

						match = classesToCheck[m].test(current.className);

						if (!match) {

							break;

						}

					}

					if (match) {

						returnElements.push(current);

					}

				}

				return returnElements;

			};

		}

		return getElementsByClassName(className, tag, elm);

	};

	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;
	}
	
