/* SVN $Id: white.js 107 2009-07-23 13:57:22Z jeroen $ */
/* SVN $URL: file:///T:/SOURCE_SVN/Start_Website/httpdocs/js/white.js $ */

//##############################################################################
//# WHITE JAVASCRIPT LIBRARY
//##############################################################################

//### GLOBAL VARIABLES

if ('undefined' == typeof WHITE_PluginHooks)
{
  var WHITE_PluginHooks = new Object();
}

//### HOOK FUNCTIONS

function WHITE_RegisterHook(sHookName,mFunction)
{
  if ('object' != typeof WHITE_PluginHooks)
  {
    WHITE_PluginHooks = new Object();
  }
  if (!WHITE_IsArray(WHITE_PluginHooks[sHookName]))
  {
    WHITE_PluginHooks[sHookName] = new Array();
  }
  WHITE_PluginHooks[sHookName].push(mFunction);
}

function WHITE_ExecuteHooks(sHookName,aArgs)
{
  var aResult = new Object();
  if ('string' == typeof sHookName)
  {
    if ('undefined' == typeof aArgs)
    {
      aArgs = new Array();
    }
    if ( WHITE_IsArray(WHITE_PluginHooks)
         && WHITE_IsArray(WHITE_PluginHooks[sHookName]) ) // must be array object
    {
      var aFunctions = WHITE_PluginHooks[sHookName];
      for (var iFu=0;iFu<aFunctions.length;iFu++)
      {
        var fFunction = aFunctions[iFu];
        if ('string' == typeof fFunction)
        {
          fFunction = document[fFunction]; // not tested
        }
        if ( fFunction
             && 'function' == typeof(fFunction) )
        {
          var aFuncResult = fFunction(aArgs);
          if ('object' == typeof aFuncResult)
          {
            for (var sResultKey in aFuncResult)
            {
              aResult[sResultKey] = aFuncResult[sResultKey];
            }
          }
        }
      }
    }
  }
  return aResult;
}

//### STRING FUNCTIONS

function WHITE_Trim(sString)
{
  var sResult = sString;
  if ('string' == typeof sString)
  {
    var sOutput = sString;
    sOutput = sOutput.replace(/^\s+/g, '');
    sOutput = sOutput.replace(/\s+$/g, '');
    sResult = sOutput;
  }
  return sResult;
}

//### EVENT FUNCTIONS

function WHITE_AddLoadEvent(fAddFunction)
{
  //### For scheduling please use WHITE_AddBodyLoadFunction
  //###                        or WHITE_AddWindowLoadFunction
  //###
  //### WHITE_AddWindowLoadFunction calls this function once for all scheduled.

  // http://simonwillison.net/2004/May/26/addLoadEvent/
  if ('string' == typeof fAddFunction)
  {
    fAddFunction = new Function(fAddFunction);
  }
  var fOldOnload = window.onload;
  if ('function' != typeof window.onload)
  {
    window.onload = fAddFunction;
  }
  else
  {
    window.onload = function()
    {
      if (fOldOnload)
      {
        fOldOnload();
      }
      fAddFunction();
    }
  }
}

function WHITE_AddEvent( mElement, sEventType, fAddFunction )
{
  var aElements = new Array();
  if (WHITE_IsArray(mElement))
  {
    aElements = mElement;
  }
  else
  {
    aElements = new Array(mElement);
  }
  for (var iNr=0; iNr < aElements.length; iNr++)
  {
    WHITE_AddEvent_Single(aElements[iNr],sEventType, fAddFunction);
  }
}

function WHITE_AddEvent_Single(mElement, sEventType, fAddFunction) // private function
{
  var oElement = WHITE_GetElementFlex(mElement);

  if ('string' == typeof(fAddFunction))
  {
    fAddFunction = new Function(fAddFunction);
  }

  // http://ejohn.org/projects/flexible-javascript-events/
  if (oElement && 'function' == typeof(fAddFunction))
  {
    if ( oElement.attachEvent ) //ie
    {
      var sEventName = sEventType+WHITE_GetFunctionName(fAddFunction);
      oElement['e'+sEventName] = fAddFunction;
      oElement[sEventName] = function() {
        return oElement['e'+sEventName]( window.event );
      }
      oElement.attachEvent( 'on'+sEventType, oElement[sEventName] );
    }
    else //ff
    {
      oElement.addEventListener( sEventType, fAddFunction, false );
    }
  }
}

function WHITE_AddEventQuick( obj, sEventType, fAddFunction )
{
  // No passing of the event-variable in Internet Explorer
  // You can get in from window.event in your event func.
  if ('string' == typeof fAddFunction)
  {
    fAddFunction = new Function(fAddFunction);
  }
  if ('function' == typeof(fAddFunction))
  {
    if ( obj.attachEvent ) //ie
    {
      obj.attachEvent( 'on'+sEventType, fAddFunction );
    }
    else //ff
    {
      obj.addEventListener( sEventType, fAddFunction, false );
    }
  }
}

function WHITE_RemoveEvent( mElement, sEventType, fFunction )
{
  var aElements = new Array();
  if (WHITE_IsArray(mElement))
  {
    aElements = mElement;
  }
  else
  {
    aElements = new Array(mElement);
  }
  for (var iNr=0; iNr < aElements.length; iNr++)
  {
    var oElement = WHITE_GetElementFlex(aElements[iNr]);
    if ('function' == typeof(fFunction))
    {
      // http://ejohn.org/projects/flexible-javascript-events/
      if ( oElement.detachEvent )
      {
        if ('function' == typeof(oElement[sEventType+fFunction]))
        {
          oElement.detachEvent( 'on'+sEventType, oElement[sEventType+fFunction] );
          oElement[sEventType+fFunction] = null;
        }
      }
      else
      {
        oElement.removeEventListener( sEventType, fFunction, false );
      }
    }
  }
}

function WHITE_AddEventToClass(oParent,sClassName,sEventName,oFunction, aTagNames)
{
  // WARNING: Make shure you run this function AFTER the document has completed
  //          loading, for example in a function called using WHITE_AddBodyLoadFunction
  //
  var aElements = WHITE_GetElementsByClass(oParent,sClassName, aTagNames);
  WHITE_AddEvent(aElements,sEventName,oFunction);
}

function WHITE_AddEventToElement(mElement,sEventName,oFunction)
{
  var oElement = WHITE_GetElementFlex(mElement);
  if (oElement)
  {
    WHITE_AddEvent(oElement,sEventName,oFunction);
  }
}

function WHITE_CancelEvent(oEvent)
{
  if ('object' == typeof oEvent)
  {
    if ('boolean'  == typeof oEvent.returnValue)     oEvent.returnValue = false;
    if ('boolean'  == typeof oEvent.cancel)          oEvent.cancel = true;
    if ('function' == typeof oEvent.preventDefault)  oEvent.preventDefault();
    if ('function' == typeof oEvent.stopPropagation) oEvent.stopPropagation();
    if ('function' == typeof oEvent.preventDefault)  oEvent.preventDefault();
    //if (oEvent.cancelable) oEvent.preventDefault();
  }
  return false;
}

//###### AUTO LOAD FUNTIONS ######

function WHITE_WindowLoadFunctions_Install()
{
  if (arguments.callee.done)
  {
    return; // quit if already called
  }
  arguments.callee.done = true; // static variable
  window['WHITE_WindowLoad_Executed'] = false;
  WHITE_AddLoadEvent(WHITE_WindowLoadFunctions_Execute);
}

function WHITE_AddWindowLoadFunction(fAddFunction)
{
  if ('string' == typeof fAddFunction)
  {
    fAddFunction = new Function(fAddFunction);
  }
  if (!window.WHITE_WindowLoads)
  {
    WHITE_WindowLoadFunctions_Install();
    window['WHITE_WindowLoads'] = new Array()
  }
  if (window.WHITE_WindowLoad_Executed) // already loaded
  {
    fAddFunction(); // call function direct
  }
  else
  {
    window.WHITE_WindowLoads.push(fAddFunction);
  }
}

function WHITE_WindowLoadFunctions_Execute()
{
  if (window.WHITE_WindowLoad_Executed)
  {
    return; // quit if already called
  }
  window['WHITE_WindowLoad_Executed'] = true;
  if ('object' == typeof window.WHITE_WindowLoads)
  {
    for (var iN=0;iN<window.WHITE_WindowLoads.length;iN++)
    {
      if ('function' == typeof window.WHITE_WindowLoads[iN])
      {
        window.WHITE_WindowLoads[iN]();
      }
    }
  }
}

