/*****************************************************************************************
 *
 *							Standard Areeba js functionality
 *
 ****************************************************************************************/

// ---------------------------------------------------------------------
// 	arb
// 	This provides us with a namespace.  Everything in this file is under arb.XXX
//  so as not to interfere with the operation of any other included scripts.
// ---------------------------------------------------------------------
var arb = { };

arb.init = function() {
	arb.form.initPromptText();	
	arb.form.initFocusHighlighting();	
	arb.form.initPopupHelp();
	arb.functions.printLink('print-link');
	arb.functions.expandMenu('secondary-navigation');
};

arb.event = {
	// ---------------------------------------------------------------------
	// 	arb.event.addHandler
	// 	add the given event handler, preserving existing event handler functions
	// ---------------------------------------------------------------------
	addHandler: function (elem, eventName, func) {
		// make a function which lets 'this' be used in our handlers and fixes e to point to an event
		var handlerFunc = function(e) {
			e = e ? e : window.event;
			elem.__f = func;
			var s = elem.__f(e);
			elem.__f = null;
			return s;
		}
		
		var currentHandler = elem['on' + eventName];
		if (typeof(currentHandler) == 'function') { // not first handler
			elem['on' + eventName] = function(e) {
				var x = currentHandler(e);
				var y = handlerFunc(e);
				return x && y;
			}	
		} else { // first handler
			elem['on' + eventName] = handlerFunc;
		}
	 }
};


arb.event.standardHandler = {
	hover: function(element, hoverClass) {
		hoverClass = (hoverClass != null) ? hoverClass : 'arbHover'; 
		arb.event.addHandler(element, 'mouseover', function() { arb.element.addClass(this, 'arbHover'); } );
		arb.event.addHandler(element, 'mouseout', function() { arb.element.removeClass(this, 'arbHover'); } );
	}
};


arb.element = {
	// ---------------------------------------------------------------------
	//	arb.element.addClass()
	//	appends the specified class to the given element
	// ---------------------------------------------------------------------
	addClass: function(theNode, theClass) {
		if (theNode.className == '') {
			theNode.className = theClass;
		} else {
			theNode.className += ' ' + theClass;
		}
	},
	
	// ---------------------------------------------------------------------
	//	arb.element.removeClass()
	//	removes the specified class to the given element
	// ---------------------------------------------------------------------
	removeClass: function(theNode, theClass) {
		var oldClass = theNode.className;
		var regExp = new RegExp('\\s?\\b'+theClass+'\\b');
		if (oldClass.match(regExp) != null) {
			theNode.className = oldClass.replace(regExp,'');
		}
	},
	
	hasClass: function(elem, theClass) {
		var regExp = new RegExp('\\b'+theClass+'\\b');
		return (elem.className.match(regExp) != null);
	},
	
	// ---------------------------------------------------------------------
	//	arb.element.getCSSProperty()
	//	read the value of the style for the given element.
	// ---------------------------------------------------------------------
	getCSSProperty: function(oNode, sProperty) {
		if(document.defaultView) {
			return document.defaultView.getComputedStyle(oNode, null).getPropertyValue(sProperty);
		} else if(oNode.currentStyle) {
			for(var reExp = /-([a-z])/; reExp.test(sProperty); sProperty = sProperty.replace(reExp, RegExp.$1.toUpperCase())) {
				;
			}
			return oNode.currentStyle[sProperty];
		}
		else {
			return null;
		}
	},
	
	moveChildren: function(fromElem, toElem) {
		var nextChild;
		for(var child = fromElem.childNodes[0]; child != null; child = nextChild) {
			var nextChild = child.nextSibling;
			fromElem.removeChild(child);
			toElem.appendChild(child);
		}
	}
};

arb.element.position = {
	left: function(el){
		var l=el.offsetLeft;
		while((el=el.parentNode) && el!=document)
			l+=el.offsetLeft;
		return l;
	},
	
	top: function(el){
		var t=el.offsetTop;
		while((el=el.parentNode) && el!=document)
			t+=el.offsetTop || 0;
		return t;
	}		
};


