//---------------------------------------------------------------------------------------------------------
//	DHTML JavaScript (ver 4.1)
//---------------------------------------------------------------------------------------------------------

//*******************************************************************************************************
//	Menu positioning stuff from selectedit js
//*******************************************************************************************************
//---------------------------------------------------------------------------------------------------------
//	Browser detection stuff
//  PHP Layers Menu 3.1.1 (C) 2001-2003 Marco Pratesi (marco at telug dot it)
//---------------------------------------------------------------------------------------------------------

DOM = (document.getElementById) ? 1 : 0;
NS4 = (document.layers) ? 1 : 0;
// We need to explicitly detect Konqueror
// because Konqueror 3 sets IE = 1 ... AAAAAAAAAARGHHH!!!
Konqueror = (navigator.userAgent.indexOf("Konqueror") > -1) ? 1 : 0;
// We need to detect Konqueror 2.2 as it does not handle the window.onresize event
Konqueror22 = (navigator.userAgent.indexOf("Konqueror 2.2") > -1 || navigator.userAgent.indexOf("Konqueror/2.2") > -1) ? 1 : 0;
Opera = (navigator.userAgent.indexOf("Opera") > -1) ? 1 : 0;
Opera5 = (navigator.userAgent.indexOf("Opera 5") > -1 || navigator.userAgent.indexOf("Opera/5") > -1) ? 1 : 0;
Opera6 = (navigator.userAgent.indexOf("Opera 6") > -1 || navigator.userAgent.indexOf("Opera/6") > -1) ? 1 : 0;
Opera56 = Opera5 || Opera6;
IE = (navigator.userAgent.indexOf("MSIE") > -1) ? 1 : 0;
IE = IE && !Opera;
IE5 = IE && DOM;
IE4 = (document.all) ? 1 : 0;
IE4 = IE4 && IE && !DOM;


//*******************************************************************************************************
//	uber menu functions
//*******************************************************************************************************
active	= new Array();

//-------------------------------------------------------------------------------------------------------
//	Show/ Hide menus
//-------------------------------------------------------------------------------------------------------
function show( group, item, imgId, imgBase, topnavid )
{
	if( !document.getElementById )
	{
		return;
	}


	//	Number of menus in the group
	menuCount	= eval("m_" + group);
	
	//	DOM ID of main (1st level) menu
	topmenu_id	= "m" + group + "0";
	TopMenuObj	= document.getElementById( topmenu_id );

	//	DOM ID of current menu
	menu_id		= "m" + group + item;
	MenuObj		= document.getElementById( menu_id );

	//	Get ID of parent item
	parent_id	= 'p' + group + item;
	ParentObj	= document.getElementById( parent_id );

	//	Does object exist?
	if( !MenuObj )
	{
		//	No, don't process
		return false;
	}
	
	//	Image toggle, if applicable
	if( imgId != 'NULL' )
	{
		imgObj	= document.getElementById( imgId );
		imgObj.setAttribute( 'base', imgBase );
		imgObj.setAttribute( 'src', imgBase );
	}
	
	//	Make visible
	TopMenuObj.style.visibility	= "visible";

	//	Do the positioning
	ShowMenuFixPosition( menu_id, topnavid );

	if(( topmenu_id != menu_id ) && ( item != 0 ))
	{
		MenuObj.style.visibility	= "visible";
		for (i = 1; i <= menuCount; i++)
		{
			if (i != item)
			{
				document.getElementById("m" + group + i).style.visibility	= "hidden";
			}
		}
	}

	//	Get ID of parent item
//	pid	= 'p' + group + item;

	//	Highlight the parent item
	tmpClassName	= ParentObj.className;

	//	Keep track of current CSS class name
	ParentObj.setAttribute( "tmpClassName", tmpClassName )

	//	Set the highlight
	ParentObj.className	= 'highlight';

	//	Make sure it gets displayed
	MenuObj.style.display	= "block";

}

