// ==============================================================================================================================
// Class EventRegister1
// ==============================================================================================================================
function EventRegister1 () {
	this.construct();
}

//-----------------------------------------------------------------
// Method EventRegister1.construct()
//-----------------------------------------------------------------
EventRegister1.prototype.construct = function (sId) {
	this.handlers = new Array();
	this.events = new Array();
	this.addHandler(window, 'unload', this, 'cleanUp');
}

//-----------------------------------------------------------------
// Method EventRegister1.addHandler()
//-----------------------------------------------------------------
EventRegister1.prototype.addHandler = function (Target, sEventType, oListener, sMethodName) {
	try {
		var oEventHandler = new EventHandler1(Target, sEventType, oListener, sMethodName);
		oEventHandler.attach();
		this.handlers.push(oEventHandler);
	} catch (e) {
		alert('Error in addHandler(' + Target + ', \'' + sEventType + '\', ' + oListener + ', \'' + sMethodName + '\') :\n\n' + e.toString());
	}
} // function addHandler

//-----------------------------------------------------------------
// Method EventRegister1.lookupHandler()
//-----------------------------------------------------------------
EventRegister1.prototype.lookupHandler = function (Target, sEventType, oListener, sMethodName) {
	for ( var i = 0; i < this.handlers.length; i++ ) 
		if ( (this.handlers[i]) && (this.handlers[i].match(Target, sEventType, oListener, sMethodName)) ) 
			return i;
	return -1;
} // function removeEventHandler

//-----------------------------------------------------------------
// Method EventRegister1.removeHandler()
//-----------------------------------------------------------------
EventRegister1.prototype.removeHandler = function (Target, sEventType, oListener, sMethodName) {
	var i = this.lookupHandler(Target, sEventType, oListener, sMethodName);
	if ( i != -1 ) {
		this.handlers[i].detach();
		this.handlers[i] = null;
	} else {
		alert('could not remove: on' + sEventType + ' -> ' + sMethodName);
	}
} // function removeEventHandler

//-----------------------------------------------------------------
// Method EventRegister1.formatEvent()
//-----------------------------------------------------------------
EventRegister1.prototype.formatEvent = function (oEvent) {
    if (typeof oEvent.charCode == 'undefined') {
        oEvent.charCode = (oEvent.type == 'keypress') ? oEvent.keyCode : 0;
        oEvent.isChar = (oEvent.charCode > 0);
    }
    if (oEvent.srcElement && !oEvent.target) {
        oEvent.eventPhase = 2;
        oEvent.pageX = oEvent.clientX + document.body.scrollLeft;
        oEvent.pageY = oEvent.clientY + document.body.scrollTop;
        if (!oEvent.preventDefault) {
                oEvent.preventDefault = function () {
                    this.returnValue = false;
                };
        }
        if (oEvent.type == 'mouseout') {
            oEvent.relatedTarget = oEvent.toElement;
        } else if (oEvent.type == 'mouseover') {
            oEvent.relatedTarget = oEvent.fromElement;
        }
        if (!oEvent.stopPropagation) {
                oEvent.stopPropagation = function () {
                    this.cancelBubble = true;
                };
        }
        oEvent.target = oEvent.srcElement;
        oEvent.time = (new Date).getTime();
    }
    return oEvent;
} // function formatEvent

//-----------------------------------------------------------------
// Method EventRegister1.destroyEvent()
//-----------------------------------------------------------------
EventRegister1.prototype.destroyEvent = function (oEvent) {
	oEvent.preventDefault = null;
	oEvent.relatedTarget = null;
	oEvent.relatedTarget = null;
	oEvent.stopPropagation = null;
	oEvent.target = null;
} // function destroyEvent

//-----------------------------------------------------------------
// Method EventRegister1.getEvent()
//-----------------------------------------------------------------
EventRegister1.prototype.getEvent = function () {
	if ( window.event ) {
		var oEvent = this.formatEvent(window.event);
		this.events.push(oEvent);
		return oEvent;
	} else {
		return getEvent.caller.arguments[0];
	}
} // function getEvent

//-----------------------------------------------------------------
// Method EventRegister1.removeAllEvents()
//-----------------------------------------------------------------
EventRegister1.prototype.removeAllEvents = function () {
	for ( var i = 0; i < this.events.length; i++ ) {
		this.destroyEvent(this.events[i]);
		this.events[i] = null;
	}
}

