
	EventUtils = function() {
	
		return {

			unload: function() {

				if(Cache.listeners)
					Cache.listeners.iterate(function(item) {EventUtils.removeEventListener.apply(this,item)});
			},

			/**** Really need to test in Safari. Also maybe Safari has advanced handling for onclick so need to 
			detect this so can use it rather than the dodgy thing if type is click****/
			addEventListener: function(el,type,listener,capture) {

				if(!Cache.listeners)
					Cache.createDivision("listeners");
				
				if (typeof capture == 'undefined') 
					capture = false;

				var el = $.id(el);
				var l = el["_"+listener] = EventUtils.wrapListener(listener, el);

				if (el.addEventListener)
					el.addEventListener(type,listener,capture);

				else if (el.attachEvent)
					el.attachEvent('on'+type,l,capture);

				else { 
					try {
						el['on'+type] = wrappedL; 
					}
					catch(e) {}
				}

				Cache.listeners.add([el,type,listener,capture]);
			},
	
			removeEventListener: function(el,type,listener,capture) {

				if (typeof capture == 'undefined') 
					capture = false;
				
				var el = $.id(el);
				var l = el["_"+listener];

				if (el.removeEventListener) {
					el.removeEventListener(type,listener,capture);
				}
				
				else if (el.detachEvent) {
					el.detachEvent('on'+type,l,capture);
					l = null;
				}

				else {
					try {
						el['on'+type] = null; //For Safari. **** I guess this is right. Look it up ****
					}
					catch(e) {}
				}	
			},
	
			targetElement: function(e) {
							   
				var e = e || window.event;
				var target = e.target? e.target: e.srcElement;
				
				if (target.nodeType == 3)			    
					target = target.parentNode; //for Safari
				
				return target;
			},
	
			mouse: function(e) {
					   
				var e = e || window.event;
				
				x = e.pageX?
					e.pageX:
					e.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
				
				y = e.pageY?
					e.pageY:
					e.clientY + document.documentElement.scrollTop + document.body.scrollTop;
				
				return {x: x, y: y};
			},
		
			relTarget: function(e) {
						   
				var e = e || window.event;
				
				if (e.type == 'mouseover')
					return e.relatedTarget || e.fromElement;
				
				else if (e.type == 'mouseout')
					return e.relatedTarget || e.toElement;
			}, 

			//**** TEST ****/
			stopDefault: function(e) {
							 
				var e = e || window.event;
				
				if (e.preventDefault) {
					e.preventDefault;
					e.stopPropagation;
				}
				
				else {
					event.returnValue = false;
					event.cancelBubble = true;
				}
			},

			/* Detects when mouse truly leaves a layer. Ignores movement from inner layer to layer with mouseout attached
			which would normally trigger a mouseout event due to bubbling. Also ignores movement onto a link within the
			layer, which is normally registered as a mouseout. Call from within event listener: if (EventUtils.mouseLeave(e) == true)
			procede with listener. 
			*/
			mouseLeave: function(e) {
							
				var e = e || window.event;
				var target = this.targetElement(e);
				var rTarget = this.relTarget(e);
				
				while (rTarget != target && rTarget.nodeName != 'BODY')
					rTarget = rTarget.parentNode;
				
				return (rTarget == target)? false: true;  
			},

			wrapListener: function(method, scope) {
							  
				return function(e) {
					method.call(scope, e || window.event);
				}
			}

		}
	}();

	//To prevent IE memory leaks
	EventUtils.addEventListener(window, 'unload', EventUtils.unload);
