//#############################################################################
//
// A JavaScript library for runtime browser manipulation
//
// ©2007 Peter A. Kemmer
//
// Library assumptions:
//
// - 'Smart' intervals and timeouts can be replaced or cancelled based on
//   function name, by setting a new timer using the same functions or by
//   using the same functions with a time of 0 milliseconds, respectively
//
//#############################################################################

//-----------------------------------------------------------------------------
// Verify Dependencies
//-----------------------------------------------------------------------------

/*
if (!isDefined(REQUIRED_LIBRARY_LOADED)) {
    alert("Error: The library Required.js needs to be loaded before This.js");
}
*/

//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------

var RUNTIME_LIBRARY_LOADED = true;

//#############################################################################
// 'Smart' Intervals & Timeouts
//#############################################################################

// Variables ------------------------------------------------------------------

var gIntervals = new Array();
var gTimeouts = new Array();

// Functions ------------------------------------------------------------------

/**
 * setSmartInterval
 *
 * Create an interval that will be automatically tracked and removed
 * if the same function is added at an interval of 0 milliseconds!!!
 *
 * @param callback - The callback
 * @param milliseconds - The number milliseconds to wait before repeating
 */
function setSmartInterval(callback, milliseconds) {
    var id;

    id = callback + "";
    id = id.substr(0, id.indexOf("("));

    if (milliseconds == 0) {
        if (isDefined(gIntervals[id])) {
            clearInterval(gIntervals[id]);

            delete gIntervals[id];
        }
    } else {
        gIntervals[id] = setInterval(callback, milliseconds);
    }
}

/**
 * setSmartTimeout
 *
 * Create a timeout that will be automatically tracked and removed
 * if the same function is added at a timeout of 0 milliseconds!!!
 *
 * @param callback - The callback
 * @param milliseconds - The number milliseconds to wait before calling
 */
function setSmartTimeout(callback, milliseconds) {
    var id;

    id = callback + "";
    id = id.substr(0, id.indexOf("("));

    if (isDefined(gTimeouts[id])) {
        clearTimeeout(gTimeouts[id]);

        delete gTimeouts[id];
    }

    if (milliseconds != 0) {
        gTimeouts[id] = setTimeout(callback, milliseconds);
    }
}

//#############################################################################
// General Utilities
//#############################################################################

/**
 * getElement
 *
 * Convert element ids into elements, and let elements pass through,
 * which somewhat simplifies the way a function can locate elements!
 *
 * @param elementOrId - An element or the id of an element we want to find
 */
function getElement(elementOrId) {
    return typeof elementOrId == "object" ? elementOrId : document.getElementById(elementOrId);
}

//#############################################################################
// Style Manipulation Utilities
//#############################################################################

/**
 * setAlpha
 *
 * A shortcut to set the alpha styles of a document element by object or id
 *
 * ELEMENTS MUST HAVE LAYOUT FOR TRANSPARENCY TO WORK IN IE
 * HEIGHT AND WIDTH ARE GOOD ATTRIBUTES TO FORCE TO LAYOUT!
 *
 * @param element - An element or the id of an element we want to modify
 * @param alpha - An alpha value from 0.0 to 1.0, transparent to opaque
 */
function setAlpha(element, alpha) {
    element = getElement(element);

    // Set the opacity fields used with different browsers!

    if (element) {
        element.style["filter"] = "alpha(opacity=".append(alpha * 100, ")");
        element.style["opacity"] = alpha;
        element.style["-moz-opacity"] = alpha;
        element.style["-khtml-opacity"] = alpha;
    }
}

