dojo.provide("apple");

dojo.registerModulePath('apple', '../qamnet');

dojo.require("apple.lang.array");
dojo.require("apple.element");
dojo.require("apple.event");
dojo.require('apple.patch.safari');
    
/** Standard extensions to the Function prototype. Basically lifted from Prototype.
 */
Function.prototype.bind = function() {
    var self = this;
    var args = apple.lang.toArray(arguments);
    var object = args.shift();

    return function() {
        return self.apply(object, args.concat(apple.lang.toArray(arguments)));
    };
}

Function.prototype.bindAsEventListener = function() {
    var self = this;
    var args = apple.lang.toArray(arguments);
    var object = args.shift();
    
    return function(event) {
        return self.apply(object, [event || window.event].concat(args));
    };
}

Math.clamp= function(number, min, max)
{
    return Math.min(Math.max(min, number), max);
}

/**
 *  Add all properties of defaults that don't already exist to value.
 *  
 *  @returns value with all original property values plus any properties
 *           from defaults which didn't exist in the original value hash.
 */
Object.applyDefaults = function(value, defaults) {
    value= value||{};
    defaults= defaults||{};
    for (var prop in defaults) {
        if (prop in value)
            continue;
        value[prop]= defaults[prop];
    }
    return value;
}

/** Make a shallow-copy clone of an object.
 */
Object.clone= function(obj) {
    var fn = (function(){});
    fn.prototype = obj;
    return new fn();
}

/** Create a query string from an object.
 */
Object.toQueryString = function(obj) {
    var p;
    var v;
    var o= {};
    var args= [];
    
    function addPair(key, value) {
        key= encodeURIComponent(key);
        if (null!==value && undefined!==value)
            value= encodeURIComponent(value);
        args.push(key+'='+value);
    }
    
    for (p in obj) {
        v= obj[p];
        //  skip properties defined on Object
        if (obj[p]===o[p])
            continue;
        if (v instanceof Array)
            v.forEach(function(value) { addPair(p, value); });
        else
            addPair(p, v);
    }
    
    return args.join("&");
}

/** Create an object from a query string.
 */
Object.fromQueryString = function(query) {
    if ("?"==query.charAt(0))
        query= query.slice(1);
        
    query= query.split(/\s*&\s*/);
    
    var params= {};
    var v;
    
    function trim(s) {
        return (s||"").replace(/^\s+/, "").replace(/\s+$/, "");
    }
    
    function splitParam(param) {
        param= param.split("=");
        var key= decodeURIComponent(trim(param[0]));
        var value= decodeURIComponent(trim(param[1]))||undefined;
        
        if (key in params) {
            v= params[key];
            if (v instanceof Array)
                v.push(value);
            else
                params[key]= [v, value];
        }
        else
            params[key]= value;
    }

    query.forEach(splitParam);
    return params;
}

if ('undefined'==typeof(Class))
    Class= {
        extend: function(klass, decl)
        {
            var proto= klass.prototype;
            for (var p in decl)
                proto[p]= decl[p];
        }
    };


/** Add console & console.log for browsers that don't support it.
 */
if ("undefined"==typeof(window.console))
    window.console= {};
if ('undefined'==typeof(window.console.log))
    window.console.log= function(){};


/** Standard components instantiated on each page... **/
dojo.require('apple.widget.LinkManager');