/*
 *	author: WebKitchen.cz; http://www.webkitchen.cz
 */

var Listener;

if (document.addEventListener) {

	Listener = function(where, when, what, callOn) {
		callOn = callOn || where;
		this._isListening = false;
		this.listen = function() {
			if (!this._isListening) {
				this._isListening = true;
				where.addEventListener(when, handler, false);
			}
		}
		this.stopListen = function() {
			if (this._isListening) {
				this._isListening = false;
				where.removeEventListener(when, handler, false);
			}
		}
		this.isListening = function() {
			return this._isListening;
		}
		function handler(e) {
			what.call(callOn, e)
		}
	}

} else {

	Listener = function (where, when, what, callOn) {

		callOn = callOn || where;

		this._isListening = false;

		this.listen = function() {
			if (!this._isListening) {
				this._isListening = true;
				where.attachEvent('on' + when, handler);
			}
		}
		this.stopListen = function() {
			this._isListening = false;
			where.detachEvent('on' + when, handler);
		}
		this.isListening = function() {
			return this._isListening;
		}
		function handler() {
			var e = window.event;
			e.currentTarget = where;
			e.target = e.srcElement;
			e.preventDefault = function() {e.returnValue = false;}
			e.stopPropagation = function() {e.cancelBubble = true;}
			what.call(callOn, e);
		}
	}

}


if (!Function.prototype.call) {
	Function.prototype.call = function(_this) {
		var i, args = [];
		for (i = 1; i < arguments.length; i++) {
			args[i - 1] = 'arguments[' + i + ']';
		}
		_this['<this-as-method>'] = this;
		eval("_this['<this-as-method>'](" + args.join(', ') + ")");
		_this['<this-as-method>'] = 'undefined';
	}
}

