/*MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006-2007 Valerio Proietti, <http://mad4milk.net>, MIT Style License.||Clientcide Copyright (c) 2006-2008, http://www.clientcide.com/wiki/cnet-libraries#license*/

(function(){var getType=function(type){var custom=Element.Events.get(type);return custom?custom.base:type};var checkOverOut=function(el,e){if(el==e.target||el.hasChild(e.target)){var related=e.relatedTarget;if(related==undefined)return true;if(related===false)return false;return($type(el)!='document'&&related!=el&&related.prefix!='xul'&&!el.hasChild(related))}};var check=function(e,test){var target=e.target;var isOverOut=/^(mouseover|mouseout)$/.test(e.type);var els=this.getElements(test);var match=els.indexOf(target);if(match>=0)return els[match];for(var i=els.length;i--;){var el=els[i];if(el==target||el.hasChild(target)){return(!isOverOut||checkOverOut(el,e))?el:false}}};var splitType=function(type){if(type.test(/^.*?\(.*?\)$/)){return{event:type.match(/.*?(?=\()/),selector:type.replace(/^.*?\((.*)\)$/,"$1")}}return{event:type}};var oldAddEvent=Element.prototype.addEvent,oldAddEvents=Element.prototype.addEvents,oldRemoveEvent=Element.prototype.removeEvent,oldRemoveEvents=Element.prototype.removeEvents;Element.implement({addEvent:function(type,fn){var splitted=splitType(type);if(splitted.selector){var monitors=this.retrieve('$moo:delegateMonitors',{});if(!monitors[type]){var monitor=function(e){var el=check.call(this,e,splitted.selector);if(el)this.fireEvent(type,[e,el],0,el)}.bind(this);monitors[type]=monitor;oldAddEvent.call(this,splitted.event,monitor)}}return oldAddEvent.apply(this,arguments)},removeEvent:function(type,fn){var splitted=splitType(type);if(splitted.selector){var events=this.retrieve('events');if(!events[type]||(fn&&!events[type].contains(fn)))return this;if(fn)events[type].erase(fn);else events[type].empty();if(events[type].length==0){var monitors=this.retrieve('$moo:delegateMonitors',{});oldRemoveEvent(splitted.event,monitors[type]);delete monitors[type]}return this}return oldRemoveEvent.apply(this,arguments)},fireEvent:function(type,args,delay,bind){var events=this.retrieve('events');if(!events||!events[type])return this;events[type].keys.each(function(fn){fn.create({'bind':bind||this,'delay':delay,'arguments':args})()},this);return this}})})();