function ShowMenuFixPosition( menuid, topnavid )
{
	MenuObj		= document.getElementById( menuid );

	//	Position the menu based on the top nav'd position
	if ( topnavid )
	{
		//	Menus right
		if( menu_positioning == 1 )
		{
			MenuObj.style.left = ( getOffsetLeft( topnavid ) + getOffsetWidth( topnavid )) +  'px';
			MenuObj.style.top  = getOffsetTop( topnavid ) + 'px';
		}
		//	Menus below (default)
		else
		{
			MenuObj.style.left = getOffsetLeft( topnavid ) + 'px';
			MenuObj.style.top  = ( getOffsetTop( topnavid ) + getOffsetHeight( topnavid )) + 'px';
		}
	}
}

//-------------------------------------------------------------------------------------------------------
//	Show custom menu
//-------------------------------------------------------------------------------------------------------
function ShowCustomMenuBlock( menuid, parentid, imgId, imgBase, topnavid )
{
	if( !document.getElementById )
	{
		return;
	}

	MenuObj		= document.getElementById( menuid );

	//	Does object exist?
	if( !MenuObj )
	{
		//	No, don't process
		return false;
	}
	
	//	Image toggle, if applicable
	if( imgId != 'NULL' )
	{
		imgObj	= document.getElementById( imgId );
		imgObj.setAttribute( 'base', imgBase );
		imgObj.setAttribute( 'src', imgBase );
	}
	
	//	Make visible
	MenuObj.style.visibility	= "visible";

	//	Do the positioning
	ShowMenuFixPosition( menuid, topnavid );

	//	Highlight the parent item
	tmpClassName	= document.getElementById( parentid ).className;

	//	Keep track of current CSS class name
	document.getElementById( parentid ).setAttribute( "tmpClassName", tmpClassName )

	//	Set the highlight
	document.getElementById( parentid ).className	= 'highlight';

	//	Make sure it gets displayed
	MenuObj.style.display	= "block";
}






//-------------------------------------------------------------------------------------------------------
//	Hide menu
//-------------------------------------------------------------------------------------------------------
function hide(group,item,imgId,imgBase)
{
	if( !document.getElementById )
	{
		return;
	}


	menuCount	= eval("m_" + group);

	//	Does object exist?
	if( !document.getElementById( "m" + group + menuCount ))
	{
		//	No, don't process
		return false;
	}
	
	if( imgId != 'NULL' )
	{
		imgObj	= document.getElementById( imgId );
		imgObj.setAttribute( 'base', imgBase );
		imgObj.setAttribute( 'src', imgBase );
	}
	
	if (item == 0)
	{
		startFrom	= 0;
	}
	else
	{
		startFrom	= 1;
	}
	for (i = startFrom; i <= menuCount; i++)
	{
		document.getElementById("m" + group + i).style.visibility	= "hidden";

		//	Get ID of parent item
		pid	= 'p' + group + i;

		tmpClassName	= document.getElementById( pid ).getAttribute( "tmpClassName" );
		curClassName	= document.getElementById( pid ).className;
		
		//	Determine new class name (to show arrow for submenus or not)
		if( tmpClassName == "showsub" || curClassName == "showsub" )
		{
			newClassName	= "showsub";
		}
		else
		{
			newClassName	= "";
		}
		
		//	un-Highlight the parent item
		if( document.getElementById( pid ) )
		{
			document.getElementById( pid ).className	= newClassName;
		}
	}
}


function HideCustomMenuBlock(id,parentid,imgId,imgBase)
{
	if( !document.getElementById )
	{
		return;
	}

	//	Does object exist?
	if( !document.getElementById( id ))
	{
		//	No, don't process
		return false;
	}
	
	if( imgId != 'NULL' )
	{
		imgObj	= document.getElementById( imgId );
		imgObj.setAttribute( 'base', imgBase );
		imgObj.setAttribute( 'src', imgBase );
	}
	
	document.getElementById( id ).style.visibility	= "hidden";

	tmpClassName	= document.getElementById( parentid ).getAttribute( "tmpClassName" );
	curClassName	= document.getElementById( parentid ).className;
	
	//	Determine new class name (to show arrow for submenus or not)
	if( tmpClassName == "showsub" || curClassName == "showsub" )
	{
		newClassName	= "showsub";
	}
	else
	{
		newClassName	= "";
	}
	
	//	un-Highlight the parent item
	if( document.getElementById( parentid ) )
	{
		document.getElementById( parentid ).className	= newClassName;
	}
}







