

/** ------------------------------------------------------------------------
 *   GLOBAL FUNCTIONS FOR THE DHL ( DYNAMIC HTML LIBRARY )
 * ------------------------------------------------------------------------
 */




/** ------------------------------------
 *   URL PARAMETERS
 * ------------------------------------
 */

/**
 *    params	= new URLParams();
 */

function URLParams ()
{
   this.params		= new Array();
   this.names		= new Array();
   var location		= window.location.search;	// URL string

   if ( location )
   {
      var pairs	= location.substr( 1 ).split( "&" );

      for ( var i = 0; i < pairs.length; i++ )
      {
         var pair		= pairs[i].split( "=" );
         var name		= unescape( pair[0] );
         this.params[ name ]	= unescape( pair[1] );
         this.names.push( name );
      }
   }

   this.getParam = function ( key )
   {
      return this.params[ key ];
   }
   this.getParamEscaped = function ( key )
   {
      return escape( this.params[ key ] );
   }
}


function urlValue( key )
{
   if ( value	= document.location.toString().match( RegExp( ".*(\\?|&)" + escape( key ) + "=([^&]*)" ) ) )
   {
      return unescape( value[2] );
   }
   return "";
}


/** ------------------------------------
 *   CAPTURE EVENTS IN MOZILLA & IE
 * ------------------------------------
 */

 /**
 * This makes the events available in Netscape as the same object in IE
 */

if( ! window.event && window.captureEvents )
{
  // set up event capturing for mouse events (add or subtract as desired)
  window.captureEvents(Event.MOUSEOVER|Event.MOUSEOUT|Event.CLICK|Event.DBLCLICK|Event.MOUSEMOVE);

  // set window event handlers (add or subtract as desired)
  window.onmouseover	= WM_getCursorHandler;
  window.onmouseout	= WM_getCursorHandler;
  window.onclick	= WM_getCursorHandler;
  window.ondblclick	= WM_getCursorHandler;
  window.onfocus	= WM_getCursorHandler;
  window.onblur		= WM_getCursorHandler;
  window.onchange	= WM_getCursorHandler;
  window.onkeypress	= WM_getCursorHandler;
  //window.onmousemove	= WM_getCursorHandler;

  // create an object to store the event properties
  window.event		= new Object;
}

function WM_getCursorHandler(e)
{
  // set event properties to global vars (add or subtract as desired)
  window.event.clientX	= e.pageX;
  window.event.clientY	= e.pageY;
  window.event.x	= e.layerX;
  window.event.y	= e.layerY;
  window.event.screenX	= e.screenX;
  window.event.screenY	= e.screenY;

  window.event.button	= e.which;

  // route the event back to the intended function
  if ( routeEvent(e) == false ) {
    return false;
  } else {
    return true;
  }
}



/**
 * ELEMENT EVENTS
 *
 * To give extra functionality to events such as onclick, oncontextmenu, onmouseover,
 * a html dom element is assigned parameters to be used with it's event.
 *
 * Works in Netscape and IE.
 *
 * Element first needs to be set in the usual way, eg.
 *
 *    element		= document.getElementById( "myElement" );
 *
 * Set the event:
 *
 *    pageEvents.setElement( element, event, action [, ignoreTag ] );
 *
 *    element is the html dom element
 *    action is the JavaScript to run
 *    ignoreTag makes any element of this tag type with the same event be ignored, used for overlapping elements
 *
 * Eg.
 *    pageEvents.setElement( element, "onclick", "alert( 'You clicked on the element' )", "BODY" );
 *
 * The element's properties are set in the HTML DOM:
 *
 *    element.onclick				= elementEvent_onclick;
 *    element.events[ 'onclick' ].action	= "alert( 'You clicked on the element' )";
 *    element.events[ 'onclick' ].ignoreTag	= "BODY";
 *
 */

