/*
 * ooutils.js: This entire file is lifted wholesale from MochiKit.  
 * Therefore the licensing should be MochiKit's at:
 *
 * http://svn.mochikit.com/mochikit/trunk/LICENSE.txt
 */

extend = function (self, obj, /* optional */skip) {
    // Extend an array with an array-like object starting
    // from the skip index
    if (!skip) {
        skip = 0;
    }
    if (obj) {
        // allow iterable fall-through, but skip the full isArrayLike
        // check for speed, this is called often.
        var l = obj.length;
        if (typeof(l) != 'number' /* !isArrayLike(obj) */) {
            if (typeof(MochiKit.Iter) != "undefined") {
                obj = MochiKit.Iter.list(obj);
                l = obj.length;
            } else {
                throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
            }
        }
        if (!self) {
            self = [];
        }
        for (var i = skip; i < l; i++) {
            self.push(obj[i]);
        }
    }
    // This mutates, but it's convenient to return because
    // it's often used like a constructor when turning some
    // ghetto array-like to a real array
    return self;
}
_wrapDumbFunction = function (func) {
    return function () {
        // fast path!
        switch (arguments.length) {
            case 0: return func();
            case 1: return func(arguments[0]);
            case 2: return func(arguments[0], arguments[1]);
            case 3: return func(arguments[0], arguments[1], arguments[2]);
        }
        var args = [];
        for (var i = 0; i < arguments.length; i++) {
            args.push("arguments[" + i + "]");
        }
        return eval("(func(" + args.join(",") + "))");
    };
}

bindMethods = function (self) {
    var bind = function(func, self/* args... */) {
        if (typeof(func) == "string") {
            func = self[func];
        }
        var im_func = func.im_func;
        var im_preargs = func.im_preargs;
        var im_self = func.im_self;
        if (typeof(func) == "function" && typeof(func.apply) == "undefined") {
            // this is for cases where JavaScript sucks ass and gives you a
            // really dumb built-in function like alert() that doesn't have
            // an apply
            func = _wrapDumbFunction(func);
        }
        if (typeof(im_func) != 'function') {
            im_func = func;
        }
        if (typeof(self) != 'undefined') {
            im_self = self;
        }
        if (typeof(im_preargs) == 'undefined') {
            im_preargs = [];
        } else  {
            im_preargs = im_preargs.slice();
        }
        extend(im_preargs, arguments, 2);
        var newfunc = function () {
            var args = arguments;
            var me = arguments.callee;
            if (me.im_preargs.length > 0) {
                args = m.concat(me.im_preargs, args);
            }
            var self = me.im_self;
            if (!self) {
                self = this;
            }
            return me.im_func.apply(self, args);
        };
        newfunc.im_self = im_self;
        newfunc.im_func = im_func;
        newfunc.im_preargs = im_preargs;
        return newfunc;
    }

    for (var k in self) {
        var func = self[k];
        if (typeof(func) == 'function') {
            self[k] = bind(func, self);
        }
    }
}