function WHITE_GetWindowLoadCompleted()
{
  return window['WHITE_WindowLoad_Executed'];
}

//####

function WHITE_BodyLoadFunctions_Install()
{
  //### http://www.cherny.com/webdev/27/domloaded-updated-again
  //### http://dean.edwards.name/weblog/2006/06/again/
  if (arguments.callee.done)
  {
    return; // quit if already called
  }
  arguments.callee.done = true; // static variable
  window['WHITE_BodyLoad_Executed'] = false;

  // for Mozilla browsers
  if (document.addEventListener)
  {
    document.addEventListener("DOMContentLoaded", WHITE_BodyLoadFunctions_Execute, false);
  }

  // for Internet Explorer (do not remove, is not comment)
  /*@cc_on
    var sVoidUrl = (location.protocol == "https:") ? "//0" : "javascript:void(0)";
    document.write("<scr"+"ipt id=__ie_onload defer src="+sVoidUrl+"><\/scr"+"ipt>");
    var oScriptEl = document.getElementById("__ie_onload");
    if ('object' == typeof oScriptEl)
    {
      oScriptEl.onreadystatechange = function()
      {
        if (this.readyState == "complete")
        {
          WHITE_BodyLoadFunctions_Execute(); // call the onload handler
        }
      };
    }
  @*/

  // for other browsers, and as backup
  WHITE_AddLoadEvent(WHITE_BodyLoadFunctions_Execute);
}

function WHITE_AddBodyLoadFunction(fAddFunction)
{
  if ('string' == typeof fAddFunction)
  {
    fAddFunction = new Function(fAddFunction);
  }
  if (!window.WHITE_BodyLoads)
  {
    WHITE_BodyLoadFunctions_Install();
    window['WHITE_BodyLoads'] = new Array()
  }
  if (window.WHITE_BodyLoad_Executed) // already loaded
  {
    fAddFunction(); // call function direct
  }
  else
  {
    window.WHITE_BodyLoads.push(fAddFunction);
  }
}

function WHITE_BodyLoadFunctions_Execute()
{
  if (window.WHITE_BodyLoad_Executed)
  {
    return; // quit if already called
  }
  window['WHITE_BodyLoad_Executed'] = true;
  if (window.WHITE_BodyLoads)
  {
    for (var iN=0;iN<window.WHITE_BodyLoads.length;iN++)
    {
      if ('function' == typeof window.WHITE_BodyLoads[iN])
      {
        window.WHITE_BodyLoads[iN]();
      }
    }
  }
}

function WHITE_GetBodyLoadCompleted()
{
  return window['WHITE_BodyLoad_Executed'];
}

//###### ELEMENT FUNCTIONS ######

function WHITE_GetElementFlex(mElement,mForm) {
  //###
  //### You can pass the following:
  //###  - an element object
  //###  - a string with the id of an object
  //###  - a fieldname + the name of the form containing it
  //###  - a fieldname + the form object containing it
  //###
  //### This function returns one of the following:
  //###  -      if possible: the object from the parameter mElement
  //###  - else if possible: an array of form objects with name==mElement
  //###  - else if possible: a single form object with name==mElement
  //###  - else if possible: a object with id==mElement
  //###  -             else: false
  //###
  var oResult = false;
  if ('undefined' == typeof mElement)
  {
    oResult = false;
  }
  if ('object' == typeof mElement)
  {
    oResult = mElement;
  }
  else if ('string' == typeof mElement && '' != mElement)
  {
    if (mForm && 'string' == typeof mForm)
    {
      mForm = document.getElementById(mForm);
    }
    if ('object' == typeof mForm && mForm.elements[mElement])
    {
      oResult = mForm.elements[mElement];
    }
    else
    {
      var oGetEl = document.getElementById(mElement);
      if (oGetEl)
      {
        oResult = oGetEl;
      }
      else // last resort: scan forms and pick first form field with matching name
      {
        if (document.forms)
        {
          for (var iF=0;iF<document.forms.length;iF++)
          {
            var oFrom = document.forms[iF];
            if (!oResult && oFrom && oFrom.elements[mElement])
            {
              oResult = oFrom.elements[mElement];
            }
          }
        }
      }
    }
  }
  return oResult;
}

function WHITE_GetElementById(oParent,mElement)
{
  if ('undefined' == typeof oParent)
  {
    oParent = document;
  }
  var oResult = false;
  if ('undefined' == typeof mElement)
  {
    oResult = false;
  }
  if ('object' == typeof mElement)
  {
    oResult = mElement;
  }
  else if ('string' == typeof mElement && '' != mElement)
  {
    var oGetEl = oParent.getElementById(mElement);
    if (oGetEl)
    {
      oResult = oGetEl;
    }
  }
}

function WHITE_GetElementsByClass(mParent,sClassName,mTagNames)
{
  var aResult = new Array();
  var oParent = WHITE_GetElementFlex(mParent);
  var aTagNames = new Array();
  if (null == mTagNames)
  {
    aTagNames = new Array('*');
  }
  else if (WHITE_IsArray(mTagNames))
  {
    aTagNames = mTagNames;
  }
  else
  {
    aTagNames = new Array(mTagNames);
  }
  if (oParent && sClassName)
  {
    var sFindStr = ' '+sClassName+' ';
    for (var iTag=0;iTag<aTagNames.length;iTag++)
    {
      var oElements = oParent.getElementsByTagName(aTagNames[iTag]); // collection
      //var oRe = new RegExp('\\b'+sClassName+'\\b');
      for (var iEl=0;iEl<oElements.length;iEl++)
      {
        //if(oRe.test(oElements[iEl].className)) // regexp = slow
        var sThisClass = ' '+oElements[iEl].className+' ';
        if (-1 != sThisClass.indexOf(sFindStr))
        {
          aResult.push(oElements[iEl]);
        }
      }
    }
  }
  return aResult;
}

function WHITE_GetElementsByTagName(mParent,mTagNames)
{
  var aResult = new Array();
  var aTagNames = new Array();
  if (WHITE_IsArray(mTagNames))
  {
    aTagNames = mTagNames;
  }
  else if ('string' == typeof mTagNames)
  {
    aTagNames = new Array(mTagNames);
  }
  var oParent = WHITE_GetElementFlex(mParent);
  if ('object' == typeof(oParent))
  {
    for (var iTa=0;iTa<aTagNames.length;iTa++)
    {
      var sTagName = aTagNames[iTa].toString();
      if (sTagName)
      {
        var oElements = oParent.getElementsByTagName(sTagName.toUpperCase()); // collection
        var aElementAr = WHITE_CollectionToArray(oElements);
        if (WHITE_IsArray(aElementAr))
        {
          aResult = aResult.concat(aElementAr);
        }
      }
    }
  }
  return aResult;
}

function WHITE_ReplaceElementContent(mElement, sInnerHTML)
{
  var oElement = WHITE_GetElementFlex(mElement);
  if (!sInnerHTML)
  {
    sInnerHTML = '';
  }
  if (oElement)
  {
    oElement.innerHTML = sInnerHTML;
  }
}

function WHITE_DisableSelect(mElement)
{
  var oElement = WHITE_GetElementFlex(mElement);
  if (oElement)
  {
    oElement.onselectstart = function() {
        return false;
    };
    oElement.unselectable = "on";
    oElement.style.MozUserSelect = "none";
  }
}

function WHITE_InsertAfterElement(mElement,sHtml,bInSpan) // bInSpan is default true
{
  if ('undefined' == typeof bInSpan)
  {
    bInSpan = true;
  }
  var oElement = WHITE_GetElementFlex(mElement);
  var oResult = false;
  if (oElement)
  {
    var oNewElement = false;
    if (bInSpan)
    {
      oNewElement = document.createElement("span");
      oNewElement.innerHTML = sHtml;
    }
    else
    {
      oNewElement = document.createElement(sHtml); // Only places the outer tag from sHtml, content gets lost
    }
    var oParentNode = oElement.parentNode;
    if (oParentNode)
    {
      var oNextNode = oElement.nextSibling; // This does not always work
      if (oNextNode)
      {
        oResult = oParentNode.insertBefore(oNewElement,oNextNode);
      }
      else
      {
        oResult = oParentNode.insertBefore(oNewElement);
      }
    }
    else
    {
      oResult = oElement.insertAdjacentElement('afterEnd', oNewElement); // Works better for IE, needs testing for FF
    }
  }
  return oResult;
}

