/************************************************************************
 *
 *  DOM Behaviours - common routines and functions for adding
 *  a behaviour layer to an (X)HTML document.
 *
 ***********************************************************************/



/************************************************************************
 *
 *  Attaching events to element nodes
 *  from http://www.sitepoint.com/article/structural-markup-javascript
 *   * addEvent
 *   * removeEvent
 *
 ***********************************************************************/

function addEvent(obj, evType, fn, useCapture){
  if (obj.addEventListener){
    obj.addEventListener(evType, fn, useCapture);
    return true;
  } else if (obj.attachEvent){
    var r = obj.attachEvent("on"+evType, fn);
    return r;
  } else {
    alert("Handler could not be attached");
  }
}

function removeEvent(obj, evType, fn, useCapture){
  if (obj.removeEventListener){
    obj.removeEventListener(evType, fn, useCapture);
    return true;
  } else if (obj.detachEvent){
    var r = obj.detachEvent("on"+evType, fn);
    return r;
  } else {
    alert("Handler could not be removed");
  }
}


/************************************************************************
 *
 *  Finding the position of an HTML element
 *  from http://www.quirksmode.org/js/findpos.html
 *   * findPosY
 *   * findPosX
 *
 ***********************************************************************/

function findPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}

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;
}



/************************************************************************
 *
 * initHelp - initialise the help system 
 * 
 *
 ***********************************************************************/

var helpArr = new Array();

function initHelp() {
	//alert("Initialising Help");
	msg="";
	
	// loop through all anchors looking for a class item of "help"
	// For each of these anchors, get the internal href reference (stuff after the #)
	// Get the element referenced by this particular id
	// link the .help link to this division, and hide the division
	
	helpLinks = document.getElementsByTagName('a');
	for (var i = 0; i < helpLinks.length; i++) { 
	
		helpLink = helpLinks[i];
		
		if (helpLink.getAttribute("rel") == "help") {
		
			// Extract the id of the help item from the href.
			helpId = helpLink.href.substring(helpLink.href.indexOf("#") + 1);
			
			msg += "Help: " + helpLink.href + "[" + helpId + "]\n";

			helpRef = document.getElementById(helpId);
			if (helpRef) {

				// 1. Add an event handler to the link to toggle the help window
				helpLink.onclick = function() {
					toggleHelp(this);
					//return false;
				}

				// 2. Hide the help element
				helpRef.style.display="none";

				// 3. Create a close link on the help
				
				// MSIE5.0 doesn't support array.push()!!!
				//helpArr.push(helpId);
				helpArr[helpArr.length] = helpId;
				
				
				msg += "Help container: " + helpId + "\n";
				
				// 4. Position the help message on the side by adding "side" to className
				helpRef.className += " side";

				// 5. Opera has a problem with absolutely positioned layers with no top property defined.
				if (window.opera) {
					//alert("I am Opera. Singer of worlds [" + findPosY(helpLink) + "]");
					helpRef.style.top = findPosY(helpLink) - 32;
				}
				
			} else {
				msg += "Could not find element with an id of " + helpId + "\n";
			}
		
		}
	
	}
	
	msg += "\nAdding close buttons to help windows\n";
	for (var i = 0; i < helpArr.length; i++) { 
		hlp = helpArr[i];
		
		helpRef = document.getElementById(hlp);
		
		if (helpRef) {
			msg += "Help Win: " + hlp + "\n";

			closeLinkBar = document.createElement('div');
			closeLinkBar.className="bar"

			closeLink = document.createElement('a');
			closeLink.className="action";
			closeLink.setAttribute("href", "#" + hlp.substring(0,hlp.length-4));

			closeLink.appendChild(document.createTextNode("Close"));
			closeLinkBar.appendChild(closeLink);
			helpRef.appendChild(closeLinkBar);
			
			//addEvent(closeLink, "click", closeHelp, true);
			closeLink.onclick = function() {
				closeHelp(this);
				focusPoint=this.href.substring(this.href.indexOf("#") + 1);
				document.getElementById(focusPoint).focus();
				return false;
			}
		}

	
	}
	//alert("Messages:\n" + msg);
}

addEvent(window, "load", initHelp, true);


var helpOpen;

function showHelp(id) {
	helpWin = document.getElementById(id);
	if (helpWin) {
		helpWin.style.display="block";
	} else {
		alert("No help window called " + id + " found.");
	}
}

function hideHelp(id) {
	helpWin = document.getElementById(id);
	if (helpWin) {
		helpWin.style.display="none";
		helpOpen = null;
	} else {
		alert("No help window called " + id + " found.");
	}
}

function toggleHelp(anchorRef) {
	helpId = anchorRef.href.substring(anchorRef.href.indexOf("#") + 1);
	
	if (helpOpen) { hideHelp(helpOpen); }

	helpWin = document.getElementById(helpId);
	if (helpWin) {
		if (helpWin.style.display=="none") {
			helpWin.style.display="block";
		} else {
			helpWin.style.display="none";
		}
		helpOpen = helpId;
	} else {
		alert("No help window called " + id + " found.");
	}
}


function closeHelp(ref) {
	if (ref.href) { 
		//alert("There is an ref.href [" + ref.href + "]");
		//alert(ref.parentNode.parentNode.nodeName);
		helpNode = ref.parentNode.parentNode;
		//alert(helpNode.className);
		if (/\bhelpmsg\b/.exec(helpNode.className)) {
			helpNode.style.display="none";
			helpOpen=null;
		}
		
		
	}

}
