/**
 * AOP style event handling, for listening for method calls. Very similar to dojo.connect

/* Add a listener for the execution of the given function slot on the given object.
 *
 * When object[eventName]() is executed the handler is called.
 * The optional before parameter can be used to indicate if the listener
 * should be fired before or after the  default action (default is after)
 */
exports.observe = function(object, eventName, listener, before) {
    if(!listener){
        throw new Error("No listener provided");
    }
	if(typeof object.observe === "function"){
		// CommonJS observable object
		return object.observe(eventName, listener);
	}
	var listenerProxy = function(that, args){//make sure we have unique function so we can remove it
        try{
			listener.apply(that, args);
    	}catch(e){
    		require("./process").print(e);
    	}
	};
	if(typeof object.addListener === "function"){
		// NodeJS EventEmitter
		object.addListener(eventName, listener);
		return {
			observe: function(listener){
				return exports.observe(object, eventName, listener);
			},
			emit: function(event){
				object.emit(eventName, event);
			},
			dismiss: function(){
				object.removeListener(eventName, listener);
			}
		};
	}
    var afters, befores,
        main = object[eventName];
    if(typeof main != "function"){
        main = function(){};
    }
	if(main._afters){
        afters = main._afters;
        befores = main._befores;
    }
    else{
        befores = [];
        afters = [];
        var newFunc = object[eventName] = function(){
            for(var i = 0; i < befores.length; i++){
            	befores[i](this, arguments);
            }
            try{
                return main.apply(this, arguments);
            }
            finally{
                for(var i = 0; i < afters.length; i++){
            		afters[i](this, arguments);
                }
            }
        };
        newFunc._befores = befores;
        newFunc._afters = afters;
    }
    if(before){
    	befores.push(listenerProxy);
    }
    else{
    	afters.push(listenerProxy);
    }
    return createSignal();
    function createSignal(){
    	var observers;
    	return {
	    	observe: function(listener){
	    		afters.push(listener);
	    	},
	    	emit: function(){
	    		main.apply(object, arguments);
	    	},
	    	dismiss: function(){
	    		if(before){
	    			befores.splice(befores.indexOf(listenerProxy), 1);
	    		}
	    		else{
	    			afters.splice(afters.indexOf(listenerProxy), 1);
	    		}
	    	}
    	};
    };
};
