/*  ------------------------
*	Library classes for constructing a template
*	all functions and properties that are preceded by _ are private
*	and should not be accessed from exterior code
*
*	Works in cooperation with the serverside templateServices.asp classes

*	Overall Version : 3.1
*		DropDownMenu is no longer compatible with versin 1.x code
*
*	1) DropDownMenu()
*	Starts the DropDownMenu produded by the serverside classes
*
*  ------------------------  */



/* =============================================================================================*/
var oTplUtils = new TemplateUtils()
function TemplateUtils() {
	
	/*  ------------------------
	*	Version 1.0
	*	Collection of utilities functins and properties for use with other
	*	classes in this package and for general use with templates.
	*  ------------------------  */
	
	/* properties that describe the browser type */
	this.BUA = navigator.userAgent;
	this.BIE = this.BUA.indexOf("MSIE");
	this.BIsIE = this.BIE>=0;
	this.BIsMaccak = this.BUA.indexOf("Mac")!=-1;
	this.BVer = this.BIE>=0 ? parseFloat(this.BUA.substring(this.BIE+5, this.BIE+6)+"."+this.BUA.substring(this.BIE+7, this.BIE+8)) : parseInt(navigator.appVersion.substring(0,1));

	/* properties for more descriptive accessing of navitems nodes */
	this.NODE_ID = 0;
	this.PARENT_NODE = 1;
	this.DISPLAY_TEXT = 2;
	this.HELP = 3;
	this.URL = 4;
	this.URL_TARGET = 5;
	
	this.hasChildren = function(navId){
		//pre:		true
		//post:		if navitem for the given navId has children then true will be returned else false
		//return:	boolean
		
		for (var i=0; i<=NavItems.length-1; i++) {
			if (NavItems[i][this.PARENT_NODE] == navId) {
				return true
			}
		}
	
		return false;
	}

	this.getNavItem = function(navId){
		//pre:		true
		//post:		An array containing the items for the navitem is returned
		//return:	boolean
	
		var navItem = Array();
	
		for (var i=0; i<NavItems.length; i++) {
			if (NavItems[i][this.NODE_ID] == navId) {
				navItem[this.NODE_ID] = NavItems[i][this.NODE_ID];
				navItem[this.PARENT_NODE] = NavItems[i][this.PARENT_NODE];
				navItem[this.DISPLAY_TEXT] = NavItems[i][this.DISPLAY_TEXT];
				navItem[this.HELP] = NavItems[i][this.HELP];
				navItem[this.URL] = NavItems[i][this.URL];
				navItem[this.URL_TARGET] = NavItems[i][this.URL_TARGET];
			}
		}
	
		return navItem;
	}

	this.navItemExists = function(id){
		//pre:		true
		//post:		if navitem for the given navId exists then true will be returned else false
		//return:	boolean

		var navItem = this.getNavItem(id)
		return navItem.length > 0;
	}
	
	this.buildAHREF = function(nodeId){
		//pre:		the navitem exists
		//post:		an <A HREF> tag string is returned based on the navitem values
		//return:	string
		
		var node = this.getNavItem(nodeId);
		
		return '<a href="'+node[this.URL]+'" '+(node[this.URL_TARGET] != '' ? 'target="'+node[this.URL_TARGET]+'"' : '')+'>'+node[this.DISPLAY_TEXT]+'</a>';
	}
	
	this.delegate = function( that, thatMethod ) {
		//create delage functions so that functions like setTimeout
		//can call methods of objects with 'this' as being the containing
		//object of the the method.
		//
		//When the delegate is created it may be given parameters to pass when it
		//it is called.
		//When the the function (that is returned by delegate) is executed it may
		//also be passed parameters. These will be added to the end of the parameter list
		//
		//eg: setTimeout(oCore.delete(obj, obj.method, param1, param2, param3), 1000);
		
		var params = [];
		for (var n = 2; n < arguments.length; ++n) {
			params.push(arguments[n]);
		}
		
		return function() {
			for (var cp = 0; cp < arguments.length; ++cp) {
				params.push(arguments[cp]);
			}
			return thatMethod.apply(that, params); 
		}
		
	}
}
/* =============================================================================================*/


