/*
	Note!!!!! If an object is an instance of a built-in class, like a form or a link, it does NOT inherit from
	the super class Object in Internet Explorer and Netscape 6. But it does in Netscape 4 and Opera.
	Remember that this file is to be loaded before any other javascript file in which you define or extend any class.
	Otherwise the methods in this file may not exist in your instance variables.
	If you capture onload or onunload events for a window/frame in Netscape 4 every possible Layer object in the window/frame will also trigger the assigned event handler.
	That is probably not what you want, so to prevent the event from trickling down the document object model,
	you specify the doCapture argument as true.
*/

/*	The following method allows inheritance from more than one (super) class.
	Every property and method of the super class is copied to the this class.
	It is used like this:
	function ClassThatInherits() {
		this.extendClass('ClassToInheritFrom');
		this.extendClass('AnotherClassToInheritFrom');
		this.extendClass('YetAnotherClassToInheritFrom');
	}
	Note that if some of the super-classes has any properties or methods in common the latter overrides the others
*/
Object.prototype.extendClass = function(className) {
	if (typeof className == "string" && className != "" && typeof window[className] == "function") {
		var objSuper = eval('new ' + className + '()');
	/*	Note that Opera 6 and previous does not allow looping through
		the built-in properties - only user-defined properties */	
		if (typeof objSuper == "object" && objSuper != null) {
			for (var p in objSuper) {
				this[p] = objSuper[p];
			}
		}
	}
}

Object.prototype.addEvent = function(target, eventName, handler, doCapture) {
	if (typeof target != "object" || typeof handler != "function") {
		return;
	}
	var targetObj, thisObj;
/*	In Opera, NS6 and IE the this keyword refers to the window object.
	But in NS4 this refers to the function from which this method was called or the Call object.
	The Call object defines the scope in which a function is executed.
	This means that variables in a function are properties of the Call object. */
	// In Opera 7 it is necessary to compare the location objects too - must be a bug
	if (typeof this == "object" && this != window && this.location != location && this.toString().indexOf("Call") == -1) {	
		thisObj = this;
	}
	targetObj = target;
	if (targetObj == null)	{
		if (thisObj == null) {
			return;
		}
		targetObj = thisObj;
	}
	eventName = eventName.toLowerCase();
	if (eventName.indexOf('on') == -1) {
		eventName = 'on' + eventName;
	}
	if (typeof doCapture != "boolean") {
		doCapture = false;
	}
	if (targetObj.captureEvents != null && doCapture) { // Both Opera, Mozilla and Netscape 4 supports captureEvents
		eval('targetObj.captureEvents(Event.' + eventName.substr(2).toUpperCase() + ');');
	}
/*	The variable thisObj is necessary to pass the object to the handler function.
	To write 'this' as an argument in the handler function passes the targetObj object instead.
	This condition makes it possible to refer to a class of your own. */
	if (thisObj == null) {
		thisObj = targetObj;
	}
/*	The Event object is automatically passed as the last argument in the handler in all browsers, but in Internet Explorer.
	Therefore it is explicitly written as an argument and then assigned the event object of the appropiate window in Internet Explorer. */

	// do not overwrite the event-handler if already defined.
	var oldHandler;
	if (targetObj[eventName] != null) {
		oldHandler = targetObj[eventName];
	}
	targetObj[eventName] = function(eventObj) {
	/*	Even though the event is global in Opera it is also automatically passed to the event handler as an argument.
		Opera can simulate Internet Explorer and then understands document.all */
		if (eventObj == null && typeof event == "object" && event != null) {
	 		eventObj = event;
		}
		if (oldHandler != null) {
			handler(eventObj, thisObj);
			// Opera 7 doesn't understand routeEvent even though it understands captureEvents	
			if (targetObj.routeEvent != null && doCapture) {
				oldHandler(eventObj)
				return targetObj.routeEvent(eventObj);
			} else {
				return oldHandler(eventObj);
			}
		} else {
			if (targetObj.routeEvent != null && doCapture) {
				handler(eventObj, thisObj);
				return targetObj.routeEvent(eventObj);
			} else {
				return handler(eventObj, thisObj);
			}
		}
	}
}

Object.prototype.removeEvent = function(target, eventName) {
	if (typeof target == "object") {
		var targetObj = target;
		if (targetObj == null)	{
			if (!(typeof this == "object" && this != window && this.toString().indexOf("Call") == -1)) {
				return;
			}
			targetObj = this;
		}	
		eventName = eventName.toLowerCase();
		if (eventName.indexOf('on') == -1) {
			eventName = 'on' + eventName;
		}		
		if (targetObj.releaseEvents != null) {
			eval('targetObj.releaseEvents(Event.' + eventName.substr(2).toUpperCase() + ');');
		}
		targetObj[eventName] = null;
	}
}

function addEvent(target, eventName, handler, doCapture) {
	if (typeof target == "object" && target != null) {
		if (eventName.toLowerCase().indexOf("load") > -1 && navigator.userAgent.toLowerCase().indexOf('msie 6') > -1 && navigator.appMinorVersion.toLowerCase().indexOf("sp1") > -1) {
		/*	It is necessary in IE6 SP1 to change the target from self to window.
			This is due to the fact that self == window, but self !== window in IE6.
			What a bug Microsoft! */
			if (target == window) {
				target = window;
			}
		}	
		var o = new Object();
		target.addEvent = o.addEvent; // necessary in Internet Explorer - otherwise one could just invoke the addEvent method of o.
		target.addEvent(target, eventName, handler, doCapture);
	}
}

function removeEvent(target, eventName) {
	if (typeof target == "object" && target != null) {
		if (eventName.toLowerCase() == "onload" && navigator.userAgent.toLowerCase().indexOf('msie 6') > -1 && navigator.appMinorVersion.toLowerCase().indexOf("sp1") > -1) {
			if (target == window) {
				target = window;
			}
		}
		var o = new Object();
		target.removeEvent = o.removeEvent;
		target.removeEvent(target, eventName);
	}
}

function stopEventPropagation(e) {
	if (e != null) {
		if (e.stopPropagation != null) {
			e.stopPropagation();
		}
		else if (e.cancelBubble != null) {
			e.cancelBubble = true;
		}
	}
}