function AllPageEvents()
{
   /**
    * Current tagName of an element with same event to be ignored
    * eg. this.ignoreTags[ "onclick" ] = "BODY" stops onclick events for <body>
    * tag to be ignored, this is cleared after it has been ignored once.
    */
   //this.ignoreTag		= "";
   this.ignoreTags		= new Array();


   /**
    * Set or append the event for the element and store the parameters
    * to use with the event as nodes of the element
    */
    this.setElement = function ( element, event, action, ignoreTag )
    {
      if ( !element.events )
      {
	 element.events			= new Array();
      }

      if ( !element.events[ event ] )
      {
	 element.events[ event ]	= new Object;
	 element.events[ event ].action	= action
	 eval( "element." + event + " = elementEvent_" + event );	// eg. element.onclick = ElementEvent_onclick;
      }

      else
      {
	 /**
	  * More than one action can be run when an event is triggered
	  */
	 element.events[ event ].action		+= "; " + action;
      }

      if ( ignoreTag )
      {
	 element.events[ event ].ignoreTag	= ignoreTag.toUpperCase();
      }

      /**
       * Initialise general ignore tag for this type of event if it has not yet been set
       */
      if ( !this.ignoreTags[ event ] )
      {
	 this.ignoreTags[ event ]	== "";
      }
   }

   /**
    * clearElement removes the attached event if it is assigned
    */
   this.clearElement = function ( element, event )
   {
      if ( element.events && element.events[ event ] && element.events[ event ].action )
      {
	 element.events[ event ].action	= "";
	 //eval( "element." + event + " = null" );	// eg. element.onclick = null;
      }
   }

   /**
    * resetElement clears an event's action if it is already set, then re assigns it
    */
   this.resetElement = function ( element, event, action, ignoreTag )
   {
      this.clearElement( element, event );
      this.setElement( element, event, action, ignoreTag );
   }

   this.run = function ( element, event )
   {
      if ( this.ignoreTags[ event ] == element.tagName.toUpperCase() || this.ignoreTags[ event ] == "*" )
      {
	 this.ignoreTags[ event ]	= "";
      }
      else
      {
	 eval( element.events[ event ].action );
	 this.ignoreTags[ event ]	= element.events[ event ].ignoreTag;
      }
   }

   this.cloneEvent = function ( element, oElement )
   {
      /**
       * TODO: This does not really clone the event object, it makes a pointer
       * to the same event object
       */

      if ( oElement.onblur )		 element.onblur		= oElement.onblur;
      if ( oElement.onchange )		 element.onchange	= oElement.onchange;
      if ( oElement.onclick )		 element.onclick	= oElement.onclick;
      if ( oElement.oncontextmenu )	 element.oncontextmenu	= oElement.oncontextmenu;
      if ( oElement.ondblclick )	 element.ondblclick	= oElement.ondblclick;
      if ( oElement.onfocus )		 element.onfocus	= oElement.onfocus;
      if ( oElement.onkeydown )		 element.onkeydown	= oElement.onkeydown;
      if ( oElement.onkeypress )	 element.onkeypress	= oElement.onkeypress;
      if ( oElement.onkeyup )		 element.onkeyup	= oElement.onkeyup;
      if ( oElement.onmousedown )	 element.onmousedown	= oElement.onmousedown;
      if ( oElement.onmousemove )	 element.onmousemove	= oElement.onmousemove;
      if ( oElement.onmouseout )	 element.onmouseout	= oElement.onmouseout;
      if ( oElement.onmouseover )	 element.onmouseover	= oElement.onmouseover;
      if ( oElement.onmouseup )		 element.onmouseup	= oElement.onmouseup;
      if ( oElement.onselect )		 element.onselect	= oElement.onselect;

      element.events		= oElement.events;
   }

   this.disable = function ( element, event )
   {
      if ( !element.events || !element.events[ event ] || !element.events[ event ].action )
      {
	 return false;
      }
      element.events[ event ].disabledAction	= element.events[ event ].action;
      element.events[ event ].action		= "";
      return true;
   }

   this.enable = function ( element, event )
   {
      if ( !element.events || !element.events[ event ] || !element.events[ event ].disabledAction )
      {
	 return false;
      }
      element.events[ event ].action		= element.events[ event ].disabledAction;
      element.events[ event ].disabledAction	= "";
      return true;
   }
}

pageEvents	= new AllPageEvents();


/**
 * Each event type is assigned it's corrisponding run function:
 */