/* =============================================================================================*/
function DropDownMenu(menuDomId) {
	
	/*  ------------------------
	*	Version 2.3
	*	Generates a drop down or slide out menu.
	*	This class generates a treed UL list from the navitem array and uses
	*	the CSS file "DDMenu.css". To change colour size etc of the menu
	*	manipulate the CSS file.
	*
	*	Usage: 
	*	After page loads
	*	1) "enableMenu()"
	*  ------------------------  */
	
	this._menuDomId = menuDomId;
	this._selectBoxList = new Array();
	this._menuULs = Array(); //internal variable for detecting menu direction


	this.enableMenu = function() {
		//pre:		true
		//post:		the menu is activated so sub menus roll out
		//			do after the page loads
		//return:	
		
		if (!document.getElementById(menuDomId)) {
			alert("The drop down menu UL list does not exist!!");
			return false;
		}
		
		this._DDMHover();
		document.getElementById(this._menuDomId).style.display = "block";
	}
	
	this._DDMHover = function() {
		var menuDomId = this._menuDomId;
		var DDMEls = document.getElementById(menuDomId).getElementsByTagName("LI");
		
		for (var i=0; i<DDMEls.length; i++) {
			DDMEls[i].oDDM = this;
			
			DDMEls[i].onmouseover = function(e) {
				if (oTplUtils.BIsIE) {
					this.className += " DDMhover";
				}
				this.oDDM._hoverDetectScreenOverflow(e ? e : event);
				this.oDDM._disableSelectInputs();
			}

			DDMEls[i].onmouseout = function() {
				if (oTplUtils.BIsIE) {
					this.className = this.className.replace(new RegExp(" DDMhover\\b"), "");
				}
				this.oDDM._enableSelectInputs();
			}
		}
	}
	
	this._disableSelectInputs = function() {
		var selectors = document.getElementsByTagName("select")
		for (var i=0; i<selectors.length; i++) {
			if (selectors[i].style.display != 'none') {
				var textInput = document.createElement('input');
				
				var obj = new Object()
				obj.selector = selectors[i];
				obj.textInput = textInput;
				
				this._selectBoxList[i] = obj;
				
				textInput.type = 'text';
				textInput.disabled = true;
				textInput.value = selectors[i].options[selectors[i].selectedIndex].text;
				textInput.style.width = selectors[i].clientWidth+'px';
				selectors[i].parentNode.insertBefore(textInput, selectors[i]);
				selectors[i].style.display = 'none';
			}
		}
	}
	
	this._enableSelectInputs = function() {
		for (var i=0; i<this._selectBoxList.length; i++) {
			if (this._selectBoxList[i] != '') {
				var selector = this._selectBoxList[i].selector
				var textInput = this._selectBoxList[i].textInput
				
				textInput.parentNode.removeChild(textInput);
				selector.style.display = 'inline';
				this._selectBoxList[i] = '';
			}
		}
	}
	
	this._hoverDetectScreenOverflow = function(e) {
		var target = e.srcElement ? e.srcElement : e.target;
		var thisUL = target;
		var menuX = 0;
		var browserWidth = 0;
		var branchWidth = 0;
		
		while ((thisUL.tagName != 'UL') && (thisUL.tagName != 'BODY')) {
			thisUL = thisUL.parentNode;
		}
		
		if (thisUL.id == this._menuDomId) {
			thisUL = target.parentNode.parentNode.childNodes[1];
			
			branchWidth = this._hoverDetectWidestBranch(thisUL);
			menuX = this._getElementXPosRelativeToScreen(thisUL);
			browserWidth = (window.innerWidth ? window.innerWidth : document.body.scrollWidth) - 20;
		
			if ((menuX + branchWidth) > browserWidth) {
				thisUL.className = ' leftAlign';
			} else if (thisUL) {
				//this may cause problems - check in future sites
				//thisUL.className = ' DDMhover';
			}
		}
	}
	
	this._hoverDetectWidestBranch = function(HTMLObj){
		if (!HTMLObj) {
			return 0;
		}
		
		var widestBranchWidth = HTMLObj.offsetWidth;
		var thisBranchesWidth = 0;
		
		this._menuULs = Array();
		this._hoverGetULsAtEndOfBranchesRC(HTMLObj);
		
		for(var i=0; i<this._menuULs.length; i++) {
			thisBranchesWidth = this._hoverDetectThisBranchesWidth(HTMLObj, this._menuULs[i]);
			if (thisBranchesWidth > widestBranchWidth) {
				widestBranchWidth = thisBranchesWidth;
			}
		}
		
		return widestBranchWidth;
	}
	
	this._hoverDetectThisBranchesWidth = function (topULObj, ULObj) {
		var width = topULObj.offsetWidth;
		
		while (ULObj != topULObj) {
			if (ULObj.tagName == 'UL') {
				width = width + ULObj.offsetWidth;
			}
			ULObj = ULObj.parentNode;
		}
		
		return width;
	}
	
	
	this._hoverGetULsAtEndOfBranchesRC = function(HTMLObj) {
		
		for (var i=0; i<HTMLObj.childNodes.length; i++) {
			var child = HTMLObj.childNodes[i];
			if (child.tagName == 'UL') {
				
				this._menuULs.push(child);
			}
			
			this._hoverGetULsAtEndOfBranchesRC(child);
		}
	}
	

	this._getElementXPosRelativeToScreen = function(elementObj) {
		var x = 0;
		
		if (!elementObj) {
			return x;
		}
		
		var element = elementObj.parentNode;
				
		while (element.tagName != 'BODY') {
			x = x + element.offsetLeft;
			element = element.parentNode;
		}
				
		return x;
	}
}
/* =============================================================================================*/