
//Cross-browser addEvent and removeEvent.
/*
addEvent(object: Object, event: String, handler: Function(e: Event): Boolean, [scope: Object = object]): void

	Adds an event listener to an object.
	
	objectobject that will receive the listener
	eventevent name without the "on" prefix (click, mouseover, ...)
	handler
	
	function that will be called when the event occur, the event object will be sent as argument to this function,
	and besides the normal properties, it will *always* have:
		
	target: object that generated the event
	key: keeps the character key code on keyboard events
	stopPropagation: method to avoid the event propagation
	preventDefault: method to avoid the default action
			
	the preventDefault method can be emulated by returning "false" in the function
		
	scopescope (who the "this" inside the callback will refer to) that will be used when the function get invoked, the default value is the object on the first argument

addEvent = function(o, e, f, s){
	var r = o[r = "_" + (e = "on" + e)] = o[r] || (o[e] ? [[o[e], o]] : []), a, c, d;
	r[r.length] = [f, s || o], o[e] = function(e){
		try{
			(e = e || event).preventDefault || (e.preventDefault = function(){e.returnValue = false;});
			e.stopPropagation || (e.stopPropagation = function(){e.cancelBubble = true;});
			e.target || (e.target = e.srcElement || null);
			e.key = (e.which + 1 || e.keyCode + 1) - 1 || 0;
		}catch(f){}
		for(d = 1, f = r.length; f; r[--f] && (a = r[f][0], o = r[f][1], a.call ? c = a.call(o, e) : (o._ = a, c = o._(e), o._ = null), d &= c !== false));
		return e = null, !!d;
    }
};
*/

function addEvent(obj, type, fn) {
    var handler = function(e) { 
        e = e || window.event;
	e.key = (e.which + 1 || e.keyCode + 1) - 1 || 0;
        if(!e.stopPropagation) e.stopPropagation = function() { this.cancelBubble = true; }
        if(!e.preventDefault) e.preventDefault = function() { this.returnValue = false; }
        // convenience function for both stopping bubbling and preventing the browser default
        if(!e.stopEvent) e.stopEvent = function() { this.stopPropagation(); this.preventDefault(); }
        return fn.apply(obj, [e]); 
    }
    handler.obj = obj; handler.type = type; handler.fn = fn;
    removeEvent.handlers.push(handler);
    if(window.addEventListener) obj.addEventListener(type, handler, false);
    else if(window.attachEvent) obj.attachEvent("on"+type, handler);
    return handler;
}
function removeEvent(obj, type, fn) {
    for(var i = 0; i < removeEvent.handlers.length; i++) {
        var h = removeEvent.handlers[i];
        if(h.obj == obj && h.type == type && h.fn == fn) {
            if(window.removeEventListener) { obj.removeEventListener(h.type, h, false); }
            if(window.detachEvent) { obj.detachEvent("on"+h.type, h); }
            removeEvent.handlers.splice(i,1);
            return h;
        }
    }
}
removeEvent.handlers = [];

///////////////////////////////////////////////////////////////////////////////////////
/*
removeEvent(object: Object, event: String, handler: function(e: Event): Boolean, [scope: Object = object]): Boolean

	Removes a previously added listener from the object and returns true in case of success.
	
	objectobject that received the listener
	eventevent name without the "on" prefix (click, mouseover, ...)
	handlersame function that was assigned on the addEvent
	scopesame scope that was assigned on the addEvent (if you provided a scope, it's necessary to send the same object as argument, otherwise the listener won't be removed), the default value is the object on the first argument

removeEvent = function(o, e, f, s){
	for(var i = (e = o["_on" + e] || []).length; i;)
		if(e[--i] && e[i][0] == f && (s || o) == e[i][1])
			return delete e[i];
	return false;
};
*/
