var tools = {};

/**
 * Sets the x and y units on an asset object according
 * to it's definition in the WebStory.
 * @param obj The JavaScript object asset.
 * @param asset The XML Element with the asset's information.
 */
tools.applyAssetUnits = function (obj, asset) {

    var x, y;

    x = asset.getAttribute('x') || "";
    y = asset.getAttribute('y') || "";
    obj.xUnit = x.replace(/^.*(px|%)$/, '$1');
    obj.xUnit = obj.xUnit || 'px';
    obj.yUnit = y.replace(/^.*(px|%)$/, '$1');
    obj.yUnit = obj.yUnit || 'px';

    if (obj.xUnit !== "px" && obj.xUnit !== "%") {
        obj.xUnit = "px";
    }

    if (obj.yUnit !== "px" && obj.yUnit !== "%") {
        obj.yUnit = "px";
    }
};

/**
 * Removes a DOM Event from a DOM Element.
 */
tools.removeEventListener = function (elem, type, listener) {

    if (typeof elem === "undefined" || elem === null) {
        return;
    }

    elem.removeEventListener(type, listener, false);
};

/**
 * Function that replaces the names of variables in a string
 * with their respective values.
 * 
 * @param text [string] The text that contains variables.
 * @param interpreter [WSE.Interpreter] The interpreter instance.
 * @return [string] The text with the inserted variable values.
 */
tools.replaceVariables = function (text, interpreter) {

    var f1, f2;

    if (text === null) {
        return text;
    }

    if (typeof text !== "string") {
        interpreter.bus.trigger("wse.interpreter.error", {
            message: "Argument supplied to the replaceVariables function must be a string."
        });
        text = "";
    }

    f1 = function () {

        var name = arguments[1];

        if (interpreter.globalVars.has(name)) {
            return "" + interpreter.globalVars.get(name);
        }

        return "";
    };

    f2 = function () {

        var name = arguments[1];

        if (name in interpreter.runVars) {
            return "" + interpreter.runVars[name];
        }

        return "";
    };

    // insert values of global variables ($$var):
    text = text.replace(/\{\$\$([a-zA-Z0-9_]+)\}/g, f1);

    // insert values of local variables ($var):
    text = text.replace(/\{\$([a-zA-Z0-9_]+)\}/g, f2);

    return text;
};

tools.getSerializedNodes = function (element) {

    var ser = new XMLSerializer(), nodes = element.childNodes, i, len;        
    var text = '';

    for (i = 0, len = nodes.length; i < len; i += 1) {
        text += ser.serializeToString(nodes[i]);
    }

    return text;
};

tools.getParsedAttribute = function (element, attributeName, interpreter, defaultValue) {

    var value;

    if (arguments.length < 3) {
        defaultValue = "";
    }

    value = element.getAttribute(attributeName) || ("" + defaultValue);

    return tools.replaceVariables(value, interpreter);
};

/**
 * Replaces { and } to < and > for making it HTML.
 * Optionally replaces newlines with <break> elements.
 * 
 * @param text [string] The text to convert to HTML.
 * @param nltobr [bool] Should newlines be converted to breaks? Default: false.
 */
tools.textToHtml = function (text, nltobr) {

    nltobr = nltobr || false;

    if (!(String.prototype.trim)) {
        text = text.replace(/^\n/, "");
        text = text.replace(/\n$/, "");
    }
    else {
        text = text.trim();
    }

    text = nltobr === true ? text.replace(/\n/g, "<br />") : text;
    text = text.replace(/\{/g, "<");
    text = text.replace(/\}/g, ">");

    return text;
};

/**
 * Generates a unique ID. Used by assets to identify their own stuff
 * in savegames and the DOM of the stage.
 * 
 * @return [number] The unique ID.
 */
tools.getUniqueId = (function () {

    var uniqueIdCount = 0;

    return function () {
        uniqueIdCount += 1;
        return uniqueIdCount;
    };
}());

/**
 * Converts the first character in a string to upper case.
 * 
 * @param input [string] The string to transform.
 * @return [string] The transformed string.
 */