arb.form = {
	// ---------------------------------------------------------------------
	//	arb.form.promptText()
	//	add event handlers to any <input> on the page with a 'promptValue' attribute to 
	//  display the promptValue as the Value when the Value is empty, and to clear the Value
	//  when the input is focus'ed.  While the <input> is displaying the promptValue, it has 
	//  a class of 'displayingPromptValue' applied to it.
	// ---------------------------------------------------------------------
		initPromptText: function() {
		/* 
		 * local function definitions 
		 */
		function _cleanupPromptTextOnSubmit(e) {
			var inputs = this.getElementsByTagName('input');
			for(var j=0; j < inputs.length; j++) {
				_clearPromptText(inputs[j]);
			}			
		}	
		function _clearPromptText(elem) {
			if($(elem).hasClass('replaced-password')) {
				var $text = $(elem);
				elem = $text.prev()[0];
				_clearPromptText(elem);
				$(elem).show();
				elem.focus();
				$text.remove();
				return;
			}
			if(elem.value == elem.getAttribute("title")) {
				elem.value = "";
				arb.element.removeClass(elem, 'displayingPromptValue');
			}
		}
		function _addPromptText(elem) {
			/* only add the prompt text if this item isn't disabled */
			if((elem.getAttribute('disabled') == null || elem.getAttribute('disabled') == false) 
				&& (!elem.value || elem.value == "" || elem.value == elem.getAttribute("title"))) {
				elem.value = elem.getAttribute("title");
				arb.element.addClass(elem, 'displayingPromptValue');
				if (elem.type == 'password') {
					$(elem).hide();
					var $text = $("<input type='text' />");
					$text.val(elem.value);
					$text.attr('class', $(elem).attr('class'));
					$text.addClass('replaced-password');
					$(elem).after($text);
					$text.bind('focus', _clearPromptTextHandler);
				}
			}
		}

		function _clearPromptTextHandler(e) { _clearPromptText(this); }
		function _replacePromptText(e) { _addPromptText(this); } 			

		/* 
		 * Start of function code 
		 */
		if(!document.getElementsByTagName) return false;
		var forms = document.getElementsByTagName('form');
		
		for(var i = (forms.length - 1); i > -1; i--) { 
			var inputs = forms[i].getElementsByTagName('input');
			arb.event.addHandler(forms[i], 'submit', _cleanupPromptTextOnSubmit);
			for(var j=0; j < inputs.length; j++) {
				var theInput = inputs[j];
				if(theInput.getAttribute("title")) {
					var selectedNode;
					// IE only, check if we're already focused
					if (typeof document.selection != "undefined" && document.selection != null && typeof window.opera == "undefined") {
						/* find the currently focused page element */
						selectedNode = document.selection.createRange().parentElement();
					}
					/* only insert prompt text at start if not focused in input */
					if(selectedNode != theInput) {
						_addPromptText(theInput);
					}
					/* add the focus and blur handlers to add/remove prompt text */
					arb.event.addHandler(theInput, 'focus', _clearPromptTextHandler);
					arb.event.addHandler(theInput, 'blur', _replacePromptText);
				}
			}
		}		
	},
				
	// ---------------------------------------------------------------------
	//	arb.form.initFocusHighlighting()
	//	add event handlers to any <input> on the page with an associated <label> which will
	//  add a class of 'arbHasFocus' to both items when the input is focused.
	// ---------------------------------------------------------------------
		initFocusHighlighting: function() {
			/* 
			 * local function definitions 
			 */
			function _focus(e) {
				if(arb.element.hasClass(this, 'arbHasFocus')) return true;
				arb.element.addClass(this, 'arbHasFocus');
				for(var i = 0; i < this._labels.length; i++) {
					arb.element.addClass(this._labels[i], 'arbHasFocus');
				}
			}
			
			function _blur(e) {
				arb.element.removeClass(this, 'arbHasFocus');
				for(var i = 0; i < this._labels.length; i++) {
					arb.element.removeClass(this._labels[i], 'arbHasFocus');			
				}
			}

			/* 
			 * Start of function code 
			 */
			if(!document.getElementsByTagName) return true;
			
			var labels = document.getElementsByTagName('label');
			
			for(var i = (labels.length -1); i > -1; i--) {
				var inputID = labels[i].getAttribute('for') ? labels[i].getAttribute('for') : labels[i].getAttribute('htmlFor');
				if(inputID) {
					var input = document.getElementById(inputID);
					if(!input._labels) input._labels = new Array();
					input._labels.push(labels[i]);
					arb.event.addHandler(input, 'focus', _focus);
					arb.event.addHandler(input, 'blur', _blur);
				}
			}
		},
		
		initPopupHelp: function() {
			var divs = document.getElementsByTagName('div');

			for(var i = (divs.length - 1); i > -1; i--) {
				if(arb.element.hasClass(divs[i], 'longHelp')) {
					var div = divs[i];
					
					/* create the 4 required divs */
					var divHoverTarget = document.createElement('div');
					var divInnerOne = document.createElement('div');		
					var divInnerTwo = document.createElement('div');		
					var divInnerThree = document.createElement('div');		
					
					/* add classes to them */
					arb.element.addClass(divHoverTarget, 'longHelpIcon');
					arb.element.addClass(divInnerOne, 'InnerOneLongHelp');
					arb.element.addClass(divInnerTwo, 'InnerTwoLongHelp');
					arb.element.addClass(divInnerThree, 'InnerThreeLongHelp');
					
					/* move the help content to the innermost div */
					arb.element.moveChildren(div, divInnerThree);
					
					/* put the help icon div where the content div was */
					div.parentNode.replaceChild(divHoverTarget, div);
					/* append all the divs to each other in the right order */
					divHoverTarget.appendChild(div);
					div.appendChild(divInnerOne);
					divInnerOne.appendChild(divInnerTwo);
					divInnerTwo.appendChild(divInnerThree);

					/* attach the hover handlers to the icon div */
					arb.event.standardHandler.hover(divHoverTarget);
				}
			}
		}
};

