var com = com || {};
com.codepoetics = com.codepoetics || {};

com.codepoetics.Async = (function() {
    
    function bind(f, g) {
        return function(a, callback, errback) {
            f(a, function(result) { return g(result, callback, errback); }, errback);
        };
    }
    
    function chain() {
        var args = Array.prototype.slice.call(arguments),
            f = args.shift();
        while (args.length > 0) {
            f = bind(f, args.shift());
        }
        return f;
    }
    
    return {
        chain: chain
    };
}());

function echoAfterOneSecond(data, callback) {
    new Request.JSON({
        url: '/echo/json/',
        data: { json: JSON.encode({ message: data }), delay: 1},
        onSuccess: function(data) { callback(data.message); }
    }).send();
}

function greet(a, callback) {
    alert("1...");
    echoAfterOneSecond(a, callback);
}

function cruel(a, callback) {
    alert("2...");
    echoAfterOneSecond(a + " cruel", callback);
}

function world(a, callback) {
    alert("3...");
    echoAfterOneSecond(a + " world", callback);
}

com.codepoetics.Async.chain(greet, cruel, world)("goodbye", function(message) { alert(message); });