tools.firstLetterUppercase = function (input) {

    if (input.length < 1) {
        return "";
    }

    return "" + input.charAt(0).toUpperCase() + input.replace(/^.{1}/, "");
};

tools.mixin = function (source, target) {

    var key;

    for (key in source) {

        if (source.hasOwnProperty(key)) {
            target[key] = source[key];
        }
    }
};

tools.extractUnit = function (numberString) {
    return typeof numberString !== "string" ? "" : numberString.replace(/^(-){0,1}[0-9]*/, "");
};

tools.calculateValueWithAnchor = function (oldValue, anchor, maxValue) {

    var value = 0, anchorUnit = "px";

    if (!anchor) {
        return oldValue;
    }

    anchorUnit = tools.extractUnit(anchor);
    anchor = parseInt(anchor, 10);

    if (anchorUnit === "%") {
        value = oldValue - ((maxValue / 100) * anchor);
    }
    else {
        value = oldValue - anchor;
    }

    return value;
};

tools.getWindowDimensions = function () {

    var e = window,
        a = 'inner';

    if (!('innerWidth' in e)) {
        a = 'client';
        e = document.documentElement || document.body;
    }

    return {
        width: e[a + 'Width'],
        height: e[a + 'Height']
    };
};

tools.fitToWindow = function (el, w, h) {

    var dim, ratio, sw, sh, ratioW, ratioH;

    dim = tools.getWindowDimensions();

    sw = dim.width; // - (dim.width * 0.01);
    sh = dim.height; // - (dim.height * 0.01);

    ratioW = sw / w;
    ratioH = sh / h;

    ratio = ratioW > ratioH ? ratioH : ratioW;

    //ratio = parseInt(ratio * 100) / 100;

    el.setAttribute('style',
    el.getAttribute('style') + ' -moz-transform: scale(' + ratio + ',' + ratio +
        ') rotate(0.01deg);' + ' -ms-transform: scale(' + ratio + ',' + ratio +
        ');' + ' -o-transform: scale(' + ratio + ',' + ratio +
        ');' + ' -webkit-transform: scale(' + ratio + ',' + ratio + ');' +
        ' transform: scale(' + ratio + ',' + ratio + ');');
};

tools.log = function (bus, message) {
    tools.trigger(bus, "wse.interpreter.message", message);
};

tools.warn = function (bus, message, element) {
    tools.trigger(bus, "wse.interpreter.warning", message, element);
};

tools.logError = function (bus, message, element) {
    tools.trigger(bus, "wse.interpreter.error", message, element);
};

tools.trigger = function (bus, channel, message, element) {
    bus.trigger(channel, {
        element: element || null,
        message: message
    });
};

[function] truthy

A function that checks whether an attribute value is considered truthy by the engine. Truthy values are true and yes.

truthy :: any -> boolean
tools.truthy = function (value) {
    return ["true", "yes"].indexOf(value) >= 0;
};

module.exports = tools;

Documents

