﻿/*
 * Provides base Briefing namespace and functionality to load additional script files.
 * Include on all pages.
 */

// Takes n arguments and returns a function wrapped to those arguments; No scope altering!
Function.prototype.createCallback = function(){
    var args = arguments;
    var method = this;
    return function() {
        return method.apply(window, args);
    };
};

/**
 * Creates a delegate (callback) that sets the scope to obj.
 * Call directly on any function. Example: <code>this.myFunction.createDelegate(this)</code>
 * Will create a function that is automatically scoped to this.
 * @param {Object} obj (optional) The object for which the scope is set
 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
 *                                             if a number the args are inserted at the specified position
 * @return {Function} The new function
 */
Function.prototype.createDelegate = function(obj, args, appendArgs){
    var method = this;
    return function() {
        var callArgs = args || arguments;
        if(appendArgs === true){
            callArgs = Array.prototype.slice.call(arguments, 0);
            callArgs = callArgs.concat(args);
        }else if(typeof appendArgs == "number"){
            callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first
            var applyArgs = [appendArgs, 0].concat(args); // create method call params
            Array.prototype.splice.apply(callArgs, applyArgs); // splice them in
        }
        return method.apply(obj || window, callArgs);
    };
} 

// Check for the global Briefing namespace and create if it doesn't exist
if (typeof Briefing == "undefined" || !Briefing) {
    window.Briefing = {};
}

Briefing.isDebug = false;
Briefing._debugCheckComplete = false;

/**
 * Briefing.env is used to keep track of what is known about the YUI library and
 * the Briefing library environment
 * @class Briefing.env
 * @static
 */
Briefing.env = Briefing.env || {

    ymodules: {},
    /**
     * Keeps the version info for all Briefing modules that have reported themselves
     * @property modules
     * @type Object[]
     */
    modules: {},
    
    /**
     * Stores Briefing modules that were explicitly listed when a script file
     * was requested via a Briefing.getScripts() call.
     */  
    expectedModules : {},
    
    loadListeners: [],
    
    isDomReady : false
};

/**
 * Returns the namespace specified and creates it if it doesn't exist
 * <pre>
 * Briefing.namespace("property.package");
 * Briefing.namespace("Briefing.property.package");
 * </pre>
 * Either of the above would create Briefing.property, then
 * Briefing.property.package
 *
 * Be careful when naming packages. Reserved words may work in some browsers
 * and not others. For instance, the following will fail in Safari:
 * <pre>
 * Briefing.namespace("really.long.nested.namespace");
 * </pre>
 * This fails because "long" is a future reserved word in ECMAScript
 *
 * @method namespace
 * @static
 * @param  {String*} arguments 1-n namespaces to create 
 * @return {Object}  A reference to the last namespace object created
 */
Briefing.namespace = function() {
    var a=arguments, o=null, i, j, d;
    for (i=0; i<a.length; i=i+1) {
        d=a[i].split(".");
        o=Briefing;

        // Briefing is implied, so it is ignored if it is included
        for (j=(d[0] == "Briefing") ? 1 : 0; j<d.length; j=j+1) {
            o[d[j]]=o[d[j]] || {};
            o=o[d[j]];
        }
    }

    return o;
};


Briefing.getFourDigitYear = function(){
	var year = (new Date()).getYear();
	return (year < 1000) ? year + 1900 : year;
};

