// JAVASCRIPT LIBRARY

// constants
var XHTML_NS_URI = 'http://www.w3.org/1999/xhtml';

/*EventCache Version 1.0
Copyright 2005 Mark Wubben

Provides a way for automagically removing events from nodes and thus preventing memory leakage.
See <http://novemberborn.net/javascript/event-cache> for more information.

This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>
*/

/*Event Cache uses an anonymous function to create a hidden scope chain.
This is to prevent scoping issues. */
var EventCache = function(){
var listEvents = [];

return {
	listEvents : listEvents,

	add : function(node, sEventName, fHandler, bCapture){
	listEvents.push(arguments);
	},

	flush : function(){
	var i, item;
	for(i = listEvents.length - 1; i >= 0; i = i - 1){
		item = listEvents[i];
		
		if(item[0].removeEventListener){
		item[0].removeEventListener(item[1], item[2], item[3]);
		};
		
		/* From this point on we need the event names to be prefixed with 'on" */
		if(item[1].substring(0, 2) != "on"){
		item[1] = "on" + item[1];
		};
		
		if(item[0].detachEvent){
		item[0].detachEvent(item[1], item[2]);
		};
		
		item[0][item[1]] = null;
	};
	}
};
}();

// destroy events on unload to prevent memory leakage in IE-Win
addEventHandler(window, 'unload', EventCache.flush);

/**
 * Implements <code>getElementById<code> method for W3C DOM-incapable browsers.
 * For these browsers it returns always <code>null</code>. You do not have
 * to detect the <code>getElementById<code> elsewhere in a script anymore.
 * <p>
 * You should always check, if the returned value is not <code>null</code> to 
 * prevent script errors; <code>getElementById</code> returns null in
 * W3C DOM-capable browsers as well, if there is no match for the given id in
 * the document tree.
 * <p>
 * Usage:
 * <p>
 * <code>var elem = document.getElementById(id);<br>
 * if (elem) {<br>
 *     // process elem<br>
 * }</code>
 *
 * @author klaus.hartl (30.03.2005)
 */
if (!document.getElementById) {
    document.getElementById = function() {
        return null;
    };
}

/**
 * Implement <code>Array.push</code> for browsers which don't support it natively.
 *
 * @author klaus.hartl (30.03.2005)
 */
if (!Array.prototype.push) {
    Array.prototype.push = function() {
        for(var i = 0; i < arguments.length; i++) {
            this[this.length] = arguments[i];
        }
        return this.length;
    }
}

/**
 * Binds an event handler function to a given node, so that the function executes
 * when an event of the particular, given type arrives at the node either as event
 * target or during event propagation. Existing events, either defined as a tag
 * attribute or binded dynamically, are not affected.
 * <p>
 * Note: If this has to work in IE/Mac with existing events as tag attributes
 * the call to bind a new event has to follow the target node in the source 
 * code.
 *
 * @param target           the node to which the event will be binded
 * @param eventType        a string of one event type (without the "on" prefix)
 *                         known to the browser's object model
 * @param listenerFunction a reference to the function to execute, when the node
 *                         hears the event type
 * @param useCapture       a Boolean value. If <code>true</code>, the node listens
 *                         for the event type only while the event propagates
 *                         toward the target node. If <code>false</code>, the 
 *                         node listens only when the event bubbles outward from
 *                         the event target. The typical setting of this parameter
 *                         is <code>false</code> and if omitted, it falls back to 
 *                         that value.
 * @author                 klaus.hartl (24.03.2005)
 */
function addEventHandler(target, eventType, listenerFunction, useCapture) {
    var result;
    if (target.addEventListener) {
        // W3C DOM approach
        useCapture = (typeof useCapture == 'boolean') ? useCapture : false;
        target.addEventListener(eventType, listenerFunction, useCapture);
        result = true;
    } else if (target.attachEvent) {
        // IE/Win DOM approach
        var r = target.attachEvent('on' + eventType, listenerFunction);
        result = r;
    } else {
        // fallback approach (IE/Mac and anything else that gets this far)
        var onEv = 'on' + eventType;
    // if there's an existing event handler function
        if(typeof target[onEv] == 'function') {
            // store it
            var existing = target[onEv];
            // attach new onload handler
            target[onEv] = function() {
                // call existing function
                existing();
                // call given function
                listenerFunction();
            };
        } else {
            target[onEv] = listenerFunction;
        }
        return true; // do not use EventCash
    }
    EventCache.add(target, eventType, listenerFunction, useCapture);
    return result;
}

/**
 *
 */
function toggleValue(evt, defaultValue) {
    evt = (evt) ? evt : ((event) ? event : null);
    if (evt) {
        var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
        if (elem) {
            if (elem.value == defaultValue) {
                elem.value = '';
            } else if (elem.value == '') {
                elem.value = defaultValue;
            }
        }
    }
}
/**
 *
 */
function attachToField(id) {
  var searchInputEl = document.getElementById(id);
  if (searchInputEl) {
    // searchInputEl.setAttribute('autocomplete', 'off'); // prevents exception occuring with mozilla's autocomplete feature
    // this exception though does not break/impact the script but maybe we want to avoid an error at the console...
    var s = searchInputEl.value;
    var listener = function(evt) {
        toggleValue(evt, s);
    }
    addEventHandler(searchInputEl, 'focus', listener);
    addEventHandler(searchInputEl, 'blur', listener);
  }
  return searchInputEl
}