/**
 * @fileoverview Functions for handling elements in the DOM tree
 * 
 * @package     util
 * @author      Marc-Oliver Stühmer
 * @version     1.0.20080103
 */
 
/**
 * Remove the element with the given ID from the DOM document
 * 
 * @param   {String} id                 The ID of the element to remove
 */
function removeElementById(id)
{
    var element = document.getElementById(id);
    if (element && element.parentNode) {
        element.parentNode.removeChild(element);
    }
}

/**
 * Remove all child nodes of the given element from the DOM tree
 *
 * @param   {Node} element              The element to remove the child nodes of
 */
function removeChildNodes(element)
{
    while (element.hasChildNodes()) {
        element.removeChild(element.firstChild);
    }
}

/**
 * Return a list of elements which have the given CSS class
 * 
 * @param   {String} classname          The classname of the elements to get
 * @param   {Node} element              The DOM node to search in
 * @return  {Array}                     All elements with the given CSS class
 */
function getElementsByClassName(classname, element)
{
    var array = new Array();
    var elements = element.getElementsByTagName('*');
    
    for (var i = 0; i < elements.length; i++) {
        var classes = elements[i].className.split(' ');
        for (var j = 0; j < classes.length; j++) {
            if (classes[j] == classname) {
                array.push(elements[i]);
            }
        }
    }
    return array;    
}

/**
 * Add the given class name to the element's className property
 * 
 * @param   {Node} element              The element to add the class name to
 * @param   {String} classname          The class name to add
 */
function addClassName(element, classname)
{
    if (element.className == null) {
        element.className = '';
    }
    element.className += ' ' + classname;
}

/**
 * Remove the given class name from the element's className property
 * 
 * @param   {Node} element              The element to remove the class name from
 * @param   {String} classname          The class name to remove
 */
function removeClassName(element, classname)
{
    if (element.className == null) {   
        return;
    }

    var new_classes = new Array();
    var cur_classes = element.className.split(' ');
    for (var i = 0; i < cur_classes.length; i++) {
        if (cur_classes[i] != classname) {
            new_classes.push(cur_classes[i]);
        }
    }
    element.className = new_classes.join(' ');  
}

/**
 * Determine whether the element has got the given class name
 *
 * @param   {Node} element              The element to check
 * @param   {String} classname          The wanted class name
 * @return  {Boolean}                   Does the element have the class name?
 */
function hasClassName(element, classname)
{
    if (element.className == null) {
        return false;
    }
    
    var classes = element.className.split(' ');
    for (var i = 0; i < classes.length; i++) {
        if (classes[i] == classname) {
            return true;
        }
    }
    return false;
}

/**
 * Add an event handler to an element's event
 *
 * @param   {Node} element              The element to add the event handler to
 * @param   {String} type               The type of the event (without 'on')
 * @param   {Function} handler          The event handler function to add
 */
function addEventHandler(element, type, handler)
{
    if (element.addEventListener) {
        element.addEventListener(type, handler, false);   // DOM version
    } else if (element.attachEvent) {
        element.attachEvent('on' + type, handler);   // IE version
    }
}

/**
 * Remove an event handler from an element's event
 * 
 * @param   {Node} element              The element to remove the event handler from
 * @param   {String} type               The type of the event (without 'on')
 * @param   {Function} handler          The event handler function to remove
 */     
function removeEventHandler(element, type, handler)
{
    if (element.removeEventListener) {
        element.removeEventListener(type, handler, false);   // DOM version
    } else if (element.detachEvent) {
        element.detachEvent('on' + type, handler);   // IE version
    }
}

/**
 * Determine the target element of an event
 *
 * @param   {Event} ev                  The calling event
 * @return  {Node}                      The target element
 */
function getTargetElement(ev)
{
    // IE hack
    var evnt = ev ? ev : window.event;

    // DOM version
    var target = evnt.currentTarget;

    // IE version
    if (!target) {
        target = evnt.srcElement;
    }

    return target;
}

/**
 * Determine the pressed key of a key press/down/up event
 *
 * @param   {KeyboardEvent} ev          The calling event
 * @return  {Number}                    The key code of the pressed key
 */
function getPressedKey(ev)
{
    // IE hack
    var evnt = ev ? ev : window.event;

    // DOM version
    var key = evnt.which;

    // IE version
    if (!key) {
        key = evnt.keyCode;
    }

    return key;
}
