/* SWIM2.0 :: Simple website menu
****************************************************************
* DOM scripting by brothercake -- http://www.brothercake.com/
* Licensed under GPL -- http://www.gnu.org/copyleft/gpl.html
****************************************************************
* For professional menu solutions visit -- http://www.udm4.com/ 
****************************************************************
*/

//var baseurl = "http://www.hjb.com.au";

//initialise the menu(s)
//you can replace this with an encapsulated onload if necessary
// http://www.brothercake.com/site/resources/onload/
//you can also take it out of this script and put it somewhere else
window.onload = function()
{
	//create a new menu ('menu-id', 'orientation')
	var verticals = new simpleMenu('menu-v', 'vertical');
//	var horizontals = new simpleMenu('menu-h', 'horizontal');
};


//menu object constructor
function simpleMenu(navid, orient)
{
	//if the dom is not supported, or this is opera 5 or 6, don't continue
	if(typeof document.getElementById == 'undefined' || /opera[\/ ][56]/i.test(navigator.userAgent)) { return; }
	
	//identify konqueror
	this.iskde = navigator.vendor == 'KDE';

	//identify internet explorer [but both opera and konqueror recognise the .all collection]
	this.isie = typeof document.all != 'undefined' && typeof window.opera == 'undefined' && !this.iskde;
	this.isie7 = this.isie && (navigator.appVersion.indexOf('MSIE 7') != -1);

	//identify old safari [< 1.2]
	this.isoldsaf = navigator.vendor == 'Apple Computer, Inc.' && typeof XMLHttpRequest == 'undefined';

	//ul tree
	this.tree = document.getElementById(navid);
	
	//if it exists
	if(this.tree != null)
	{
		//get trigger elements
		this.items = this.tree.getElementsByTagName('li');
		this.itemsLen = this.items.length;

		//initialise each trigger, using do .. while because it's faster
		var i = 0; 
		do
		{
			this.init(this.items[i], this.isie, this.isie7, this.isoldsaf, this.iskde, navid, orient, this.tree);
		}
		while (++i < this.itemsLen);
	}
}