function WHITE_InsertAfterElement2(mElement,sHtml,bInSpan) // bInSpan is default true
{
  var oElement = WHITE_GetElementFlex(mElement);
  var oResult = false;
  var oNewElement = false;
  if ('undefined' == typeof bInSpan)
  {
    bInSpan = true;
  }
  if (bInSpan)
  {
    oNewElement = document.createElement("span");
    oNewElement.innerHTML = sHtml;
  }
  else
  {
    oNewElement = document.createElement(sHtml); // Only places the outer tag from sHtml, content gets lost
  }
  if (oElement)
  {
    oElement = oElement.insertAdjacentElement('afterEnd', oNewElement); // Works better for IE, needs testing for FF
  }
  return oNewElement;
}

function WHITE_InsertBeforeElement(mElement,sHtml,bInSpan)
{
  if ('undefined' == typeof bInSpan)
  {
    bInSpan = true;
  }
  var oElement = WHITE_GetElementFlex(mElement);
  var oResult = false;
  if (oElement)
  {
    var oNewElement = false;
    if (bInSpan)
    {
      oNewElement = document.createElement("span");
      oNewElement.innerHTML = sHtml;
    }
    else
    {
      oNewElement = document.createElement(sHtml); // Only places the outer tag from sHtml, content gets lost
    }
    var oParentNode = oElement.parentNode;
    if (oParentNode)
    {
      oResult = oParentNode.insertBefore(oNewElement,oElement);
    }
  }
  return oResult;
}

//### CLASSNAME FUNCTIONS

function WHITE_AddClassName(mElement, sClassName)
{
  var aElements = new Array();
  if (WHITE_IsArray(mElement))
  {
    aElements = mElement;
  }
  else
  {
    aElements = new Array(mElement);
  }
  for (var iNr=0; iNr < aElements.length; iNr++)
  {
    var oElement = WHITE_GetElementFlex(aElements[iNr]);
    if (oElement && sClassName)
    {
      if (!WHITE_HasClassName(oElement,sClassName))
      {
        oElement.className += (oElement.className ? ' ' : '') + sClassName;
      }
    }
  }
}

function WHITE_RemoveClassName(mElement, sClassName)
{
  var aElements = new Array();
  if (WHITE_IsArray(mElement))
  {
    aElements = mElement;
  }
  else
  {
    aElements = new Array(mElement);
  }
  for (var iNr=0; iNr < aElements.length; iNr++)
  {
    var oElement = WHITE_GetElementFlex(aElements[iNr]);
    if (oElement && sClassName)
    {
      var oClassReg = new RegExp("(^|\\s+)" + sClassName + "(\\s+|$)")
      oElement.className = WHITE_Trim(oElement.className.replace(oClassReg, ' '));
    }
  }
}

function WHITE_AddRemoveClassName(mElement, sClassName, bState)
{
  if (bState)
  {
    WHITE_AddClassName(mElement,sClassName);
  }
  else
  {
    WHITE_RemoveClassName(mElement,sClassName);
  }
}

function WHITE_ToggleClassName(mElement, sClassName)
{
  var aElements = new Array();
  if (WHITE_IsArray(mElement))
  {
    aElements = mElement;
  }
  else
  {
    aElements = new Array(mElement);
  }
  for (var iNr=0; iNr < aElements.length; iNr++)
  {
    var oElement = WHITE_GetElementFlex(aElements[iNr]);
    if (oElement && sClassName)
    {
      if (WHITE_HasClassName(oElement,sClassName))
      {
        WHITE_RemoveClassName(oElement, sClassName)
      }
      else
      {
        WHITE_AddClassName(oElement, sClassName);
      }
    }
  }
}

function WHITE_HasClassName(mElement, sClassName  )
{
  var bResult = false;
  var oElement = WHITE_GetElementFlex(mElement);
  if (oElement && sClassName)
  {
    var oClassReg = new RegExp("(^|\\s)" + sClassName + "(\\s|$)");
    var sObjClassName = oElement.className;
    if ( 'undefined' != typeof sObjClassName
         && sObjClassName.length > 0 )
    {
      if (sObjClassName == sClassName || oClassReg.test(sObjClassName))
      {
        bResult = true;
      }
    }
 }
  return bResult;
}

function WHITE_DisableSelectClass(oParent,sClassName, sTagName)
{
  var aElements = WHITE_GetElementsByClass(oParent,sClassName, sTagName);
  for (var iEl=0;iEl<aElements.length;iEl++)
  {
    WHITE_DisableSelect(aElements[iEl]);
  }
}

function WHITE_IsArray(mObj)
{
  var bResult = false;
  if ('object' == typeof(mObj)
      && mObj.constructor == Array)
  {
    bResult = true;
  }
  return bResult;
}


