/**
 *	EventListener module
 *	---------------------------------------------
 *	(c) Lost Boys - http://www.lostboys.nl
 */

var EventListener = {
	listeners:[],
	bCapture:false,
	bSafari:/safari/i.test(navigator.userAgent),
	addEvents:function(els, type, func, scope) {
		var events = [];
		for(var event,i=0; i<els.length; i++) {
			event = this.addEvent(els[i], type, func, scope);
			events.push(event);
		}
		return events;
	},

	addEvent:function(el, type, func, scope) {
		var handler = this.delegate(func, scope || el);
		try {
			el.addEventListener(type, handler, this.bCapture);
		} catch (e) {
			el.attachEvent('on' + type, handler);
		}

		var event = { element:el, type:type, handler:handler, capture:this.bCapture };
		this.listeners.push(event);
		return event;
	},

	removeEvents:function(events) {
		for (var i=0; i<events.length; i++) {
			this.removeEvent(events[i]);
		}
	},

	removeEvent:function(event) {
		try {
			event.element.removeEventListener(event.type, event.handler, event.capture);
		} catch (e) {
			event.element.detachEvent('on' + event.type, event.handler);
		}

		for(var i=0; i<this.listeners.length; i++) {
			if(this.listeners[i] == event) {
				this.listeners.splice(i, 1);
				break;
			}
		}
	},

	dispatchEvents:function(elements, type) {
		for (var i=0; i<elements.length; i++) {
			this.dispatchEvent(elements[i], type);
		}
	},
	
	dispatchEvent:function(el, type) {
		var events, node = el, event = {target:el, type:type};
		while(node && !event.cancelBubble) {
			events = this.getEvents(node, type);
			for(var i=0; i<events.length; i++) {
				events[i].handler(event);
			}
			node = node.parentNode;
		}
	},

	getTarget:function(e, name) {
		var target = e.target || e.srcElement;
		var reg = name? new RegExp('^'+name+'$', 'i') : null;
		while(target && (target.nodeType != 1 || (reg && !reg.test(target.nodeName)))) {
			target = target.parentNode;
		}
		return target;
	},

	getEvents:function(el, type) {
		var result = [];
		for(var item,i=0; (item = this.listeners[i++]);) {
			if((!el || el == item.element) && (!type || type == item.type)) {
				result.push(item);
			}
		}
		return result;
	},

	cancelEvent:function(e) {
		this.preventDefault(e);
		this.stopPropagation(e);
		return false;
	},

	preventDefault:function(e) {
		try {
			e.preventDefault();
		} catch (exception) {
			e.returnValue = false;
		}

		if(this.bSafari) {
			var target = this.getTarget(e, 'a');
		 	if(target) { target.onclick = function() { return false; }; };
		}
	},

	stopPropagation:function(e) {
		try {
			e.stopPropagation();
		} catch (exception) {
			e.cancelBubble = true;
		}
	},

	setCapture:function(toggle) {
		this.bCapture = toggle;
	},

	delegate:function(func, scope) {
		return function() {
			func.apply(scope, arguments);
		}
	}
}