//trigger initialiser
simpleMenu.prototype.init = function(trigger, isie, isie7, isoldsaf, iskde, navid, ishoriz, masterList)
{
	// store link to master list
	trigger.masterList = masterList;
	
	//store menu object, or null if there isn't one
	//extend it as a property of the trigger argument
	//so it's global within [and unique to] the scope of this instantiation
	//which is the same trick as going "var self = this"
	trigger.menu = trigger.getElementsByTagName('ul').length > 0 ? trigger.getElementsByTagName('ul')[0] : null;
		
	//store link object
	trigger.link = trigger.getElementsByTagName('a')[0];	

	//store whther this is a submenu or child menu
	//a submenu's parent node will have the navbar id
	trigger.issub = trigger.parentNode.id == navid;	
	
	//whether this is a horizontal navbar
	trigger.ishoriz = ishoriz == 'horizontal';	
	
	
	try{
		if(trigger.menu != null /*&& trigger.parentNode.id != "menu-v"*/){
			var linkText = document.createTextNode(trigger.link.firstChild.nodeValue);
			//trigger.link.className='hasmenu';
			var img = document.createElement('img');
			img.setAttribute('src','/_template/_images/submenu_arrow.gif');
			img.setAttribute('border','0');
			if(isie && !isie7) img.setAttribute('hspace','3');
			img.setAttribute('align','right');
			trigger.link.removeChild(trigger.link.firstChild);
			
			// reverse these lines to align left
			trigger.link.appendChild(img);		
			trigger.link.appendChild(linkText);					
		}
	
	
		if(trigger.link == document.location.href.replace("%5F","_")){					
			if(trigger.parentNode.className=="vertical"){						
				// top level menu
				if(trigger.className.length>0){					
					trigger.className +=" down";					
				}else{				
					trigger.className ="down";
				}
				if(trigger.menu) trigger.menu.className="down";		
			}else if(trigger.parentNode.parentNode.nodeName=="LI"){
				// submenu
				trigger.className="down";				
				trigger.parentNode.className="down";
				
				// make all menus up the chain "down"
				var node = trigger;
				while(node.className!="vertical"){					
					if(node.nodeName=="UL"){
						node.className="down";												
					}
					// set top level to "down"
					if(node.parentNode.className=="vertical"){
						node.getElementsByTagName('A')[0].className+= " down";
					}
					node = node.parentNode;					
				}								
				//node.getElementsByTagName('A')[0].className+= " down";
								
				if(trigger.menu!=null) trigger.menu.className="down";	
				
				//trigger.parentNode.parentNode.getElementsByTagName('a')[0].className="down";
			}else if(trigger.parentNode.parentNode.nodeName=="DIV"){
				trigger.className="down";
			}
	
			trigger.link.className="down";
			
			var c = document.getElementById("container").offsetHeight;
			var n = document.getElementById("menu-v").offsetHeight;
			var menu = document.getElementById("menu-v");
			var menuPos = findPosY(menu);
			
			//alert(n+","+c+","+menuPos);
			
			if(n>c){
				document.getElementById("container").style.height = (n+30)+"px";
				if(isie)
					document.getElementById("footer").style.top = (n+menuPos+30)+"px";
			}
		}
	
	}catch(e){
		
	}
	
	
	//menu opening events
	//onfocus doesn't bubble in ie, but its proprietary 'onactivate' event does
	//which works in win/ie5.5+
	this.openers = { 'm' : 'onmouseover', 'k' : (isie ? 'onactivate' : 'onfocus') };

	//bind menu openers
	for(var i in this.openers)
	{
		trigger[this.openers[i]] = function(e)
		{			
			// [CC] ignore "down" menu
			if(trigger.menu && trigger.menu.className == "down") return;					
			
			//set rollover persistence classname -- we have to check for an existing value first
			//because some opera builds don't allow the class attribute to have a leading space
			//don't do persistent rollovers for konqueror, because they stick in kde <= 3.0.4
			if(!iskde) { trigger.link.className += (trigger.link.className == '' ? '' : ' ') + 'rollover'; }

			//if trigger has a menu
			if(trigger.menu != null)
			{				
				// HJB ONLY
				// set select boxes invisible (ie6 only)
				if(isie && !isie7){
					document.getElementById("wrapper").className = "hover";
				}
				
				//if this is a horizontal navbar and a first-level submenu 
				//set the top position to auto [css] or compute a position [compute]
				//otherwise set it to 0 [css] or compute a position [compute]
				trigger.menu.style.top = (trigger.ishoriz && trigger.issub) ? (isie || (trigger.ishoriz && isoldsaf)) ? trigger.link.offsetHeight + 'px' : 'auto' : (isie || (trigger.ishoriz && isoldsaf)) ? trigger.offsetTop + 'px' : '0';
				
				
				
				if(isie7) trigger.menu.style.top = 0+'px';
		

				
				var winHeight = (isie) ? document.body.clientHeight : window.innerHeight;
				var menuPos = findPosY(trigger);
				var menuHeight =  trigger.menu.offsetHeight;
				var menuBottom = menuPos + menuHeight;
				if(isie && !isie7){
					var scrollPos = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop
				}else{
					var scrollPos = window.pageYOffset;
				}			
				var overlap = menuBottom - (winHeight + scrollPos);
				
				if(isie && !isie7){
					var adjustedPos = (trigger.offsetTop-overlap);			
				}else{
					var adjustedPos = -overlap;
				}
				
				//var msg = ("winHeight="+winHeight+", menuBottom="+menuBottom+" : menuPos="+menuPos+", menuHeight="+menuHeight+", scrollPos="+scrollPos+", overlap="+overlap+", adjustedPos="+adjustedPos);
				//window.status = msg;
				//debug(msg);
				
				if(overlap > 0 ){
					trigger.menu.style.top = (adjustedPos)+'px';					
				}
				
				
			}
		};
	}


	//menu closing events
	//'ondeactivate' is the equivalent blur handler for 'onactivate'
	this.closers = { 'm' : 'onmouseout', 'k' : (isie ? 'ondeactivate' : 'onblur') };

	//bind menu closers
	for(i in this.closers)
	{
		trigger[this.closers[i]] = function(e)
		{
			// HJB ONLY
			// reset select boxes visible (ie6 only)
			if(isie && !isie7){
				document.getElementById("wrapper").className = null;
			}
			
			// [CC] ignore "down" menu
			if(trigger.menu && trigger.menu.className == "down") return;
		

			//store event-related-target property
			this.related = (!e) ? window.event.toElement : e.relatedTarget;

			//if event came from outside current trigger branch
			if(!this.contains(this.related))
			{
				//reset rollover persistence classname; not for konqueror
				if(!iskde) { trigger.link.className = trigger.link.className.replace(/[ ]?rollover/g, ''); }
				
				//if trigger has a menu
				if(trigger.menu != null)
				{
					//hide menu using left for a horizontal menu, or top for a vertical
					trigger.menu.style[(trigger.ishoriz ? 'left' : 'top')] = trigger.ishoriz ? '-10000px' : '-100em';
				}
			}
		};
	}


	//contains method by jkd -- http://www.jasonkarldavis.com/
	//not necessary for ie because we're re-creating in ie-proprietary method
	//and it would throw errors in mac/ie5 anyway
	//not actually necessary for opera 7 either, because it's already implemented
	//but it won't do any harm, so spoofing doesn't matter
	if(!isie)
	{
		trigger.contains = function(node)
		{
			if (node == null) { return false; }
			if (node == this) { return true; }
			else { return this.contains(node.parentNode); }
		};
	}
}


function findPosY(obj)
{
	var curtop = 0;

	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	
	return curtop;
}