//-----------------------------------------------------------------
// Method EventRegister1.removeAllHandlers()
//-----------------------------------------------------------------
EventRegister1.prototype.removeAllHandlers = function () {
	for ( var i = 0; i < this.handlers.length; i++ ) 
		if ( (this.handlers[i]) && (this.handlers[i].eventType != 'unload') ) {
			this.handlers[i].detach();
			this.handlers[i] = null;
		}
}

//-----------------------------------------------------------------
// Method EventRegister1.cleanUp()
//-----------------------------------------------------------------
EventRegister1.prototype.cleanUp = function () {
	this.removeAllEvents();
	this.removeAllHandlers();
	this.removeHandler(window, 'unload', this, 'cleanUp');
}

// ==============================================================================================================================
// Class EventHandler1
// ==============================================================================================================================
function EventHandler1 (Target, sEventType, oListener, sMethodName) {
	if ( arguments.length > 0 ) this.construct(Target, sEventType, oListener, sMethodName);
}

//-----------------------------------------------------------------
// Method EventHandler1.construct()
//-----------------------------------------------------------------
EventHandler1.prototype.construct = function (Target, sEventType, oListener, sMethodName) {
	this.target = this.convertTarget(Target);
	this.eventType = sEventType;
	this.listener = oListener;
	this.methodName = sMethodName;
	this.func = function(event) { oListener[sMethodName](event); };
}

//-----------------------------------------------------------------
// Method EventHandler1.match()
//-----------------------------------------------------------------
EventHandler1.prototype.match = function (Target, sEventType, oListener, sMethodName) {
	if ( this.eventType != sEventType ) return false;
	if ( this.methodName != sMethodName ) return false
	if ( this.listener != oListener ) return false;
	if ( this.target != this.convertTarget(Target) ) return false;
	return true;
}

//-----------------------------------------------------------------
// Method EventHandler1.convertTarget()
//-----------------------------------------------------------------
EventHandler1.prototype.convertTarget = function (Target) {
	switch  ( typeof(Target) ) {
		case 'object':
			return Target;
		case 'string': 
			var oTarget = getElementById(Target);
			if (!oTarget)
				throw("EventHandler1:convertTarget: target id '"+Target+"' does not exist.");
			return oTarget;
		default:
			throw('EventHandler1:convertTarget: unsupported argument type for target('+(typeof Target)+'), need (string) or (object)');	
			return false;
	}
}

//-----------------------------------------------------------------
// Method EventHandler1.attach()
//-----------------------------------------------------------------
EventHandler1.prototype.attach = function () {
	if ( this.target.addEventListener ) 
		this.target.addEventListener(this.eventType, this.func, false);
	else if ( this.target.attachEvent )
		this.target.attachEvent('on' + this.eventType, this.func);
	else
		this.target['on' + this.eventType] = this.func;
} // function attach

//-----------------------------------------------------------------
// Method EventHandler1.detach()
//-----------------------------------------------------------------
EventHandler1.prototype.detach = function () {
	if ( this.target.removeEventListener ) {
		this.target.removeEventListener(this.eventType, this.listener, this.func, false);
	} else if ( this.target.detachEvent ) {
		this.target.detachEvent('on' + this.eventType, this.func);
	} else { 
		this.target['on' + this.eventType] = null;
	}
	this.target = null;
	this.listener = null;
	this.func = null;
} // function detach

//-----------------------------------------------------------------
// Event related functions
//-----------------------------------------------------------------		

var oEventHandler = new EventRegister1();

function addEventHandler(Target, sEventType, oListener, sMethodName) {
	oEventHandler.addHandler(Target, sEventType, oListener, sMethodName);
}

function removeEventHandler(Target, sEventType, oListener, sMethodName) {
	oEventHandler.removeHandler(Target, sEventType, oListener, sMethodName);
}

function getEvent() {
	return oEventHandler.getEvent();
}

//-----------------------------------------------------------------
// Add IE functionality
//-----------------------------------------------------------------		

if ( !document.all ) {

	Event.prototype.__defineSetter__("cancelBubble", function (b) {
   	if (b) this.stopPropagation();
	});
	
	Event.prototype.__defineSetter__("returnValue", function (b) {
   	if (!b) this.preventDefault();
	});
	
}