﻿if (typeof NURUN === "undefined" || !NURUN) {
    /**
    * @namespace
    */
    NURUN = {};
}

/**
 * Report on the version of the NURUN object
 */
NURUN.version = "0.3";


/**
 * Report on the build of the NURUN object
 */
NURUN.build = "0";

/**
 * Creates a namespace (nested objects) based on a string. The namespace's
 * root level must be in uppercase, otherwise it is assumed that one was
 * not passed and the default NURUN namespace will be used.
 *
 * @param    {String} ns  Dot notation string representing the namespace 
 *                        to be created.
 * @return                Returns true if successful, false if it fails
 * @type      {Boolean}
 */
NURUN.namespace = function (ns) {
    if (typeof ns !== "string") {
        return false;
    }
    
    // Split namespace string into an array
    var levels = ns.split(".");
    
    // Initialize vars
    var progress;
    
    // A root node was not passed, use NURUN as default root node
    if (levels[0] !== levels[0].toUpperCase()) {
        progress = NURUN;
    } else {
        // Create root var if it doesn't already exist
        var root = levels[0];
        if (typeof window[root] === "undefined" || !window[root]) {
            window[root] = {};
        }
        
        // Assign root node to var named "progress" for future iteration
        progress = window[root];
        
        // Truncate levels array so as to remove root node
        levels = levels.slice(1, levels.length);
    };
    
    // Iterate over levels and create objects where necessary
    for (var i = 0; levels[i]; i += 1) {
        if (typeof progress[levels[i]] === "undefined") {
            progress[levels[i]] = {};
        }
        progress = progress[levels[i]];
    }
    return true;
};

NURUN.addObjects = function () {
    var total = {};
    for (var i = 0; arguments[i]; i += 1) {
        if (YAHOO.lang.isObject(arguments[i])) {
            var obj = arguments[i];
            for (var key in obj) {
                if (obj.hasOwnProperty(key)) {
                    total[key] = obj[key];
                }
            }
        }
    }
    return total;
};
    
/**
 * Reports on the type of object NURUN is
 * @ignore
 */
NURUN.toString = function () {
    return "NURUN Global Object";
};


/**
* Define the NURUN.lang namespace
*/
NURUN.namespace("NURUN.lang");
/** 
* @namespace
*/
NURUN.lang = NURUN.lang


/**
* Convert special caracters from a string to HTML  (&,<, >, ")
* @param {String} str String to convert into HTML 
* @return Returns a converted string
* @type {String}
*/
NURUN.lang.convertTextToHTMLText = function(str){
    str = str.replace(new RegExp('<','g'),'&lt;');
    str = str.replace(new RegExp('>','g'),'&gt;');
    str = str.replace(new RegExp('\"','g'),'&quot;');
    str = str.replace(new RegExp("&",'g'),'&amp;');

    return str;
}

// Register module with YUI (for use with YUI Loader)
if (typeof YAHOO !== "undefined" && YAHOO.register) {
    YAHOO.register("NURUN", NURUN, {version: NURUN.version, build: NURUN.build}); 
}

NURUN.namespace("util");

NURUN.util.Param = function (params) {
    /*
     * Data format:
        {
            key: {
                value: mixed,
                persist: bool
            }
        }
     */
    var data = {};
    
    /**
     * Adds a parameter to the param manager.
     */
    this.addParam = function (key, value) {
        if (YAHOO.lang.isString(key)) {
            if (!data[key]) {
                data[key] = {};
            }
            if (YAHOO.lang.isObject(value) && !YAHOO.lang.isFunction(value)) {
                data[key].value = value.value;
                data[key].persist = value.persist;
            } else {
                data[key].value = value;
                data[key].persist = true; // persist value by default
            }
            return true;
        } else {
            return false; // fail silently
        }
    };

    /**
     * Adds a set of parameters to the param manager.
     */
    this.addParams = function (data) {
        if (YAHOO.lang.isObject(data)) {
            for (var key in data) {
                if (data.hasOwnProperty(key)) {
                    this.addParam(key, data[key]);
                }
            }
        } else {
            return false; // fail silently
        }
        
        return true;
        
    };

    /**
     * Adds parameters from a querystring
     */
    this.addParamsFromQuerystring = function (qs) {
        // Make sure the value was not previously escaped as a stand-alone value in another querystring
        qs = unescape(qs);
        
        // Remove preceding question mark character
        qs = qs.replace(/^\?/, "");
        
        // Split name/value pairs
        var arr = qs.split("&");
        
        // Iterate over pairs and store params
        for (var i = 0; arr[i]; i += 1) {
            var keyValue = arr[i].split("=");
            this.addParam(keyValue[0], keyValue[1]);
        }
    };

    /**
     * Returns the value of a parameter based on its key.
     */
    this.getParam = function (key) {
        if (data[key]) {
            return data[key].value;
        } else {
            return false // fail silently
        }
    };

    /**
     * Returns an object containing the stored parameter data as key/value pairs.
     */
    this.getParams = function () {
        var params = {};
        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                params[key] = data[key].value;
            }
        }
        return params;
    };

    /**
     * Purges a param from the param manager.
     */
    this.purgeParam = function (key) {
        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                if (data[key]) {
                    delete data[key];
                    return true;
                } else {
                    return false;
                }
            }
        }
    };

    /**
     * Purges all params from the param manager.
     */
    this.purgeParams = function () {
        data = {};
        return true;
    };

    /**
     * Goes through data and deletes all params that aren't set to persist.
     */
    this.purgeNonPersistent = function () {
        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                if (data[key].persist === false) {
                    delete data[key];
                }
            }
        }
    };

    /**
     * Builds a querystring out of the stored parameter data.
     */
    this.toQuerystring = function () {
        var qs = "";
        var delim = "?";
        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                qs += delim + key + "=" + data[key].value.toString();
                delim = "&";
            }
        }
        return qs;
    };
    
    /**
     * Helper method that takes a URL, creates a querystring with the stored
     * params, puts the two together and returns the result.
     */
    this.makeURL = function (URL) {
        return URL + this.toQuerystring();
    };

    /**
     * Identifies the type of the object.
     */
    this.toString = function () {
        return "Param";
    };
    
    // If params were passed in the constructor, process them.
    if (params) {
        this.addParams(params);
    }
};

// Register module with YUI (for use with YUI Loader)
if (typeof YAHOO !== "undefined" && YAHOO.register) {
    YAHOO.register("Param", NURUN.util.Param, {version: "1", build: "1"}); 
}