/*

$Id: EventManager.js 86 2006-03-24 05:32:12Z lindsay $
$Revision: 86 $
$Date: 2006-03-24 16:32:12 +1100 (Fri, 24 Mar 2006) $
$Author: lindsay $

*/

var EventManager = new __EventManager();

function __EventManager(){
	this._events = {};
	this._elements = {};
	this.debug = false;
	this.processEvents = true;
}

__EventManager.prototype.addEventListener = function(element, type, listener, useCapture){

	if(useCapture == null){
		useCapture = false;
	}
	var previouslyAdded = this.addEvent(element, type, listener);
	if(element.addEventListener){
		element.addEventListener(type, this.dispatchEvent, useCapture);
	}else if(element.attachEvent){
		if(!previouslyAdded){
			element.attachEvent('on' + type, this.dispatchEvent);
		}
	}else{
		element['on' + type] = this.dispatchEvent;
	}
}

__EventManager.prototype.removeEventListener = function(element, type, listener){
	var elementGUID = this.getElementGUID(element, type);
	if(element.removeEventListener){
		element.removeEventListener(type, this.dispatchEvent, false);
	}else if(element.detachEvent){
		element.detachEvent('on' + type, this.dispatchEvent);
	}else{
		element['on' + type] = null;
		delete element['on' + type];
	}
	if(this._events[elementGUID] != null){
		this._elements[elementGUID] = null;
		this._events[elementGUID] = null;
		delete this._elements[elementGUID];
		delete this._events[elementGUID];
	}
}

__EventManager.prototype.addEvent = function(element, type, listener){
	var elementGUID = this.getElementGUID(element, type);
	if(this._events[elementGUID] == null){
		this._elements[elementGUID] = [element];
		this._events[elementGUID] = [listener];
		return false;
	}else{
		this._elements[elementGUID].push(element);
		this._events[elementGUID].push(listener);
		return true;
	}
}

__EventManager.prototype.dispatchEvent = function(e){
	var element;
	var type;
	if(!EventManager.processEvents){
		return false;
	}
	if(typeof event != 'undefined' && event != null){ // Internet Explorer event model, and Safari
		element = event.srcElement == null ? window : event.srcElement; // guess whether the source was the window object or a HTML element
		// Safari passes the document instead of null when we want window...
		if(event.srcElement != null && event.srcElement.getElementsByTagName && event.srcElement.nodeName == '#document'){
			element = window;
		}
		type = event.type;
	}else if(typeof e != 'undefined'){ // DOM event model
		element = e.currentTarget == document ? window : e.currentTarget; // guess whether the source was the window object or a HTML element

		// currentTarget is null for window in Safari 2.0, using srcElement instead (hopefully doesn't break anything else)
		if(element == null){
			element = e.srcElement == document ? window : e.srcElement;
		}
		type = e.type;
	}else{
	}
	var elementGUID = EventManager.getElementGUID(element, type);
//alert('dispatching: '+elementGUID+' ('+EventManager._events[elementGUID].length+' events)')
	if(EventManager._events[elementGUID] != null){
		for(var i = 0; i < EventManager._events[elementGUID].length; i++){
			EventManager._events[elementGUID][i]({target: element, type: type});
		}
	}
}

__EventManager.prototype.getElementGUID = function(element, type){
	var elementName = element == window ? 'window' : element.tagName + ':' + element.id; //  + ':' + element.className // className is no good as an ID, as it is usually what is being change in an event
	var elementGUID = elementName + '_' + type;
	return elementGUID;
}
