Event.Custom = Class.create();
Event.Custom.prototype =
{
	initialize: function(type)
	{
		this.type        = type;
		this.subscribers = [];
		//Logger.debug(type);
	},
	
	subscribe: function(fn) 
	{
		this.subscribers.push(new Event.Custom.Subscriber(fn));
		//Logger.debug(this.type + " has this many " + this.subscribers.length + " subscribers.");
	},
	
	unsubscribe: function(fn) 
	{
		var found = false;
		for (var i=0; i<this.subscribers.length; ++i) 
		{
			var s = this.subscribers[i];
			if (s && s.contains(fn)) 
			{
				this._delete(i);
				found = true;
			}
		}

		return found;
	},
	
	fire: function(e) 
	{
		if (!e.type) { e.type = this.type; }
		//Logger.debug(e.type + " has " + this.subscribers.length + "subscribers.");
		for (var i=0; i<this.subscribers.length; ++i) 
		{
			var s = this.subscribers[i];
			if (s) 
			{
				//s.fn.call(this.type, arguments);
				s.fn(e);
			}
		}
	},
	
	unsubscribeAll: function() 
	{
		//Logger.debug("unsubscribing all from " + this.type);
		for (var i=0; i<this.subscribers.length; ++i) 
		{
			this._delete(i);
		}
	},
	
	_delete: function(index) 
	{
		var s = this.subscribers[index];
		if (s) 
		{
			delete s.fn;
		}

		delete this.subscribers[index];
	}
}

Event.Custom.Subscriber = Class.create();
Event.Custom.Subscriber.prototype = 
{
	initialize: function(fn)
	{
		this.fn = fn;
	},
	
	contains: function(fn)
	{
		return (this.fn == fn);
	}
};

//Extend existing event object in prototype
Object.extend(Event,
{
	getCharCode: function(ev) 
	{
		return ev.charCode || (ev.type == "keypress") ? ev.keyCode : 0;
	},
	
	getRelatedTarget: function(ev) 
	{
		var t = ev.relatedTarget;
		if (!t) 
		{
			if (ev.type == "mouseout") 
			{
				t = ev.toElement;
			} 
			else if (ev.type == "mouseover") 
			{
				t = ev.fromElement;
			}
		}

		return t;
	}
});