//-------------------------------------------------------------------------------------------------------
//	Image swap
//-------------------------------------------------------------------------------------------------------
function swapImg(id,img)
{
	if( document.getElementById)
	{
		obj	= document.getElementById(id);
		obj.setAttribute( 'src', img );
	}
}

//-------------------------------------------------------------------------------------------------------
//	Redirect
//-------------------------------------------------------------------------------------------------------
function redirectTo( nav )
{
	//	Selected a url?
	dropdown	= nav.options;
	value		= dropdown[dropdown.selectedIndex].value;

	if ( value )
	{
		window.location.href = value;	
	}
}

//*******************************************************************************************************
//	Menu positioning stuff from selectedit js
//*******************************************************************************************************


function getOffsetLeft(eElement)
{
	eElement	= document.getElementById( eElement );

   if (!eElement && this)                    // if argument is invalid
   {                                         // (not specified, is null or is 0)
      eElement = this;                       // and function is a method
   }                                         // identify the element as the method owner

   var DL_bIE = document.all ? true : false; // initialize var to identify IE

   var nLeftPos = eElement.offsetLeft;       // initialize var to store calculations
   var eParElement = eElement.offsetParent;  // identify first offset parent element

   while (eParElement != null)
   {                                         // move up through element hierarchy

      if(DL_bIE)                             // if browser is IE, then...
      {
         if( (eParElement.tagName != "TABLE") && (eParElement.tagName != "BODY") )
         {                                   // if parent is not a table or the body, then...
            nLeftPos += eParElement.clientLeft; // append cell border width to calcs
         }
      }
      else                                   // if browser is Gecko, then...
      {
         if(eParElement.tagName == "TABLE")  // if parent is a table, then...
         {                                   // get its border as a number
            var nParBorder = parseInt(eParElement.border);
            if(isNaN(nParBorder))            // if no valid border attribute, then...
            {                                // check the table's frame attribute
               var nParFrame = eParElement.getAttribute('frame');
               if(nParFrame != null)         // if frame has ANY value, then...
               {
                  nLeftPos += 1;             // append one pixel to counter
               }
            }
            else if(nParBorder > 0)          // if a border width is specified, then...
            {
               nLeftPos += nParBorder;       // append the border width to counter
            }
         }
      }
      nLeftPos += eParElement.offsetLeft;    // append left offset of parent
      eParElement = eParElement.offsetParent; // and move up the element hierarchy
   }                                         // until no more offset parents exist
   return nLeftPos;                          // return the number calculated
}

function getOffsetTop(eElement)
{
	eElement	= document.getElementById( eElement );
   if (!eElement && this)                    // if argument is invalid
   {                                         // (not specified, is null or is 0)
      eElement = this;                       // and function is a method
   }                                         // identify the element as the method owner

   var DL_bIE = document.all ? true : false; // initialize var to identify IE

   var nTopPos = eElement.offsetTop;         // initialize var to store calculations
   var eParElement = eElement.offsetParent;  // identify first offset parent element

   while (eParElement != null)
   {                                         // move up through element hierarchy
      if(DL_bIE)                             // if browser is IE, then...
      {
         if( (eParElement.tagName != "TABLE") && (eParElement.tagName != "BODY") )
         {                                   // if parent a table cell, then...
            nTopPos += eParElement.clientTop; // append cell border width to calcs
         }
      }
      else                                   // if browser is Gecko, then...
      {
         if(eParElement.tagName == "TABLE")  // if parent is a table, then...
         {                                   // get its border as a number
            var nParBorder = parseInt(eParElement.border);
            if(isNaN(nParBorder))            // if no valid border attribute, then...
            {                                // check the table's frame attribute
               var nParFrame = eParElement.getAttribute('frame');
               if(nParFrame != null)         // if frame has ANY value, then...
               {
                  nTopPos += 1;              // append one pixel to counter
               }
            }
            else if(nParBorder > 0)          // if a border width is specified, then...
            {
               nTopPos += nParBorder;        // append the border width to counter
            }
         }
      }

      nTopPos += eParElement.offsetTop;      // append top offset of parent
      eParElement = eParElement.offsetParent; // and move up the element hierarchy
   }                                         // until no more offset parents exist
   return nTopPos;                           // return the number calculated
}







