//	**************************************
//	*                                    *
// 	*   Events stacks for HTML objects   *
//	*                                    *
//	*   © Yann Lojewski                  *
//	*		27.01.2007 - France              *
//	*                                    *
//	*		nxstyle@gmail.com                *
//	*		www.nenex.info                   *
//	*                                    *
//	**************************************
//
//	You can create a new listerner :
//		var myHTMLEl = document.getElementById('myHtmlElementId');
//		var myEvL = new EventListener(myHTMLEl);
//
//	You can add functions to any events
//		myEvL.addEvent('onclick', helloJohn);
//		myEvL.addEvent('onclick', helloWorld);
//		myEvL.addEvent('onclick', hello [, 'John', 'Hello World!']); // optional parameters
//
//	You can remove one or all functions from events stacks, with optional callback function
//		myEvL.remEvent('onclick', helloJohn);
//		myEvL.remEvent('onclick', helloJohn, doAfterRemoveJohn);
//		myEvL.remEvent('onclick');
//		myEvL.remEvent('onclick', null, doAfterRemoveAll);
//
//	You can replace an event function
//		myEvL.repEvent('onclick', helloJohn, helloJane);
//		myEvL.repEvent('onclick', helloJohn, hello [, 'Jane', 'Hello World!']); // optional parameters
//
//	You can get ...
//		myEvL.getEvents('onclick');
//
//	... save ...
//		myEvL.saveEvents();
//
//	... clear ...
//		myEvL.clearEvents();
//
//	... or restore
//		myEvL.restoreEvents();
//
//	**************************************



EventListener = function(htmlElement) {
	this.EL = htmlElement;
	this.EL.ref = this;
	this.EL.events = [];
}
	
EventListener.prototype = {
	callBack: function(e) {
		ev = e || window.event;
		this.ref.execFuncs.call(this, ev);
	},
	execFuncs: function(ev) {
		var funcs = this.events['on' + ev.type];
		for(var i in funcs) {
			if(typeof funcs[i] == 'object') {
				var a = [];
				for(var j=1; j<funcs[i].length; j++) a.push(funcs[i][j]);
				funcs[i][0].apply(this, a);
			}
			else
				funcs[i].call(this);
		}
	},
	addEvent: function(eventName, eventFunction) {
		this.EL[eventName] = this.callBack;
		if(!this.EL.events[eventName]) this.EL.events[eventName] = [];
		var isIn = false;
		for(var i in this.EL.events[eventName])
			if(this.EL.events[eventName][i] == eventFunction) { isIn = true; break; }
		if(!isIn) {
			args = this.addEvent.arguments;
			if(args.length > 2) {
				eventFunction = [eventFunction];
				for(var i=2; i<args.length; i++) eventFunction.push(args[i]);
			}
			this.EL.events[eventName].push(eventFunction);
		}
	},
	remEvent: function(eventName, eventFunction, callBack) {
		if(!eventFunction)
			this.EL.events[eventName] = [];
		else {
			var a = [];
			var funcs = this.EL.events[eventName];
			for(var i in funcs) {
				if(typeof funcs[i] == 'object') {
					if(funcs[i][0] != eventFunction) a.push(funcs[i]);
				}
				else
					if(funcs[i] != eventFunction) a.push(funcs[i]);
			}
			this.EL.events[eventName] = a;
			if(callBack) callBack.call(this.EL);
		}
	},
	repEvent: function(eventName, oldEventFunction, newEventFunction) {
		var funcs = this.EL.events[eventName];
		var isIn = -1;
		for(var i in funcs)
			if((typeof funcs[i] == 'object' && funcs[i][0] == oldEventFunction) || funcs[i] == oldEventFunction) isIn = i;
		if(isIn >= 0 && newEventFunction) {
			args = this.repEvent.arguments;
			if(args.length > 3) {
				newEventFunction = [newEventFunction];
				for(var i=3; i<args.length; i++) newEventFunction.push(args[i]);
			}
			this.EL.events[eventName][i] = newEventFunction;
		}
	},
	getEvents: function(eventName) {
		return this.EL.events[eventName];
	},
	clearEvents: function() {
		for(var eventName in this.EL.events)
			if(typeof this.EL.events[eventName] == 'object') this.EL[eventName[0]] = null;
			else this.EL[eventName] = null;
		this.EL.events = [];
	},
	saveEvents: function() {
		this.EL.eventsBak = this.EL.events;
	},
	restoreEvents: function() {
		if(this.EL.eventsBak) this.EL.events = this.EL.eventsBak;
	}
}