function WHITE_GetFunctionName(oFunction)
{
  var name=/\W*function\s+([\w\$]+)\(/.exec(oFunction);
  if (!name) return 'Anonymous';
  return name[1];
}

//#### FORM FUNCTIONS

function WHITE_IsFormFieldSet(mField,oForm) {
  var bResult = false;
  var mFieldValue = WHITE_GetFormFieldValue(mField,oForm);
  var mFieldValue = WHITE_Trim(mFieldValue);
  if (mFieldValue)
  {
    bResult = true;
  }
  return bResult;
}

function WHITE_GetFormFieldValue(mField,oForm)
{
  var oElement = false;
  oElement = WHITE_GetFormField(mField,oForm);
  var mResult = false;
  if (oElement)
  {
    if ('undefined' != typeof oElement[0] && 'radio' == oElement[0].type) // array of radio buttons
    {
      for (var iNr=0; iNr < oElement.length; iNr++)
      {
        if (oElement[iNr].checked)
        {
          mResult = true;
        }
      }
    }
    else if ('select-one' == oElement.type)  // drop-down select
    {
      if (oElement.options[oElement.selectedIndex])
      {
        if (oElement.options[oElement.selectedIndex].value)
        {
          // The <option> tag needs to containt "value=..." to make this work.
          mResult = oElement.options[oElement.selectedIndex].value;
        }
        else
        {
          mResult = oElement.options[oElement.selectedIndex].innerText;
        }
      }
    }
    else if ('checkbox' == oElement.type)
    {
      mResult = oElement.checked;
    }
    else if ('radio' == oElement.type)
    {
      mResult = oElement.checked;
    }
    else // default check value, works for type = text, file, textarea, ...
    {
      if ( null != oElement.value
           && 0 < oElement.value.length )
      {
        mResult = oElement.value;
      }
    }
  }
  return mResult;
}

function WHITE_GetFormField(mField,oForm)
{
  var oElement = WHITE_GetElementFlex(mField,oForm);
  if (oElement && !oForm && oElement.name && oElement.form)
  {
    var oFormEl = WHITE_GetElementFlex(oElement.name,oElement.form);
    if (oFormEl)
    {
      oElement = oFormEl;
    }
  }
  return oElement;
}

/*###### FIELD EXPLANATIONS ######*/
/*

Example:

  var oForm = WHITE_GetElementFlex('tellafriend_form');
  if ('object' == typeof oForm)
  {
    WHITE_InitFieldExplanation('friend_firstname', 'voornaam ontvanger');
    WHITE_InitFieldExplanation('friend_surname',   'achternaam ontvanger');
    WHITE_InitFieldExplanation('friend_email',     'email ontvanger');
    WHITE_AddEvent(oForm, 'submit', WHITE_FormRemoveEplanationsEvent);
  }

Add to CSS:

input.explanation {
  color:                       #AAA;
}

*/

function WHITE_InitFieldExplanation(mInput, sExplanation)
{
  var oInput = WHITE_GetElementFlex(mInput);
  if ('object' == typeof oInput)
  {
    oInput['sExplanation'] = sExplanation;
    WHITE_FieldRefillExplanation(oInput);
    WHITE_AddEvent(oInput, 'focus', WHITE_FieldRemoveExplanationEvent);
    WHITE_AddEvent(oInput, 'blur',  WHITE_FieldRefillExplanationEvent);
  }
}

function WHITE_FieldRemoveExplanationEvent(oEvent) // add this event to field:focus
{
  WHITE_FieldRemoveExplanation(this);
}

function WHITE_FieldRemoveExplanation(oElement)
{
  if ( oElement.sExplanation == oElement.value
       && WHITE_HasClassName(oElement, 'explanation') )
  {
    WHITE_RemoveClassName(oElement, 'explanation');
    oElement.value = '';
  }
}

function WHITE_FieldRefillExplanationEvent(oEvent) // add this event to field:blur
{
  WHITE_FieldRefillExplanation(this);
}

function WHITE_FieldRefillExplanation(oElement)
{
  if ('' == WHITE_Trim(oElement.value))
  {
    WHITE_AddClassName(oElement, 'explanation');
    oElement.value = oElement.sExplanation;
  }
}

function WHITE_FormRemoveEplanationsEvent(oEvent) // add this event to form:submit
{
  var aResetFormFields = WHITE_GetElementsByTagName(this, 'input');
  for (var iNr=0; iNr<aResetFormFields.length; iNr++)
  {
    var oResetFormField = aResetFormFields[iNr];
    WHITE_FieldRemoveExplanation(oResetFormField);
  }
}

/*###### FOLD FUNCTIONS ######*/
//###
//### do on load:   WHITE_InitializeFolds();
//###
//### Add  onclick="WHITE_FoldToggle('foldhead')"  to the fold head
//###

function WHITE_FoldHeadClickEvent(oEvent)
{
  var oBlock = WHITE_GetElementFlex(this.id+'_foldout');
  if (oBlock)
  {
    WHITE_ToggleClassName(oBlock, 'hidden');
    WHITE_FoldHeadUpdate(this);
  }
}

function WHITE_FoldHeadUpdate(mHeadElement)
{
  //
  // Foldout must have id from foldhead + '_foldout'
  // Usable classnames in foldhead: showwhenopen showwhenclosed
  //
  var oHeadElement = WHITE_GetElementFlex(mHeadElement);
  var oBlock = WHITE_GetElementFlex(oHeadElement.id+'_foldout');
  if (oHeadElement && oBlock)
  {
    var oElementFoldout = WHITE_GetElementFlex(oHeadElement.id+'_foldout');
    var bIsOpen = !WHITE_HasClassName(oElementFoldout, 'hidden');

    if (bIsOpen)
    {
      WHITE_AddClassName(oHeadElement, 'foldhead_open');
      WHITE_RemoveClassName(oHeadElement, 'foldhead_closed');
    }
    else
    {
      WHITE_RemoveClassName(oHeadElement, 'foldhead_open');
      WHITE_AddClassName(oHeadElement, 'foldhead_closed');
    }

    var aShowHide  = WHITE_GetElementsByClass(oHeadElement,'showwhenclosed','*');
    for (var iNr=0; iNr < aShowHide.length; iNr++)
    {
      if (bIsOpen)
      {
        WHITE_AddClassName(aShowHide[iNr], 'hidden');
      }
      else
      {
        WHITE_RemoveClassName(aShowHide[iNr], 'hidden');
      }
    }
    var aShowHide = WHITE_GetElementsByClass(oHeadElement,'showwhenopen','*');
    for (var iNr=0; iNr < aShowHide.length; iNr++)
    {
      if (bIsOpen)
      {
        WHITE_RemoveClassName(aShowHide[iNr], 'hidden');
      }
      else
      {
        WHITE_AddClassName(aShowHide[iNr], 'hidden');
      }
    }

    //// Depreciated: showonopen + showonclose
    var aShowHide  = WHITE_GetElementsByClass(oHeadElement,'showonopen','div');
    for (var iNr=0; iNr < aShowHide.length; iNr++)
    {
      if (bIsOpen)
      {
        WHITE_AddClassName(aShowHide[iNr], 'hidden');
      }
      else
      {
        WHITE_RemoveClassName(aShowHide[iNr], 'hidden');
      }
    }
    var aShowHide = WHITE_GetElementsByClass(oHeadElement,'showonclose','div');
    for (var iNr=0; iNr < aShowHide.length; iNr++)
    {
      if (bIsOpen)
      {
        WHITE_RemoveClassName(aShowHide[iNr], 'hidden');
      }
      else
      {
        WHITE_AddClassName(aShowHide[iNr], 'hidden');
      }
    }
    /// /Depreciated: showonopen + showonclose

    var aImages = WHITE_GetElementsByTagName(oHeadElement,'img');
    for (var iNr=0; iNr < aImages.length; iNr++)
    {
      if (aImages[iNr].src)
      {
        var sImgSrc = aImages[iNr].src;
        if (bIsOpen)
        {
          sImgSrc = sImgSrc.replace(/close/, 'open');
        }
        else
        {
          sImgSrc = sImgSrc.replace(/open/, 'close');
        }
        aImages[iNr].src = sImgSrc;
      }
    }

    var aHeadInputs = WHITE_GetElementsByTagName(oHeadElement,'input');
    for (var iIn=0;iIn<aHeadInputs.length;iIn++)
    {
      if ('checkbox' == aHeadInputs[iIn].type)
      {
        aHeadInputs[iIn].checked = bIsOpen;
      }
    }

    var aBlockInputs = WHITE_GetElementsByTagName(oBlock,'input');
    for (var iNr=0; iNr < aBlockInputs.length; iNr++)
    {
      if (bIsOpen)
      {
        if (WHITE_HasClassName(aBlockInputs[iNr],'required_dis'))
        {
          WHITE_RemoveClassName(aBlockInputs[iNr],'required_dis');
          WHITE_AddClassName(aBlockInputs[iNr],'required');
        }
      }
      else // not open
      {
        if (WHITE_HasClassName(aBlockInputs[iNr],'required'))
        {
          WHITE_RemoveClassName(aBlockInputs[iNr],'required');
          WHITE_AddClassName(aBlockInputs[iNr],'required_dis');
        }
      }
    }
    var oHookParam = new Object();
    oHookParam['oHeadElement'] = oHeadElement;
    oHookParam['oBlockElement'] = oBlock;
    oHookParam['bIsOpen'] = bIsOpen;
    var oHookResult = WHITE_ExecuteHooks('WHITE_FoldHeadAfterUpdate',oHookParam);
  }
}

function WHITE_FoldOut(mHeadElement)
{
  var oHeadElement = WHITE_GetElementFlex(mHeadElement);
  if (oHeadElement)
  {
    var oBlock = WHITE_GetElementFlex(oHeadElement.id+'_foldout');
    if (WHITE_HasClassName(oBlock,'hidden'))
    {
      WHITE_RemoveClassName(oBlock, 'hidden');
      WHITE_FoldHeadUpdate(oHeadElement);
    }
  }
}

function WHITE_FoldIn(mHeadElement)
{
  var oHeadElement = WHITE_GetElementFlex(mHeadElement);
  if (oHeadElement)
  {
    var oBlock = WHITE_GetElementFlex(oHeadElement.id+'_foldout');
    if (!WHITE_HasClassName(oBlock,'hidden'))
    {
      WHITE_AddClassName(oBlock, 'hidden');
      WHITE_FoldHeadUpdate(oHeadElement);
    }
  }
}

function WHITE_FoldToggle(mHeadElement)
{
  var oHeadElement = WHITE_GetElementFlex(mHeadElement);
  if (oHeadElement)
  {
    var oBlock = WHITE_GetElementFlex(oHeadElement.id+'_foldout');
    if (WHITE_HasClassName(oBlock,'hidden'))
    {
      WHITE_FoldOut(oHeadElement);
    }
    else
    {
      WHITE_FoldIn(oHeadElement);
    }
  }
}

function WHITE_InitializeFolds()
{
  var aCheckElements = new Array('li','div');
  var aFoldHeads = WHITE_GetElementsByClass(document,'foldhead', aCheckElements);
  for ( var iEl=0 ; iEl<aFoldHeads.length ; iEl++ )
  {
    //### For each foldhead
    var oHeadElement = aFoldHeads[iEl];
    if (oHeadElement)
    {
      var aHeadInputs = WHITE_GetElementsByTagName(oHeadElement,'input');
      //### If it has inputs
      if (0 < aHeadInputs.length)
      {
        var bHeadIsChecked = false;
        var bCheckBoxFound = false;
        //### For each input
        for (var iIn=0;iIn<aHeadInputs.length;iIn++)
        {
          //### If it is a checkbox
          if ( 'checkbox' == aHeadInputs[iIn].type )
          {
            bCheckBoxFound = true;
            if ( aHeadInputs[iIn].checked )
            {
              bHeadIsChecked = true;
            }
          }
        }
        if (bCheckBoxFound)
        {
          if (bHeadIsChecked)
          {
            WHITE_FoldOut(oHeadElement);
          }
          else
          {
            WHITE_FoldIn(oHeadElement);
          }
        }
      }
      WHITE_FoldHeadUpdate(oHeadElement);
    }
  }
}

/*###### ######*/

function WHITE_CollectionToArray(oCollection)
{
  var aResult = new Array();
  for (var iItem=0,iLength=oCollection.length; iItem < iLength; iItem++)
  {
    aResult.push(oCollection[iItem]);
  }
  return aResult;
}

function WHITE_ChangeOverImagesInit()
{
  /*
  This function changes images within a link on mouseover.
  Add class="overlink" to the link and class="overimage" to the image.
  The link tag must be arround the image.

  You can also add 'overimage' to separate images

  Add to your js-code:
  if ('function' == typeof WHITE_AddLoadEvent)
  {
    WHITE_AddLoadEvent(WHITE_ChangeOverImagesInit);
  }

  We have seen problems when initializing WHITE_AddBodyLoadFunction... needs testing.

  */

  var aLinkTags = new Array('a','div');
  var aOverLinks = WHITE_GetElementsByClass(document, 'overlink',aLinkTags);
  var aImageTags = new Array('IMG','INPUT');

  if (0 < aOverLinks.length)
  {
    for (var iEl=0;iEl<aOverLinks.length;iEl++)
    {
      var oOverLink = aOverLinks[iEl];
      if ('object' == typeof oOverLink)
      {
        WHITE_AddEventToElement(oOverLink, 'mouseover', WHITE_OnMouseOverImage);
        WHITE_AddEventToElement(oOverLink, 'mouseout',  WHITE_OnMouseOutImage);

        var aImages = new Array();
        var aOverImages = WHITE_GetElementsByClass(oOverLink, 'overimage', aImageTags);
        for (var iEl2=0;iEl2<aOverImages.length;iEl2++)
        {
          var oOverImage = aOverImages[iEl2];
          if ('object' == typeof oOverImage)
          {
            WHITE__SetImageOverSrc(oOverImage);
            aImages[iEl2] = oOverImage;
          }
        }
        oOverLink.aImages = aImages;
      }
    }
  }

  var aOverImages = WHITE_GetElementsByClass(document, 'overimage', aImageTags);
  for (var iOI=0;iOI<aOverImages.length;iOI++)
  {
    var oImage = aOverImages[iOI];
    if (!oImage['MouseOverSrc']) // only do ones not already done by aOverLinks loop
    {
      WHITE__SetImageOverSrc(oImage);
      WHITE_AddEventToElement(oImage, 'mouseover', WHITE_OnMouseOverImage);
      WHITE_AddEventToElement(oImage, 'mouseout',  WHITE_OnMouseOutImage);
    }
  }
}

function WHITE__SetImageOverSrc(oImage) // private function
{
  if ('object' == typeof oImage)
  {
    if (!oImage['MouseOverSrc'])
    {
      /*if (-1 != oImage.src.indexOf('spacer.gif'))
      {
        // for all spacer images
        oImage['MouseOverSrc'] = oImage.src;;
        oImage['DefaultSrc']   = oImage.src;;
      }
      else*/ if (-1 != oImage.src.indexOf('_over.'))
      {
        // src is already containing '_over.'
        oImage['MouseOverSrc'] = oImage.src;;
        oImage['DefaultSrc']   = oImage.src.replace(/_over\.(\w+)$/i, '.$1');
        WHITE_PreloadImages(oImage['DefaultSrc']);
      }
      else
      {
        // src is not containing '_over.'
        oImage['DefaultSrc']   = oImage.src;
        oImage['MouseOverSrc'] = oImage.src.replace(/\.(\w+)$/i, '_over.$1');
        WHITE_PreloadImages(oImage['MouseOverSrc']);
      }
    }
  }
}

function WHITE_OnMouseOverImage() //# Called by WHITE_ChangeOverImagesInit function
{
  if (this.aImages) // probably a link
  {
    aOverImages = this.aImages;
    if (0 < aOverImages.length)
    {
      for (var iEl=0;iEl<aOverImages.length;iEl++)
      {
        oOverImage = aOverImages[iEl];
        if ('object' == typeof oOverImage
            && oOverImage.MouseOverSrc)
        {
          WHITE__SetImageSrc(oOverImage,oOverImage.MouseOverSrc);
        }
      }
    }
  }
  else
  {
    if (this.MouseOverSrc)
    {
      WHITE__SetImageSrc(this,this.MouseOverSrc);
    }
  }
}

function WHITE__SetImageSrc(oElement,sNewSrc) // private function
{
  if ('object' == typeof oElement)
  {
    if (oElement['HasIE6PngFix'])
    {
      // TODO: Fix this, is not working
      // oElement.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + sNewSrc + "', sizingMethod='scale')";
    }
    else
    {
      oElement.src = sNewSrc;
    }
  }
}

function WHITE_OnMouseOutImage() //# Called by WHITE_ChangeOverImagesInit function
{
  if (this.aImages) // probably a link
  {
    aOverImages = this.aImages;
    if (0 < aOverImages.length)
    {
      for (var iEl=0;iEl<aOverImages.length;iEl++)
      {
        oOverImage = aOverImages[iEl];
        if ('object' == typeof oOverImage
            && oOverImage.DefaultSrc)
        {
          WHITE__SetImageSrc(oOverImage,oOverImage.DefaultSrc);
        }
      }
    }
  }
  else
  {
    if (this.DefaultSrc)
    {
      WHITE__SetImageSrc(this,this.DefaultSrc);
    }
  }
}

function WHITE_PreloadImages(mUrl)
{
  if (document.images)
  {
    var aUrl = new Array();
    if (WHITE_IsArray(mUrl))
    {
      aUrl = mUrl;
    }
    else
    {
      aUrl = new Array(mUrl);
    }
    if(!document.WHITE_PreloadImages)
    {
      document.WHITE_PreloadImages=new Array();
    }
    var iCount = document.WHITE_PreloadImages.length;
    for (var iU=0;iU<aUrl.length;iU++)
    {
      sUrl = aUrl[iU];
      if (0 != sUrl.indexOf("#"))
      {
        WHITE_PreloadImages[iCount] = WHITE_GetNewImageObject(sUrl);
        iCount++;
      }
    }
  }
}

function WHITE_GetNewImageObject(sUrl)
{
  var oResult = false;
  if ('string' == typeof sUrl)
  {
    if (document.images)
    {
      oResult = new Image();
      oResult.src = sUrl;
    }
  }
  return oResult;
}

function GetVariableFromQueryString(sVariable, sQueryString) // DEPRECIATED function
{
  return WHITE_GetVariableFromQueryString(sVariable, sQueryString);
}

function WHITE_GetVariableFromQueryString(sVariable, sQueryString)
{
  // function to get URL parameter
  var sResult = undefined;
  if (typeof sQueryString != 'string')
  {
    sQueryString = document.location.search.substring(1);
  }
  var aVars = sQueryString.split("&");
  for (var i=0;i<aVars.length;i++)
  {
    var aPair = aVars[i].split("=");
    if (aPair[0] == sVariable)
    {
      sResult = unescape(aPair[1].replace(/\+/g,  " "));
    }
  }
  return sResult;
}

function WHITE_ConnectClickExec(oEvent)
{
  if (this.oWHITE_TargetElement && !oEvent['WHITE_ConnectedClick'])
  {
    if (this.oWHITE_TargetElement.click) // IE has this for every link, executes onlick
    {
      this.oWHITE_TargetElement.click();
    }
    else
    {
      var bGoHref = true;
      var oClickEvent = document.createEvent("MouseEvents");
      oClickEvent.initEvent("click", true, true);
      oClickEvent['WHITE_ConnectedClick'] = true;
      if (this.oWHITE_TargetElement.getAttribute('onClick'))
      {
        bGoHref = this.oWHITE_TargetElement.dispatchEvent(oClickEvent)
      }
      if (bGoHref && this.oWHITE_TargetElement.href) // Needed for FF for links
      {
        document.location = this.oWHITE_TargetElement.href;
      }
    }
  }
}

function WHITE_ConnectClick(mMakeClickAble,mIsClickAble)
{
  //### mIsClickAble must be already clickable,
  //### This function makes mMakeClickAble also clickable,
  //### with same result as clicking on mIsClickAble

  //### mMakeClickAble and mIsClickAble can be the same object
  var oElement = WHITE_GetElementFlex(mMakeClickAble);
  var oTarget = WHITE_GetElementFlex(mIsClickAble);
  if ( oElement && oTarget )
  {
    //### List of elements inside mMakeClickAble to make clickable
    var aUpdateTagNames = new Array('img');
    //###
    //### Connect click for Element itself
    if (oElement != oTarget)
    {
      oElement['oWHITE_TargetElement'] = oTarget;
      WHITE_AddEventToElement(oElement,'click',WHITE_ConnectClickExec);
    }
    //### Connect click to elements children of with tagtype in aUpdateTagNames
    for (var iTagNr=0;iTagNr<aUpdateTagNames.length;iTagNr++)
    {
      var sTagName = aUpdateTagNames[iTagNr];
      var aChildren = WHITE_GetElementsByTagName(oElement,sTagName);
      for (var iEl=0;iEl<aChildren.length;iEl++)
      {
        if ( aChildren[iEl]
             && aChildren[iEl] != oTarget )
        {
          var oChild = aChildren[iEl];
          oChild['oWHITE_TargetElement'] = oTarget;
          WHITE_AddEventToElement(oChild,'click',WHITE_ConnectClickExec);
        }
      }
    }
  }
}

function WHITE_MakeBigLinks()
{
  var aBigLinkTags = new Array('div');
  var aBigLinks = WHITE_GetElementsByClass(document,'makebiglink',aBigLinkTags);
  for (var iEl=0;iEl<aBigLinks.length;iEl++)
  {
    if (aBigLinks[iEl])
    {
      var oBigLink = aBigLinks[iEl];
      var aLinks = WHITE_GetElementsByTagName(oBigLink,'a');
      if (aLinks[0] && aLinks[0].href)
      {
        var oLink = aLinks[0];
        WHITE_ConnectClick(oBigLink,oLink);
        oBigLink.style.cursor = 'pointer';
      }
    }
  }
}

function WHITE_GetParentNode(mElement,sTagType)
{
  oElement = WHITE_GetElementFlex(mElement);
  oResult = false;
  if (oElement)
  {
    if (null == sTagType)
    {
      sTagType = '*';
    }
    oResult = oElement;
    do
    {
      oResult = oResult.parentNode;
    }
    while ( 'object' == typeof oResult
            && '*' != sTagType
            && sTagType.toUpperCase() != oResult.nodeName )
  }
  return oResult;
}

function WHITE_IE6PngFix(sSpacerUrl)
{
  /* Add to the html header:

  <!--[if IE 6]>
    <script type="text/javascript">
      WHITE_AddBodyLoadFunction(WHITE_IE6PngFix);
    </script>
  <![endif]-->

  */
  if ('undefined' == typeof sSpacerUrl)
  {
    sSpacerUrl = '/images/spacer.gif';
    if ('file:' == document.location.protocol)
    {
      sSpacerUrl = 'images/spacer.gif';
    }
  }

  var aFgTags = new Array('img','input');

  // Do not 'body': because of an IE bug onclicks on contained elements will not work anymore
  var aBgTags = new Array('div','span','table','tr','th','td','h1','h2','h3','h4','h5','h6','p','hr','a','li','ul','ol');

  // Add all 'active' elements here
  var aFixActiveTags = new Array('A','INPUT','IMG'); //

  var aHidden = WHITE_GetElementsByClass(document,'hidden','*');
  WHITE_RemoveClassName(aHidden,'hidden'); // make all visible

  var aFgElements = WHITE_GetElementsByTagName(document,aFgTags);
  for (var iEl=0;iEl<aFgElements.length;iEl++)
  {
    oElement = aFgElements[iEl];
    if (oElement.src && oElement.src.match(/\.png$/i) !== null)
    {
      var sSrc = oElement.src;
      if ( !oElement.style.width || !oElement.style.height )
      {
        var iSetWidth = oElement.width;
        var iSetHeight = oElement.height;
        oSizeImg = WHITE_GetNewImageObject(sSrc);

        // Fix for sometimes incorrect .width and .height
        // If the the width or height is bigger than the natural width and height of the image,
        // so the image is strechted, it is probably miscalculated by IE6, so then we use the
        // natural image size.
        if (oSizeImg && oSizeImg.width && oSizeImg.height)
        {
          if ( !iSetWidth
               || !iSetHeight
               || oElement.width > oSizeImg.width
               || oElement.height > oSizeImg.height )
          {
            iSetWidth = oSizeImg.width;
            iSetHeight = oSizeImg.height;
          }
        }
        if (oSizeImg && iSetWidth && iSetHeight)
        {
          // always set both width and height at same time to prevent image from getting square because the space is.
          oElement.style.width = iSetWidth + "px";
          oElement.style.height = iSetHeight + "px";
        }
      }
      oElement.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + sSrc + "', sizingMethod='scale')";
      oElement.src = sSpacerUrl;
      oElement['HasIE6PngFix'] = true;
    }
  }

  var aBgElements = WHITE_GetElementsByTagName(document,aBgTags);
  for (var iEl=0;iEl<aBgElements.length;iEl++)
  {
    oElement = aBgElements[iEl];
    if (oElement.currentStyle.backgroundImage.match(/\.png/i) !== null)
    {
      var sSizingMethod = 'scale';
      var sBackgroundStyle  = oElement.currentStyle.backgroundImage;
      var sSrc = sBackgroundStyle.substring(5,sBackgroundStyle.length-2);
      if (oElement.currentStyle.backgroundRepeat == 'no-repeat')
      {
        sSizingMethod = 'crop';
      }
      oElement.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + sSrc + "', sizingMethod='" + sSizingMethod + "')";
      oElement.style.backgroundImage = 'url('+sSpacerUrl+')';
      oElement['HasIE6PngFix'] = true;
      var aFixActive = WHITE_GetElementsByTagName(oElement,aFixActiveTags);
      for (var iAc=0;iAc<aFixActive.length;iAc++)
      {
        var oActive = aFixActive[iAc];
        if (!WHITE_HasClassName(oActive,'noposfix'))
        {
          if (!oActive.style.position) // This 'if does not already have position style' needs to be tested (ll be)
          {
            oActive.style.position = 'relative';
          }
          var aFixActiveChilderen = WHITE_GetElementsByTagName(oActive,'*');
          for (var iCh=0;iCh<aFixActiveChilderen.length;iCh++)
          {
            var oChild = aFixActiveChilderen[iCh];
            if (!WHITE_HasClassName(oActive,'noposfix')
                && !oChild.style.position)
            {
              oChild.style.position = 'relative';
            }
          }
        }
      }
    }
  }

  WHITE_AddClassName(aHidden,'hidden'); // make all hidden again
}

function WHITE_Write(sStr)
{
  document.write(sStr);
}

/*
function WHITE_FlashFix()
{
  var aElements = WHITE_GetElementsByClass(document,'flashdiv','div');
  for (var iEl=0;iEl<aElements.length;iEl++)
  {
    if (aElements[iEl])
    {
      var oFlashDiv = aElements[iEl];
      var aNoScript = WHITE_GetElementsByTagName(oFlashDiv,'noscript');
      if (aNoScript[0])
      {
        var sFlashHtml = aNoScript[0].innerHTML;
    		oFlashDiv.innerHTML = sFlashHtml;
        //var FlashHtml = src.value = DOMtoString(output);

		    //for (var i = 0, j = aNoScript[0].childNodes.length; i < j; i++)
        //{
        //  var oNode = aNoScript[0].childNodes[i].cloneNode(true);
        //  oFlashDiv.appendChild(oNode);
        //}
  			//oFlashDiv.removeChild(aNoScript[0]);
    		//var DOM = stringToDOM(input.value);
    		//output.appendChild(DOM);
      }
    }
  }
}
*/

function WHITE_InitAddBookmarkLinks()
{
  //
  // Use in NetActual Template:
  // <a href="#" title="WHITE - {title}" class="bookmarklink">Bij Favorieten</a>
  //
  // Add to your 'Main_Initialize' funtion in main.js:
  // WHITE_InitAddBookmarkLinks();
  //
  var aElements = WHITE_GetElementsByClass(document,'bookmarklink', 'a');
  for (var iEl=0;iEl<aElements.length;iEl++)
  {
    if ( aElements[iEl]
         && document.location )
    {
      oLink = aElements[iEl];
      if ( !oLink.title
           && document.location.host )
      {
        oLink.title = document.location.host;
      }
      if ( !oLink.href
           || (oLink.href.match(/#$/i) !== null) )
      {
        oLink.href = document.location;
      }
      oLink.rel = 'sidebar';
      if (!window.opera) // not for Opera
      {
        WHITE_AddEvent(oLink,'click',WHITE_AddBookmarkEvent);
      }
    }
  }
}

function WHITE_AddBookmarkEvent(oEvent)
{
  var bResult = false;
  if ( this.href && this.title )
  {
    // inspired by http://www.dynamicsitesolutions.com/
    var sUserAgent = navigator.userAgent.toLowerCase();
    var bIsKonq=(sUserAgent.indexOf('konqueror')!=-1);
    var bIsWebKit=(sUserAgent.indexOf('webkit')!=-1);
    var bIsMac=(sUserAgent.indexOf('mac')!=-1);
    var sButtonStr=bIsMac?'Command/Cmd':'CTRL';

    if ( window.external
         && ( !document.createTextNode
              || (typeof(window.external.AddFavorite)=='unknown') ) ) // IE Win Favorite
    {
  		window.external.AddFavorite( this.href, this.title);
    }
    else if (window.sidebar && 'function' == typeof window.sidebar.addPanel ) // Mozilla Firefox Bookmark
    {
  		window.sidebar.addPanel(this.title, this.href,"");
  	}
  	else if ( window.opera ) // Opera Bookmark
    {
      // On Opera this event is not attached by WHITE_InitAddBookmark.
    }
    else if(bIsKonq)
    {
      alert('You need to press CTRL + B to bookmark our site.');
    }
    else if(window.home || bIsWebKit) // Firefox, Netscape, Safari, iCab, Chrome
    {
      alert('You need to press '+sButtonStr+' + D to bookmark this page.');
    }
    else if(!window.print || bIsMac) // IE5/Mac and Safari 1.0
    {
      alert('You need to press Command/Cmd + D to bookmark this page.');
    }
    else
    {
      alert('In order to bookmark this page you need to do so manually through your browser.');
    }
  }
	WHITE_CancelEvent(oEvent);
  return bResult;
}

function WHITE_SetCookie(sName,sValue,iExpDays)
{
  if ('undefined' == typeof iExpDays)
  {
    iExpDays = 1;
  }
  var oExDate=new Date();
  oExDate.setDate(oExDate.getDate()+iExpDays);
  var sDomain = document.location.hostname;
  sDomain = sDomain.replace(/^www\./,'');
  document.cookie=sName+ "=" +escape(sValue)+ ";path=/; expires="+oExDate.toGMTString()+"; domain="+sDomain;
}

function WHITE_GetCookie(sName)
{
	var mResult = null;
	var aCookies = document.cookie.split( ';' );
	for ( var iNr = 0; iNr < aCookies.length; iNr++ )
	{
		var aCookieDuo = aCookies[iNr].split( '=' );
		var sCookieName = WHITE_Trim(aCookieDuo[0]);

		if ( sCookieName == sName )
		{
			if ( aCookieDuo.length > 1 )
			{
				sCookieValue = WHITE_Trim(aCookieDuo[1]);
			  mResult = unescape( sCookieValue );
			}
			else
			{
			  mResult = '';
			}
			break;
		}
	}
	return mResult;
}

function WHITE_TrackIntLink(oElement)
{
  // for Google Tracking links between different domains of one site
  // <a href="http://www.othersite.com" onclick="return ('function'==typeof WHITE_TrackIntLink)?WHITE_TrackIntLink(this):1;">
  // <form action="http://www.othersite.com/script.php" method="post" onsubmit="return ('function'==typeof WHITE_TrackIntLink)?WHITE_TrackIntLink(this):1;">
  var bResult = true;
  if (oElement)
  {
    if ('A' == oElement.nodeName)
    {
      if ( 'undefined' != typeof pageTracker
           && 'function' == typeof pageTracker._getLinkerUrl
           && oElement.href
           && null == oElement.href.match(/\b__utma/i) )
      {
        oElement.href = pageTracker._getLinkerUrl(oElement.href);
      }
    }
    else if ('FORM' == oElement.nodeName)
    {
      if ( pageTracker
           && 'function' == typeof pageTracker._linkByPost )
      {
        var oRedirField = WHITE_GetElementFlex('RedirBackUrl',oElement);
        if ( oRedirField
             && null == oRedirField.value.match(/\b__utma/i) )
        {
          oRedirField.value = pageTracker._getLinkerUrl(oRedirField.value);
        }
        pageTracker._linkByPost(oElement);
      }
    }
  }
  return bResult;
}

function WHITE_EventWindowClose(oEvent)
{
  if (parent && 'function' == typeof parent.SUNGLASS_CloseThisPopupWindow) // Sunglass window
  {
    parent.SUNGLASS_CloseThisPopupWindow();
  }
  else
  {
    if (1 >= history.length) // opened in new window/tab // FF=1, IE=0
    {
      window.close();
    }
    else // opened in same window in _top
    {
      history.back();
    }
  }
  return WHITE_CancelEvent(oEvent);
}

function WHITE_InitCloseLinks()
{
  var aApplyToElements = new Array('A','IMG');
  var aCloseButtons = WHITE_GetElementsByClass(document, 'closelink', aApplyToElements);
  for (var iElC=0;iElC<aCloseButtons.length;iElC++)
  {
    WHITE_AddEventToElement(aCloseButtons[iElC], 'click', WHITE_EventWindowClose);
  }
}

function WHITE_DebugLog(sMsg)
{
  // For FireFox: The 'console' tab in FireBug needs to be enabled. If it doen't log you need to restart FF.
  // For IE8:     Press F12
  //
  // Safe use of this function:
  //
  //    if ('function' == typeof WHITE_DebugLog) WHITE_DebugLog("Hello World.");
  //
  if (window.console && 'undefined' != typeof window.console.log)
  {
    window.console.log(sMsg);
  }
}

function WHITE_UrlGoSelectChangeEvent(oEvent)
{
  var oSelect = false;
  if ('object' == typeof this && this.type && 'select-one' == this.type)
  {
    oSelect = this;
  }
  if (oSelect)
  {
    if (oSelect.options[oSelect.selectedIndex] && oSelect.options[oSelect.selectedIndex].value)
    {
      document.location = oSelect.options[oSelect.selectedIndex].value;
    }
  }
  return WHITE_CancelEvent(oEvent);
}

function WHITE_UrlGoSelect_Initialize()
{
  WHITE_AddEventToClass(document,'UrlGoSelect','change',WHITE_UrlGoSelectChangeEvent,'select');
}

/* ADD TO YOUR main.js:

  if ( 'function' == typeof WHITE_AddBodyLoadFunction
       && 'function' == typeof WHITE_UrlGoSelect_Initialize )
  {
    WHITE_AddBodyLoadFunction(WHITE_UrlGoSelect_Initialize);
  }

*/

//##############################################################################
//# WHITEFORM FUNCTIONS
//##############################################################################

function WhiteForm_FieldFocusEvent(oEvent)
{
  WHITE_AddClassName(this,'focus');
  WHITE_RemoveClassName(this.id+'_help','hidden');
}

function WhiteForm_FieldUpdateEvent(oEvent)
{
  WhiteForm_FieldUpdate(this);
}

function WhiteForm_FieldUpdate(mElement)
{
  var oElement = WHITE_GetElementFlex(mElement);
  if (oElement)
  {
    var bFieldSet = WHITE_IsFormFieldSet(oElement);
    var sFieldPrefix = oElement.id;
    if (1 < sFieldPrefix.search('-')) // radio buttons have id="name-value"
    {
      sFieldPrefix = sFieldPrefix.substr(0,sFieldPrefix.search('-'));
    }
    var oErrorEl = WHITE_GetElementFlex(sFieldPrefix + '_error');
    var oHelpEl = WHITE_GetElementFlex(sFieldPrefix + '_help');
    var sErrorMsg = false;
    WHITE_RemoveClassName(oElement,'focus');
    WHITE_AddClassName(oHelpEl,'hidden');

    if (WHITE_HasClassName(oElement,'required')
         && !bFieldSet )                     // required and not set, show error
    {
      if ('function' == typeof WhiteForm_GetTextFieldRequired)
      {
        sErrorMsg = WhiteForm_GetTextFieldRequired(sFieldPrefix);
      }
      else
      {
        sErrorMsg = 'Required field.';
      }
    }
    if (!sErrorMsg && WHITE_HasClassName(oElement,'email'))
    {
      sFieldValue = WHITE_GetFormFieldValue(oElement);
      sFieldValue = WHITE_Trim(sFieldValue);
      var oEmailReg = new RegExp('^[^\\@]+\\@([a-zA-Z0-9\-]+\\.)+[a-zA-Z0-9]{2,6}$');
      if ('' != sFieldValue && !oEmailReg.test(sFieldValue))
      {
        if ('function' == typeof WhiteForm_GetTextFieldRequired)
        {
          sErrorMsg = WhiteForm_GetTextInvalidEmail(sFieldPrefix);
        }
        else
        {
          sErrorMsg = 'Invalid email address.';
        }
      }
    }

    if (sErrorMsg)
    {
      if (oErrorEl) // existing error element
      {
        WHITE_ReplaceElementContent(oErrorEl,sErrorMsg);
      }
      else
      {
        WHITE_InsertAfterElement(oElement,'<div class="fielderror" id="'+sFieldPrefix+'_error">'+sErrorMsg+'</div>');
      }
      WHITE_AddClassName(oElement,'error');
      WHITE_RemoveClassName(oErrorEl,'hidden');
      WHITE_RemoveClassName(oErrorEl,'hidden');
      WHITE_RemoveClassName(oElement,'good');
    }
    else // no error
    {
      if (bFieldSet)
      {
        WHITE_AddClassName(oElement,'good');
      }
      WHITE_RemoveClassName(oElement,'error');
      if (oErrorEl)
      {
        WHITE_AddClassName(oErrorEl,'hidden');
        WHITE_ReplaceElementContent(oErrorEl,'');
      }
    }
  }
}

function WhiteForm_AutoNext(mElement,mNextElement) {
  var oElement = WHITE_GetElementFlex(mElement);
  var oNextElement = WHITE_GetElementFlex(mNextElement);
  if ( oElement
       && oElement.type
       && 'text' == oElement.type
       && oElement.type
       && oElement.maxLength
       && oNextElement )
  {
    oElement['AutoNextNextElement'] = oNextElement;
    oNextElement['AutoNextBackElement'] = oElement;
    WHITE_AddEventToElement(oElement,'keyup',WhiteForm_AutoNextKeyUpEvent);
    WHITE_AddEventToElement(oElement,'keydown',WhiteForm_AutoNextKeyDownEvent);
    WHITE_AddEventToElement(oNextElement,'keyup',WhiteForm_AutoNextKeyUpEvent);
  }
}

function WhiteForm_AutoNextKeyDownEvent(oEvent) {
  var iKeyCode = WhiteForm_GetEventKeyCode(oEvent);
  // forward
  if ( iKeyCode
       && 48 <= iKeyCode
       && this.value
       && this.value.length
       && this.maxLength
       && this.value.length >= this.maxLength
       && this['AutoNextNextElement'] )
  {
    this['AutoNextNextElement'].focus();
  }
}

function WhiteForm_AutoNextKeyUpEvent(oEvent) {
  var iKeyCode = WhiteForm_GetEventKeyCode(oEvent);
  // forward
  if ( iKeyCode
       && (48 <= iKeyCode || 39 == iKeyCode)
       && this.value
       && this.value.length
       && this.maxLength
       && this.value.length >= this.maxLength
       && this['AutoNextNextElement'] )
  {
    this['AutoNextNextElement'].focus();
  }
  // back
  if ( iKeyCode
       && (8 == iKeyCode || 37 == iKeyCode)
       && 0 == WhiteForm_GetInputCursorPos(this)
       && this['AutoNextBackElement'] )
  {
    this['AutoNextBackElement'].focus();
    if ( this['AutoNextBackElement'].value
         && this['AutoNextBackElement'].value.length )
    {
      var iMovePos = this['AutoNextBackElement'].value.length;
      WhiteForm_MoveInputCursor(this['AutoNextBackElement'],iMovePos);
    }
  }
}

function WhiteForm_MoveInputCursor(mElement,iIndex)
{
  var oElement = WHITE_GetElementFlex(mElement);
  if (oElement)
  {
    if( oElement.setSelectionRange ) // FF
    {
        oElement.setSelectionRange(iIndex,iIndex);
    }
    else if( oElement.createTextRange ) // IE
    {
      var oRange = oElement.createTextRange();
      oRange.collapse(true);
      oRange.moveEnd('character',iIndex);
      oRange.moveStart('character',iIndex);
      oRange.select();
    }
  }
}

function WhiteForm_GetInputCursorPos(mElement)
{
  var oElement = WHITE_GetElementFlex(mElement);
	var iResult = false;
  if (oElement)
  {
    if (document.selection) // IE
    {
      oElement.focus();
      var oRange = document.selection.createRange ();
      oRange.moveStart ('character', -oElement.value.length);
      iResult = oRange.text.length;
    }
    else if (oElement.selectionStart || oElement.selectionStart == '0') // FF
    {
      iResult = oElement.selectionStart;
    }
  }
	return (iResult);
}

function WhiteForm_DebugMessage(sMsg)
{
  var oElement = WHITE_GetElementFlex('debug');
  if (oElement)
  {
    oElement.innerHTML += '<br />'+sMsg;
  }
  else
  {
    window.alert(sMsg);
  }
}

function WhiteForm_DisableFormEnter(mFormElement)
{
  var oFormElement = WHITE_GetElementFlex(mFormElement);
  var aElements = WHITE_GetElementsByTagName(oFormElement,'input');
  for (var iEl=0;iEl<aElements.length;iEl++)
  {
    var oElement = aElements[iEl];
    WHITE_AddEventToElement(oElement,'keydown',WhiteForm_EnterFilterInputKeyDownEvent);
  }
}

function WhiteForm_EnterFilterInputKeyDownEvent(oEvent) {
  var bResult = true;
  var iKeyCode = WhiteForm_GetEventKeyCode(oEvent);
  if ( 13 == iKeyCode )
  {
    if (window.event) // IE
    {
      if (oEvent.keyCode)
      {
        oEvent.keyCode = 9;
      }
    }
    else // FF: Ignore key
    {
      WHITE_CancelEvent(oEvent);
      bResult = false;
    }
  }
  return bResult;
}

function WhiteForm_GetEventKeyCode(oEvent) {
  var iResult = false;
  if ( 'object' == typeof oEvent)
  {
    if (oEvent.keyCode) // IE or modern FF
    {
      iResult = oEvent.keyCode;
    }
    else if (oEvent.which) // FF
    {
      iResult = oEvent.which;
    }
  }
  return iResult;
}

function WhiteForm_CancelEvent(oEvent) // backwards compatible
{
  return WHITE_CancelEvent(oEvent);
}

function WhiteForm_SetLabelAllClick(mWhiteForm)
{
  var oWhiteForm = WHITE_GetElementFlex(mWhiteForm);
  if (oWhiteForm)
  {
    var aLabels = WHITE_GetElementsByTagName(oWhiteForm,'label');
    for (var iLa=0;iLa<aLabels.length;iLa++)
    {
      var oLabelEl = aLabels[iLa];
      WHITE_ConnectClick(oLabelEl,oLabelEl);
    }
  }
}

function WhiteForm_InstallDynamics()
{
  var aWhiteForms = WHITE_GetElementsByClass(document, 'whiteform', 'form');
  var oWhiteFormById = WHITE_GetElementFlex('whiteform');
  if (oWhiteFormById)
  {
    aWhiteForms.push(oWhiteFormById);
  }
  for (var iWf=0;iWf<aWhiteForms.length;iWf++)
  {
    var oWhiteForm = aWhiteForms[iWf];
    WHITE_AddEventToClass(oWhiteForm, 'text',     'mousedown', WhiteForm_FieldFocusEvent,  'input'); // doing this beside of focus fixes problem with select box
    WHITE_AddEventToClass(oWhiteForm, 'text',     'focus',     WhiteForm_FieldFocusEvent,  'input');
    WHITE_AddEventToClass(oWhiteForm, 'text',     'blur',      WhiteForm_FieldUpdateEvent, 'input');
    WHITE_AddEventToClass(oWhiteForm, 'textarea', 'focus',     WhiteForm_FieldFocusEvent,  'textarea');
    WHITE_AddEventToClass(oWhiteForm, 'textarea', 'blur',      WhiteForm_FieldUpdateEvent, 'textarea');
    WHITE_AddEventToClass(oWhiteForm, 'radio',    'focus',     WhiteForm_FieldFocusEvent,  'input');
    WHITE_AddEventToClass(oWhiteForm, 'radio',    'blur',      WhiteForm_FieldUpdateEvent, 'input');
    WHITE_AddEventToClass(oWhiteForm, 'radio',    'click',     WhiteForm_FieldUpdateEvent, 'input');
    WHITE_AddEventToClass(document,   'foldhead', 'click',     WHITE_FoldHeadClickEvent,   'li');
    WhiteForm_SetLabelAllClick(oWhiteForm);
  }
}

//###
//### Add an other JS file to your HTML, and add this on the bottom:
//###
/*

if ('function' == typeof WHITE_AddBodyLoadFunction)
{
  if ('function' == typeof WhiteForm_InstallDynamics)
  {
    WHITE_AddBodyLoadFunction(WhiteForm_InstallDynamics);
  }
}
*/

//###### EXECUTE ON LOAD OF white.js

WHITE_BodyLoadFunctions_Install();
WHITE_WindowLoadFunctions_Install();
