/**
 * Contains common functions for use on front-end
 * @version $Revision: 1.10.4.3 $
 */

/**
 * arrays for use later on
 */
var preloadimages = new Array();
var events = new Array();


/* ----------------
 * COMMON FUNCTIONS
 * ---------------- */

function is_array(array)
{
    return (array instanceof Array);
}

function in_array(needle, haystack)
{
    if ((needle != '') && (haystack.length > 0)) {
        for (var i = 0; i < haystack.length; i++) {
            if (haystack[i] == needle) return true;
        }
    }
    return false;
}


/* ----------------
 * MISCELLANEOUS FUNCTIONS
 * ---------------- */

/**
 * Enable scrolling for overflow:auto elements in Mozilla
 */
function scrollMe(e)
{
    var scrollTop = e.currentTarget.scrollTop + (e.detail * 12);
    e.currentTarget.scrollTop = scrollTop < 0 ? 0 : scrollTop;
    e.preventDefault();
}

function scroll(e)
{
    if (document.body.addEventListener) {
        try {
            document.getElementById(e).addEventListener('DOMMouseScroll', scrollMe, false);
        } catch (ex) {
        }
    }
}

/**
 * Adds image to preload stack
 * The stack is processed in preloadImages()
 * @param string src The image src
 * @return void
 */
function preparePreloadImage(src)
{
    for (i in window.preloadimages) if (window.preloadimages[i] == src) return;
    window.preloadimages.push(src);
}

/**
 * Preloads images set in window.preloadimages
 * @return void
 */
function preloadImages()
{
    if (preloadimages.length > 0) {
        for (var i = 0; i < preloadimages.length; i++) {
            preloadImg(preloadimages[i]);
        }
    }
}

/**
 * Adds image (invisible) to body so that it will be preloaded
 * @return void
 */
function preloadImg(src)
{
    var img = document.createElement('img');
    img.setAttribute('src', src);
    img.setAttribute('width', 0);
    img.setAttribute('height', 0);
    img.style.display = 'none';

    document.getElementsByTagName('body').item(0).appendChild(img);
}

/**
 * Prints current screen
 */
function printScreen(e)
{
    cancelEvent(e);
    window.print();
}

/**
 * Navigates browser window back 1 page in history
 */
function goBack(e)
{
    cancelEvent(e);
    history.back();
}

/**
 * Opens a new popup window
 */
function popup(what, w, h, location, menubar, toolbar, status)
{
    var width    = w ? w : screen.width * 0.8;
    var height   = h ? h : screen.height * 0.8;
    var features = 'width=' + width + ',height=' + height + ',location=' + location + ',menubar=' + menubar + ',toolbar=' + toolbar + ',status=' + status;

    var win      = window.open(what.getAttribute('href'), win, features);
    win.focus();

    return win;
}

/**
 * Redirects browser to event target's value (target should be input box)
 */
function redirect(e)
{
    var target = getTarget(e);
    var node = document.getElementById(target.redir_id);

    cancelEvent(e);

    if (node.value != '') {
        window.location.href = node.value + ( (node.value.indexOf('?') > 0) ? '&redir=1' : '?redir=1');
    }
    return false;
}

/**
 * Returns random element from array using weight factors as values
 * @param Array factors The array holding the factors (integers)
 * @return mixed The 'lucky' key
 */
function arrayFactorRand(factors)
{
    var factorTotals = 0;
    var factorEnds = new Array();
    var luckyKey = false;

    for (i in factors) {
        factorTotals += factors[i];
        factorEnds[i] = factorTotals;
    }

    var luckyNumber = Math.random() * factorTotals;

    for (i in factors) {
        if (factorEnds[i] > luckyNumber) {
            luckyKey = i;
            break;
        }
    }

    return luckyKey;
}


/* ----------------
 * EVENT FUNCTIONS
 * ---------------- */

/**
 * Parses anchors and span tags in page.
 * Applies event handlers to nodes with attributes for 'back', 'external' or 'print' links
 */
function eventLinks()
{
    if (!document.getElementsByTagName) return;

    var anchor, span, regexp, rel, className;
    var anchors = document.getElementsByTagName('a');
    var spans = document.getElementsByTagName('span');
    var onclick = 'popup(this); return false;';

    for (var i = 0; i < anchors.length; i++) {
        anchor = anchors[i];
        rel = anchor.getAttribute('rel');

        if (rel != '') {
            regexp = new RegExp('\\bexternal\\b', 'i');
            if (regexp.test(rel)) {
                anchor.setAttribute('target', '_blank');
                var img = document.createElement('img');
                img.setAttribute('width', 16);
                img.setAttribute('height', 16);
                img.setAttribute('src', '/images/i_exlink.gif');
//                anchor.appendChild(img);
            }

            regexp = new RegExp('\\bback\\b', 'i');
            if (regexp.test(rel)) {
                applyEvent(anchor, 'click', goBack);
            }
        }
    }

    for (var i = 0; i < spans.length; i++) {
        span = spans.item(i);
        className = span.getAttribute('class');

        if (className != '') {
            regexp = new RegExp('\\bprint\\b', 'i');
            if (regexp.test(className)) {
                var txtnode = document.createTextNode(span.getAttribute('title'));
                span.appendChild(txtnode);
                applyEvent(span, 'click', printScreen);
                span.style.display = 'block';
            }
        }
    }
}

/**
 * Adds event to stack
 * The stack will be processed in .onload()
 * @param string id The element id
 * @param string eventname The name of the event
 * @param string callback Function to callback to
 * @param array properties Array containing properties to apply to element
 * @return void
 */
function prepareEvent(id, eventname, callback, properties)
{
    var property;
    var event = new Object();
    event.id = id;
    event.eventname = eventname;
    event.callback = callback;
    event.properties = new Array();

    if (properties instanceof Array) {
        for (var i = 0; i < properties.length; i++) {
            event.properties.push(properties[i]);
        }
    }
    window.events.push(event);
}

/**
 * Process events
 * This is done in body.onload()
 * @return void
 */
function applyEvents()
{
    var event;
    for (var i = 0; i < window.events.length; i++) {
        event = window.events[i];
        applyEvent(document.getElementById(event.id), event.eventname, event.callback, event.properties);
    }
}

/**
 * Attaches event to element, with given callback function and properties
 * @param DOMNode node The node to attach the event to
 * @param string event The event name
 * @param string callback The function to callback to
 * @param array properties The properties to be assigned to the node
 */
function applyEvent(node, event, callback, properties)
{
    if (node instanceof Object) {
        if (properties) {
            for (var i = 0; i < properties.length; i++) {
                for (var a in properties[i]) {
                    node[a] = properties[i][a];
                }
            }
        }

        if (node.addEventListener) {
            node.addEventListener(event, callback, false);
        } else if (node.attachEvent) {
            node.attachEvent('on'+event, callback);
        }
    }
}

/**
 * Add onload() event to the stack
 * @param callback func The callback (function name or inline function) to add
 * @return void
 * @author Simon Willison
 * @see http://simon.incutio.com/archive/2004/05/26/addLoadEvent
 */
function addLoadEvent(func)
{
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = func;
    } else {
        window.onload = function() {
            if (oldonload) {
              oldonload();
            }
            func();
        }
    }
}

/**
 * Returns event target.
 */
function getTarget(e)
{
    return e.target || e.scrElement;
}

function cancelEvent(e)
{
    if (e.cancelable) e.preventDefault();
}

/**
 * Apply 'onload' events
 */
addLoadEvent(applyEvents);
addLoadEvent(eventLinks);
addLoadEvent(preloadImages);