function elementEvent_onblur()		{ pageEvents.run( this, "onblur" );		}
function elementEvent_onchange()	{ pageEvents.run( this, "onchange" );		}
function elementEvent_onclick()		{ pageEvents.run( this, "onclick" );		}
function elementEvent_oncontextmenu()	{ pageEvents.run( this, "oncontextmenu" );	return false;	}	// Stops browser's context menu being displayed
function elementEvent_ondblclick()	{ pageEvents.run( this, "ondblclick" );		}
function elementEvent_onfocus()		{ pageEvents.run( this, "onfocus" );		}
function elementEvent_onkeydown()	{ pageEvents.run( this, "onkeydown" );		}
function elementEvent_onkeypress()	{ pageEvents.run( this, "onkeypress" );		}
function elementEvent_onkeyup()		{ pageEvents.run( this, "onkeyup" );		}
function elementEvent_onmousedown()	{ pageEvents.run( this, "onmousedown" );	}
function elementEvent_onmousemove()	{ pageEvents.run( this, "onmousemove" );	return false;	}
function elementEvent_onmouseout()	{ pageEvents.run( this, "onmouseout" );		}
function elementEvent_onmouseover()	{ pageEvents.run( this, "onmouseover" );	}
function elementEvent_onmouseup()	{ pageEvents.run( this, "onmouseup" );		}
function elementEvent_onselect()	{ pageEvents.run( this, "onselect" );		}

/*
Elements not being handled:
   onabort
   onerror
   onload
   onreset
   onsubmit
   onunload
*/

/**
 * END OF ELEMENT EVENTS
 */



/** ------------------------------------
 *   ELEMENT OFFSET
 * ------------------------------------
 *
 * Gets the position of an element relative to the top left of the page
 * returns object with properties .left & .top
 */

function elementOffset( element )
{
   offsetLeft	= 0;
   offsetTop	= 0;

   for ( var el	= element; el != null; el = el.offsetParent )
   {
      offsetLeft     += el.offsetLeft;
      offsetTop      += el.offsetTop;

      if ( el.border)
      {
	 offsetLeft  += parseInt( el.border / 2 );
	 offsetTop   += parseInt( el.border / 2 );
      }
   }

   return { left: offsetLeft, top: offsetTop }
}


/** ------------------------------------
 *   ELEMENT CSS PROPERTY
 * ------------------------------------
 *
 * For the given element, gets the property from the stylesheet
 * - works in IE and Netscape
 */

function elementCSSProperty( element, property )
{
   if ( element.currentStyle )		// Works in IE
   {
      return eval( "element.currentStyle." + property );
   }
   else					// Works in Netscape
   {
      return window.getComputedStyle( element, "" ).getPropertyValue( property );
   }
}


/** ------------------------------------
 *   GET ELEMENT
 * ------------------------------------
 *
 * Returns an element when given the element or it's ID
 */

function getElement( elementParam )
{
   if ( elementParam )
   {
      if ( elementParam.tagName )	// TODO: Is there a better way to identify that it is an HTML DOM element?
	 return elementParam;
      if ( element = document.getElementById( elementParam ) )
	 return element;
   }
   return false;
}


/** ------------------------------------
 *   GET ELEMENT BY TAGNAME AND NAME
 * ------------------------------------
 *
 * Looks for the first decendant of element with a matching tagName and name
 */

function getElementByTagNameAndName( parent, tagName, name )
{
   var allByTag	= parent.getElementsByTagName( tagName );
   for( var i = 0; i < allByTag.length; i++ )
   {
      if( allByTag[ i ].name == name )
      {
	 return allByTag[ i ];
      }
   }
   return null;
}

function getFormFieldByTagNameAndName( parent, name )
{
   var fieldTags	= new Array( 'input', 'select', 'textarea' );
   var element		= null;
   for( var i = 0; i < fieldTags.length && element == null; i++ )
   {
      element = getElementByTagNameAndName( parent, fieldTags[ i ], name );
   }
   return element;
}


/** ------------------------------------
 *   LOCATE PARENT ELEMENT
 * ------------------------------------
 *
 * Given an element this searches for a parent element with specified tagName
 */

function locateParentElement( tagName, element )
{
   if ( element.tagName.toUpperCase() == tagName.toUpperCase() )
   {
      return element;
   }
   if ( element.tagName.toUpperCase() != "BODY" )
   {
      return locateParentElement( tagName, element.parentNode );
   }
   return false;
}


/** ------------------------------------
 *   ON RESIZE
 * ------------------------------------
 */

window.addOnresize = function (fn) {
    if (!window.OnresizeCache) window.OnresizeCache = [];
    var ol = window.OnresizeCache;
    ol.push( fn );
}

window.onresize = function () {
    var ol = window.OnresizeCache;
    if (ol)
        for (var x = 0; x < ol.length; x++)
            ol[x]();
}