docs/reference/elements/nametemplate.md
docs/reference/elements/stop.md
docs/development.md
docs/documentation.md
docs/downloads.md
docs/examples.md
docs/games.md
docs/index.md
docs/reference/elements/alert.md
docs/reference/elements/animation.md
docs/reference/elements/assets.md
docs/reference/elements/audio.md
docs/reference/elements/background.md
docs/reference/elements/break.md
docs/reference/elements/character.md
docs/reference/elements/choice.md
docs/reference/elements/clear.md
docs/reference/elements/composite.md
docs/reference/elements/conditionals.md
docs/reference/elements/confirm.md
docs/reference/elements/curtain.md
docs/reference/elements/displayname.md
docs/reference/elements/do.md
docs/reference/elements/easing_attribute.md
docs/reference/elements/else.md
docs/reference/elements/flash.md
docs/reference/elements/flicker.md
docs/reference/elements/fn.md
docs/reference/elements/global.md
docs/reference/elements/globalize.md
docs/reference/elements/goto.md
docs/reference/elements/group.md
docs/reference/elements/hide.md
docs/reference/elements/image.md
docs/reference/elements/imagepack.md
docs/reference/elements/line.md
docs/reference/elements/localize.md
docs/reference/elements/move.md
docs/community.md
docs/reference/elements/option.md
docs/reference/elements/pause.md
docs/reference/elements/play.md
docs/reference/elements/prompt.md
docs/reference/elements/restart.md
docs/reference/elements/scene.md
docs/reference/elements/scenes.md
docs/reference/elements/set.md
docs/reference/elements/set_vars.md
docs/reference/elements/settings.md
docs/reference/elements/shake.md
docs/reference/elements/show.md
docs/reference/elements/source.md
docs/reference/elements/stage.md
docs/reference/elements/start.md
docs/beginners-guide.md
docs/reference/elements/sub.md
docs/reference/elements/tag.md
docs/reference/elements/textbox.md
docs/reference/elements/track.md
docs/reference/elements/transform.md
docs/reference/elements/trigger.md
docs/reference/elements/trigger_command.md
docs/reference/elements/triggers.md
docs/reference/elements/var.md
docs/reference/elements/wait.md
docs/reference/elements/when.md
docs/reference/elements/while.md
docs/reference/elements/with.md
docs/reference/elements/ws.md
docs/reference/elements.md
docs/reference/language.md
docs/reference/structure.md
docs/reference/syntax.md
docs/web-servers.md
libs/MO5/README.md
libs/MO5/libs/using.js/README.md
libs/MO5/js/EventBus.js
libs/MO5/js/Animation.js
libs/MO5/js/CoreObject.js
libs/MO5/js/Exception.js
libs/MO5/js/List.js
libs/MO5/js/MO5.js
libs/MO5/js/Map.js
libs/MO5/js/Point.js
libs/MO5/js/Promise.js
libs/MO5/js/Queue.js
libs/MO5/js/Result.js
libs/MO5/js/Set.js
libs/MO5/js/Size.js
libs/MO5/js/Timer.js
libs/MO5/js/TimerWatcher.js
libs/MO5/js/ajax.js
libs/MO5/js/assert.js
libs/MO5/js/dom.Element.js
libs/MO5/js/dom.effects.typewriter.js
libs/MO5/js/dom.escape.js
libs/MO5/js/easing.js
libs/MO5/js/fail.js
libs/MO5/js/globals.document.js
libs/MO5/js/globals.window.js
libs/MO5/js/range.js
libs/MO5/js/tools.js
libs/MO5/js/transform.js
libs/MO5/js/types.js
libs/MO5/libs/using.js/tests/index.js
libs/MO5/libs/using.js/tests/module1.js
libs/MO5/libs/using.js/tests/module2.js
libs/MO5/libs/using.js/tests/module3.js
libs/MO5/libs/using.js/using.js
libs/MO5/tests/node/EventBus.test.js
libs/MO5/tests/node/Set.test.js
src/savegames.js
src/tools/reveal.js
src/tools/ui.js
src/loader.js
src/tools/tools.js
src/tools/compile.js
src/functions.js
src/DisplayObject.js
src/Game.js
src/Interpreter.js
src/Keys.js
src/LoadingScreen.js
src/Trigger.js
src/assets/Audio.js
src/assets/Background.js
src/assets/Character.js
src/assets/Composite.js
src/assets/Curtain.js
src/assets/Imagepack.js
src/assets/Textbox.js
src/assets.js
src/bus.js
src/commands/alert.js
src/commands/break.js
src/commands/choice.js
src/commands/confirm.js
src/commands/do.js
src/commands/fn.js
src/commands/global.js
src/commands/globalize.js
src/commands/goto.js
src/commands/line.js
src/commands/localize.js
src/commands/prompt.js
src/commands/restart.js
src/commands/set_vars.js
src/commands/sub.js
src/commands/trigger.js
src/commands/var.js
src/commands/wait.js
src/commands/while.js
src/commands/with.js
src/commands.js
src/dataSources/LocalStorage.js
src/dataSources.js
src/engine.js
src/extensions/button.js
src/extensions/colored-rectangle.js
src/extensions/get-backtrace.js
src/extensions/hello.js
src/extensions/side-images.js
CHANGELOG.md
LICENSE.md
README.md
build.js
index.js
index.md
package.js