/*



function getOffsetLeft(layer) {
	var value = 0;
	if (DOM) {	// Mozilla, Konqueror >= 2.2, Opera >= 5, IE
		object = document.getElementById(layer);
		value = object.offsetLeft;
//alert (object.tagName + " --- " + object.offsetLeft);
		while (object.tagName != "BODY" && object.offsetParent) {
			object = object.offsetParent;
//alert (object.tagName + " --- " + object.offsetLeft);
			value += object.offsetLeft;
		}
	} else if (NS4) {
		value = document.layers[layer].pageX;
	} else {	// IE4 IS SIMPLY A BASTARD !!!
		if (document.all["IE4" + layer]) {
			layer = "IE4" + layer;
		}
		object = document.all[layer];
		value = object.offsetLeft;
		while (object.tagName != "BODY") {
			object = object.offsetParent;
			value += object.offsetLeft;
		}
	}
	return (value);
}
*/
function setTop(layer,y) {
//layerTop[layer] = y;
	if (DOM && !Opera5) {
		document.getElementById(layer).style.top = y + "px";
	} else if (Opera5) {
		document.getElementById(layer).style.top = y;
	} else if (NS4) {
		document.layers[layer].top = y;
	} else {
		document.all[layer].style.pixelTop = y;
	}
}
/*
function getOffsetTop(layer) {
// IE 5.5 and 6.0 behaviour with this function is really strange:
// in some cases, they return a really too large value...
// ... after all, IE is buggy, nothing new
	var value = 0;
	if (DOM) {
		object = document.getElementById(layer);
		value = object.offsetTop;
		while (object.tagName != "BODY" && object.offsetParent) {
			object = object.offsetParent;
			value += object.offsetTop;
		}
	} else if (NS4) {
		value = document.layers[layer].pageY;
	} else {	// IE4 IS SIMPLY A BASTARD !!!
		if (document.all["IE4" + layer]) {
			layer = "IE4" + layer;
		}
		object = document.all[layer];
		value = object.offsetTop;
		while (object.tagName != "BODY") {
			object = object.offsetParent;
			value += object.offsetTop;
		}
	}
	return (value);
}
*/
function setWidth(layer,w) {
	if (DOM) {
		document.getElementById(layer).style.width = w;
	} else if (NS4) {
//		document.layers[layer].width = w;
	} else {
		document.all[layer].style.pixelWidth = w;
	}
}

function getOffsetWidth(layer) {
	var value = 0;
	if (DOM && !Opera56) {
		value = document.getElementById(layer).offsetWidth;
	} else if (NS4) {
		value = document.layers[layer].document.width;
	} else if (Opera56) {
		value = document.getElementById(layer).style.pixelWidth;
	} else {	// IE4 IS SIMPLY A BASTARD !!!
		if (document.all["IE4" + layer]) {
			layer = "IE4" + layer;
		}
		value = document.all[layer].offsetWidth;
	}
	return (value);
}

function setHeight(layer,h) {	// unused, not tested
	if (DOM) {
		document.getElementById(layer).style.height = h;
	} else if (NS4) {
//		document.layers[layer].height = h;
	} else {
		document.all[layer].style.pixelHeight = h;
	}
}

function getOffsetHeight(layer) {
	var value = 0;
	if (DOM && !Opera56) {
		value = document.getElementById(layer).offsetHeight;
	} else if (NS4) {
		value = document.layers[layer].document.height;
	} else if (Opera56) {
		value = document.getElementById(layer).style.pixelHeight;
	} else {	// IE4 IS SIMPLY A BASTARD !!!
		if (document.all["IE4" + layer]) {
			layer = "IE4" + layer;
		}
		value = document.all[layer].offsetHeight;
	}
	return (value);
}

function getWindowWidth() {
	var value = 0;
	if ((DOM && !IE) || NS4 || Konqueror || Opera) {
		value = top.innerWidth;
//	} else if (NS4) {
//		value = document.width;
	} else {	// IE
		if (document.documentElement && document.documentElement.clientWidth) {
			value = document.documentElement.clientWidth;
		} else if (document.body) {
			value = document.body.clientWidth;
		}
	}
	if (isNaN(value)) {
		value = top.innerWidth;
	}
	return (value);
}