arb.base = {
	// ---------------------------------------------------------------------
	//	arb.base.debug()
	//	Print passed messages to an onscreen box
	// ---------------------------------------------------------------------
	debugCounter: 0,
	debug: function(strMessage) {
		var debugBox = document.getElementById('debugBox');
		var msgP = document.createElement('DIV');
		msgP.appendChild(document.createTextNode(arb.base.debugCounter + ': ' + strMessage));
		arb.base.debugCounter++;
		
		if(!debugBox) {
			debugBox = document.createElement('DIV');
			debugBox.style.position = 'absolute';
			debugBox.style.width = '280px';
			debugBox.style.height = '280px';
			debugBox.style.top = '0';
			debugBox.style.right = '0';
			debugBox.style.backgroundColor = "#dddddd";
			debugBox.style.border = '1px solid #aaaaaa';
			debugBox.style.overflow = 'auto';
			debugBox.onclick = function(){this.style.display = 'none';};
			debugBox.id = 'debugBox';
			document.body.appendChild(debugBox);
		}
		debugBox.style.display = 'block';
		debugBox.insertBefore(msgP, debugBox.firstChild);
	}
};


arb.functions = {
	// ---------------------------------------------------------------------
	//	arb.functions.expandMenu()
	//	traverses a ul/li/a menu structure under an element with the passed id
	//  and determines which item is the current page.
	//  Marks the current page's item with a class of 'active', and all it's 
	//  parents with a class of 'expanded'.
	// ---------------------------------------------------------------------
	expandMenu: function(id) {
		if(!document.getElementById) return;
		
		var menu = document.getElementById(id);
		if(!menu) return;
		
		var menuItems = menu.getElementsByTagName("a");
		var activeMenuItem;
		
		// set the class of "menusExpanded" on a new child of the top level menu
		// containing all the previous children.
		var innerDiv = document.createElement('div');
		arb.element.addClass(innerDiv, 'menusExpanded');	
		arb.element.moveChildren(menu, innerDiv)
		menu.appendChild(innerDiv);
		
		// find the currently active menu item.  If the page exists in more than one place
		// in the navigation heirarchy, this will only find one.  Which one depends on the
		// order of links returned by getElementsByTagName("a")
		for (var i=0; i<menuItems.length; i++){
			if (menuItems[i].href == document.location.href) {
				activeMenuItem = menuItems[i];
				break;
			}
		}
		
		// put a class of 'active' on the active menu item, and 'expanded' on it's parent items
		if(activeMenuItem) {
			var parent = activeMenuItem.parentNode;  // our enclosing 'li'
			arb.element.addClass(parent, 'active');
			while(parent != menu) {
				if(parent.nodeName == "LI" || parent.nodeName == "UL") {
					arb.element.addClass(parent, 'expanded');
				}
				parent = parent.parentNode;
			}
		}
	},	
	
	// ---------------------------------------------------------------------
	//	arb.functions.showDiv()
	//  Author: Stuart Vaughan
	//  Date  : 2006-02-15
	//  Notes : Sets an element to be visible.
	// ---------------------------------------------------------------------
	showDiv: function(sDivName) {
		document.getElementById(sDivName).style.display = 'block';
	},
	
	// ---------------------------------------------------------------------
	//	arb.functions.hideDiv()
	//  Author: Stuart Vaughan
	//  Date  : 2006-02-15
	//  Notes : Sets an element to be hidden.
	// ---------------------------------------------------------------------	
	hideDiv: function(sDivName) {
		document.getElementById(sDivName).style.display = 'none';
	},

	printLink: function(id) {
		/* browser feature check */
		if(!document.getElementById || !window.print) return true;
		
		/* get the dummy print element which we'll replace */
		var printElement = document.getElementById(id);
		if(!printElement) return true;
		
		/* create our print link, it just points to the current page */
		var linkElement = document.createElement('a');
		linkElement.setAttribute('href','#');
		
		/* give it the id of the dummy element */
		linkElement.setAttribute('id', id);
		
		/* add an onclick event handler which will print the window */
		arb.event.addHandler(linkElement, 'click', function() { window.print(); return false; } );
		
		/* replace the dummy element with the link element */
		printElement.parentNode.replaceChild(linkElement, printElement);
	}

};

arb.event.addHandler(window, 'load', arb.init);



// ---------------------------------------------------------------------
//                      array.push (if unsupported)
// ---------------------------------------------------------------------
if(Array.prototype.push == null) {
  Array.prototype.push = function(item) {
    this[this.length] = item;
    return this.length;
  };
};

