go.events = new (function()
{

this.add = (
	function(node, event, handler, group, enb)
	{
		node = go.$(node);
		if (!group) {group = "general";}
		if (enb === undefined) {enb = true;}
		var id = aHandlers.length;				
		var h  = [node, event, handler, group, enb];
		aHandlers[id] = h;
		h[5] = mHandler(id);
		if (aGroups[group]) {
			aGroups[group][0].push(id);
		} else {
			aGroups[group] = [[id], true];
		}
		return id;
	}
);

this.remove = (
	function(id)
	{
		var h = aHandlers[id];
		if (!h) {return false;}
		remove(h[0], h[1], h[5]);
		aHandlers[id] = false;
		return true;
	}
);
this.enable = (
	function(id)
	{
		var h = aHandlers[id];
		if (!h) {return false;}
		h[4] = true;
		return true;
	}
);
this.disable = (
	function(id)
	{
		var h = aHandlers[id];
		if (!h) {return false;}
		h[4] = false;
		return true;	
	}
);

this.groupRemove = (
	function(name) 
	{
		var g = aGroups[name];
		if (!g) {return false;}
		g = g[0];
		var len = g.length;
		for (var i = 0; i < len; i++) {
			_this.remove(g[i]);
		}
		delete(aGroups[name]);
		return true;
	}
); 
this.groupEnable = (
	function(name) 
	{
		var g = aGroups[name];
		if (!g) {return false;}
		g[1] = true;
		return true;
	}
);
this.groupDisable = (
	function(name)
	{
		var g = aGroups[name];
		if (!g) {return false;}
		g[1] = false;
		return true;	
	}
);

this.getEvent = (function() {return event;});

this.getTarget = (function() {return event.srcElement || event.target;});

this.getNode = (function() {return enode;});

this.stopPropagation = (
	function()
	{
		if (event.stopPropagation) {
			return event.stopPropagation();
		}
		event.cancelBubble = true;		
		return true;
	}
);

this.preventDefault = (
	function()
	{
		if (event.preventDefault) {			
			return event.preventDefault();
		}
		event.returnValue = false;
		return true;	
	}
);


/*** PRIVATE: ***/

function add(node, event, handler)
{
	if (node.addEventListener) {
		var f = (function(node, event, handler) {return node.addEventListener(event, handler, false);});
	} else if (node.attachEvent) {
		var f = (function(node, event, handler) {return node.attachEvent("on" + event, handler);});		
	} else {
		var f = go.emptyFunction;
	}
	add = f;
	return f(node, event, handler);
}
function remove(node, event, handler)
{
	if (node.removeEventListener) {
		var f = (function(node, event, handler) {return node.removeEventListener(event, handler)});
	} else if (node.dettachEvent) {
		var f = (function(node, event, handler) {return node.dettachEvent("on" + event, handler);});		
	} else {
		var f = go.emptyFunction;
	}
	remove = f;
	return f(node, event, hanlder);
}

var aHandlers = [];
var aGroups   = {};
var event;
var enode;
var _this = this;
var me = go.methodExec;

function mHandler(id)
{
	var h = aHandlers[id];
	var f = (
		function(e)
		{
			if (!h[4]) {
				return false;
			}
			if (!aGroups[h[3]][1]) {
				return false;
			}
			event = e || window.event;
			enode = h[0];
			return me(h[2], h[0]);
		}
	);
	add(h[0], h[1], f);
	return f;
}

})(); 