function getWindowXOffset() {
	var value = 0;
	if ((DOM && !IE) || NS4 || Konqueror || Opera) {
		value = window.pageXOffset;
	} else {	// IE
		if (document.documentElement && document.documentElement.scrollLeft) {
			value = document.documentElement.scrollLeft;
		} else if (document.body) {
			value = document.body.scrollLeft;
		}
	}
	return (value);
}

function getWindowHeight() {
	var value = 0;
	if ((DOM && !IE) || NS4 || Konqueror || Opera) {
		value = top.innerHeight;
	} else {	// IE
		if (document.documentElement && document.documentElement.clientHeight) {
			value = document.documentElement.clientHeight;
		} else if (document.body) {
			value = document.body.clientHeight;
		}
	}
	if (isNaN(value)) {
		value = top.innerHeight;
	}
	return (value);
}

function getWindowYOffset() {
	var value = 0;
	if ((DOM && !IE) || NS4 || Konqueror || Opera) {
		value = window.pageYOffset;
	} else {	// IE
		if (document.documentElement && document.documentElement.scrollTop) {
			value = document.documentElement.scrollTop;
		} else if (document.body) {
			value = document.body.scrollTop;
		}
	}
	return (value);
}




/* document.getElementsBySelector(selector)
   - returns an array of element objects from the current document
     matching the CSS selector. Selectors can contain element names, 
     class names and ids and can be nested. For example:
     
       elements = document.getElementsBySelect('div#main p a.external')
     
     Will return an array of all 'a' elements with 'external' in their 
     class attribute that are contained inside 'p' elements that are 
     contained inside the 'div' element which has id="main"

   New in version 0.4: Support for CSS2 and CSS3 attribute selectors:
   See http://www.w3.org/TR/css3-selectors/#attribute-selectors

   Version 0.4 - Simon Willison, March 25th 2003
   -- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows
   -- Opera 7 fails 
*/

function getAllChildren(e) {
  // Returns all children of element. Workaround required for IE5/Windows. Ugh.
  return e.all ? e.all : e.getElementsByTagName('*');
}

document.getElementsBySelector = function(selector) {
  // Attempt to fail gracefully in lesser browsers
  if (!document.getElementsByTagName) {
    return new Array();
  }
  // Split selector in to tokens
  var tokens = selector.split(' ');
  var currentContext = new Array(document);
  for (var i = 0; i < tokens.length; i++) {
    token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
    if (token.indexOf('#') > -1) {
      // Token is an ID selector
      var bits = token.split('#');
      var tagName = bits[0];
      var id = bits[1];
      var element = document.getElementById(id);
      if (tagName && element.nodeName.toLowerCase() != tagName) {
        // tag with that ID not found, return false
        return new Array();
      }
      // Set currentContext to contain just this element
      currentContext = new Array(element);
      continue; // Skip to next token
    }
    if (token.indexOf('.') > -1) {
      // Token contains a class selector
      var bits = token.split('.');
      var tagName = bits[0];
      var className = bits[1];
      if (!tagName) {
        tagName = '*';
      }
      // Get elements matching tag, filter them for class selector
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      continue; // Skip to next token
    }
    // Code to deal with attribute selectors
    if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
      var tagName = RegExp.$1;
      var attrName = RegExp.$2;
      var attrOperator = RegExp.$3;
      var attrValue = RegExp.$4;
      if (!tagName) {
        tagName = '*';
      }
      // Grab all of the tagName elements within current context
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      var checkFunction; // This function will be used to filter the elements
      switch (attrOperator) {
        case '=': // Equality
          checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
          break;
        case '~': // Match one of space seperated words 
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
          break;
        case '|': // Match start with value followed by optional hyphen
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
          break;
        case '^': // Match starts with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
          break;
        case '$': // Match ends with value - fails with "Warning" in Opera 7
          checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
          break;
        case '*': // Match ends with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
          break;
        default :
          // Just test for existence of attribute
          checkFunction = function(e) { return e.getAttribute(attrName); };
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (checkFunction(found[k])) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
      continue; // Skip to next token
    }
    // If we get here, token is JUST an element (not a class or ID selector)
    tagName = token;
    var found = new Array;
    var foundCount = 0;
    for (var h = 0; h < currentContext.length; h++) {
      var elements = currentContext[h].getElementsByTagName(tagName);
      for (var j = 0; j < elements.length; j++) {
        found[foundCount++] = elements[j];
      }
    }
    currentContext = found;
  }
  return currentContext;
}

/* That revolting regular expression explained 
/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
  \---/  \---/\-------------/    \-------/
    |      |         |               |
    |      |         |           The value
    |      |    ~,|,^,$,* or =
    |   Attribute 
   Tag
*/


// behavior.js - by Dave Herman
// Copyright (C) 2005 by Dave Herman
//
// Based on behaviour.js by Ben Nolan, June 2005
// and getElementBySelector.js by Simon Willison, 2004.
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or (at
// your option) any later version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
// License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

// =============================================================================
// Class: HandlerSet
// =============================================================================

function HandlerSet() {
    this.clearHandlers();
}

HandlerSet.prototype = {
    addHandler : function(f, key) {
        key = key || this.uniqueID++;
        this.installedHandlers[key] = f;
        return key;
    },

    removeHandler : function(key) {
        delete this.installedHandlers[key];
    },

    clearHandlers : function() {
        this.installedHandlers = { };
        this.uniqueID = 0;
    },

    replaceHandlers : function(f, key) {
        clearHandlers();
        return addHandler(f, key);
    },

    applyAll : function(object, arguments) {
        for (var handler in this.installedHandlers) {
            this.installedHandlers[handler].apply(object, arguments);
        }
    },

    debug : function() {
        var str = "";
        for (var p in this.installedHandlers) {
            str += p + " => " + this.installedHandlers[p] + "\n";
        }
        alert(str);
    }
};

// =============================================================================
// Function Class: EventHandler
// =============================================================================

function isEventHandler(x) {
    return (typeof x == 'function' &&
            x.handlers &&
            x.handlers.constructor == HandlerSet);
}

function makeEventHandler(original) {
    var handlers = new HandlerSet();

    if (typeof original == 'function') {
        handlers.addHandler(original);
    }

    // The event handler is a function, so it can be used with the DOM.
    // But when it's called, we apply all the handlers in the set.
    var result = function() {
        handlers.applyAll(this, arguments);
    };

    // We also expose its handler set so we can get at it later.
    result.handlers = handlers;

    return result;
}

// =============================================================================
// Module: Behavior
// =============================================================================

var Behavior = {
    registry : new Array,

    register : function(sheet) {
        Behavior.registry.push(sheet);
    },

    registerEventHandlers : function(element, handlers) {
        for (var event in handlers) {
            if (!isEventHandler(element[event])) {
                element[event] = makeEventHandler(element[event]);
            }
            element[event].handlers.addHandler(handlers[event]);
        }
    },

    apply : function() {
        for (var i = 0; i < Behavior.registry.length; i++) {
            var sheet = Behavior.registry[i];
            for (var selector in sheet) {
                var list = document.getElementsBySelector(selector);
                if (!list) {
                    continue;
                }
                for (var j = 0; j < list.length; j++) {
                    Behavior.registerEventHandlers(list[j], sheet[selector]);
                }
            }
        }
    },

    addLoadHandler : function(handler) {
        var oldHandler = window.onload;

        if (typeof oldHandler != 'function') {
            window.onload = handler;
        }
        else {
            window.onload = function() {
                oldHandler();
                handler();
            };
        }

/*
		window.onload = function() {
//			oldHandler();
			handler();
			InitTabs('info',5);
			InitTabs('relatedinfo',2);
		};
*/	
	
	}
};

Behavior.addLoadHandler(function() { Behavior.apply(); });





function MenuOn( object )
{
	ButtonOn( object );

	if( object.className != "m1" )
	{
		//	Highlight the parent link (link moused over to get the submenu)
		sublinks	= object.getElementsByTagName( "a" );
		sublinks[0].setAttribute( "baseclass", sublinks[0].className );

		if( sublinks[0].className == "showsub" )
		{
			highlightclassname	= " highlight-active";
		}
		else
		{
			highlightclassname	= " highlight";
		}

		sublinks[0].className	= sublinks[0].className + highlightclassname;
		//	----------
		
		submenus	= object.getElementsByTagName( 'ul' );

		if( submenus.length == 0 )
		{
			return;
		}

		MenuObj	= submenus[0];
	}

	TransitionOn( MenuObj );
}

function MenuOff( object )
{
	ButtonOff( object );

	if( object.className != "m1" )
	{
		//	Un-highlight the parent link (link moused over to get the submenu)
		sublinks	= object.getElementsByTagName( "a" );
		sublinks[0].className	= sublinks[0].getAttribute( "baseclass" );
		//	----------
		
		submenus	= object.getElementsByTagName( 'ul' );

		if( submenus.length == 0 )
		{
			return;
		}

		MenuObj	= submenus[0];
	}

	TransitionOff( MenuObj );
}



/*
function MenuOff( object )
{
	ButtonOff( object );

	object.style.backgroundColor = 'yellow';

	submenus	= object.getElementsByTagName( 'ul' );

	if( submenus.length == 0 )
	{
		return;
	}

	TransitionOff( submenus[0] );
}

*/

function TransitionOn( object )
{
	ButtonOn( object );
	object.style.display	= "block";
}

function TransitionOff( object )
{
	ButtonOff( object );
	object.style.display	= "none";
}




function UberGetMenuObjectFromButtonObject( object )
{
	LinkID	= object.getAttribute( "id" );
	MenuID	= LinkID.substring( 2, LinkID.length );
	MenuObj	= document.getElementById( MenuID );

	return MenuObj;
}

function UberOn( object )
{
	MenuObj	= UberGetMenuObjectFromButtonObject( object );

	if( !MenuObj )
	{
		return false;
	}

	MenuRePosition( MenuObj );
	MenuOn( MenuObj );
}

function UberOff( object )
{
	MenuObj	= UberGetMenuObjectFromButtonObject( object );

	if( !MenuObj )
	{
		return false;
	}

	MenuOff( MenuObj );
}







function ButtonGetButtonID( object )
{
	while ( object.parentNode.tagName != "BODY" )
	{
		object	= object.parentNode;
	}

	MenuID		= object.getAttribute( "id" );
	ButtonID	= "b-" + MenuID;

	return ButtonID;
}

function ButtonOn( object )
{
	ButtonID	= ButtonGetButtonID( object );
	ButtonObj	= document.getElementById( ButtonID );

	if( !ButtonObj.getAttribute( "baseclass" ))
	{
		ButtonObj.setAttribute( "baseclass", ButtonObj.className );
	}

	ButtonObj.className	= "active";
}

function ButtonOff( object )
{
	ButtonID	= ButtonGetButtonID( object );
	ButtonObj	= document.getElementById( ButtonID );
	ButtonObj.className	= ButtonObj.getAttribute( "baseclass" );
}










function MenuRePosition( object )
{
	ButtonID	= ButtonGetButtonID( object );

	//	Menus right
	if( menu_positioning == 1 )
	{
		object.style.left = ( getOffsetLeft( ButtonID ) + getOffsetWidth( ButtonID )) +  'px';
		object.style.top  = getOffsetTop( ButtonID ) + 'px';
	}
	//	Menus below (default)
	else
	{
		object.style.left = getOffsetLeft( ButtonID ) + 'px';
		object.style.top  = ( getOffsetTop( ButtonID ) + getOffsetHeight( ButtonID )) + 'px';
	}
}


var	rules = {
	'.m1':
	{
		onmouseover	: function() { TransitionOn( this ) },
		onmouseout	: function() { TransitionOff( this ) }
	},

	'ul.m1 li':
	{
		onmouseover	: function() { MenuOn( this ); },
		onmouseout	: function() { MenuOff( this ); }
	},

	'#nav-main a':
	{
		onmouseover	: function() { UberOn( this ); },
		onmouseout	: function() { UberOff( this ); }
	}
};

Behavior.register(rules);





