
/*
 * @author:		Martijn Polak <martijn.polak@amgate.com>
 * @name:		Javascript Kit v1.00
 *				Crossbrowser compatibility
 */
 
if (typeof(javascriptKit) != 'undefined') {
	
	javascriptKit.compat = {
	
		// Add aditional properties to an event object so it works properly on both IE and Mozilla
		compatibleEvent : function (e) {

			// This makes sure you can pass an event object to a function as the first argument in a direct function assignment, 
			// which by default works in Mozilla but doesn't in IE.
			if (typeof(e) == 'undefined') e = window.event;
			if (typeof(e) == 'undefined') return;
		
			// If the input event has already been made compatible we don't need to go though this function again
			if (typeof(e.compatible) != 'undefined') return e;
			
			e.compatible = true;
			if (typeof(e) == 'undefined') e = window.event;
			if (typeof(e.target) == 'undefined') e.target = e.srcElement;
			if (typeof(e.layerX) == 'undefined') e.layerX = e.offsetX;
			if (typeof(e.layerY) == 'undefined') e.layerY = e.offsetY;
			if (typeof(e.keyCode) == 'undefined') e.keyCode = e.which;
		
			// The button property will be set as event.mousebutton because event.button is readonly in Mozilla.
			// 1 = left, 2 = right, 4 = middle
			if (typeof e.button == 'undefined') {
		
				e.mousebutton = event.which;
				if (e.mousebutton == 0) e.mousebutton = 1;
				if (e.mousebutton == 2) e.mousebutton = 4;
				if (e.mousebutton == 3) e.mousebutton = 2;
		
			} else {
				
				e.mousebutton = e.button;
		
				// The latest versions of mozilla support event.button but implement them differently from IE
				if (navigator.appName == 'Netscape') {
					if (e.mousebutton == 0) e.mousebutton = 1;
					else if (e.mousebutton == 1) e.mousebutton = 4;
					else if (e.mousebutton == 2) e.mousebutton = 2;
				}
				
			}
		
			// Use mozilla compatible functions for cancelling events on IE browsers
			if (!e.stopPropagation) e.stopPropagation = function () { window.event.cancelBubble = true };
			if (!e.preventDefault) e.preventDefault = function () { window.event.returnValue = false; };
		
			return e;

		},
		
		// Crossbrowser compatible positioning
		elementOffset : function (element) {

			this.x = (element.offsetLeft ? element.offsetLeft : 0);
			this.y = (element.offsetTop ? element.offsetTop : 0);
			var parent = element.offsetParent;
		
			while (parent) {
				this.x += (parent.offsetLeft ? parent.offsetLeft : 0);
				this.y += (parent.offsetTop ? parent.offsetTop : 0);
				parent = parent.offsetParent;
			}

		},

		// Crossbrowser compatible scroll offset
		scrollOffset : function (frame) {

			if (!frame) frame = window;

			var docElem;
			if (frame.document.documentElement) docElem = frame.document.documentElement;
			else docElem = frame.document.body;

			if (docElem) {
				this.x = (frame.pageXOffset ? frame.pageXOffset : docElem.scrollLeft);
				this.y = (frame.pageYOffset ? frame.pageYOffset : docElem.scrollTop);
				this.width = (docElem.scrollWidth ? docElem.scrollWidth : docElem.offsetWidth);
				this.height = (docElem.scrollHeight ? docElem.scrollHeight : docElem.offsetHeight);
			} else {
				javascriptKit.debugPrint('compat::scrollOffset: no document/body element in page');
			}

		},

		// Mozilla includes textNodes in it's DOM hierarchy, which means that the 
		// firstChild or nextSibling of an element will be a textNode instead of an html 
		// element whenever we use spaces, newlines or tab characters to make our html
		// human readable. These functions loop through the children of a node until 
		// they encounter a valid html entity (ie, an element that has a tagName propery).
		firstChild : function (node) {

			node = node.firstChild;
			while(javascriptKit.compat.isTextNode(node)) node = node.nextSibling;

			return node;

		},
		
		nextSibling : function (node) {
			
			while(node) {
				node = node.nextSibling;
				if (!javascriptKit.compat.isTextNode(node)) break;
			}
			
			return node;
			
		},
		
		lastChild : function (node) {
			
			node = node.lastChild;
			while(javascriptKit.compat.isTextNode(node)) node = node.previousSibling;
		
			return node;
		
		},
		
		previousSibling : function (node) {
			
			while(node) {
				node = node.previousSibling;
				if (javascriptKit.compat.isTextNode(node)) break;
			}
			
			return node;
		
		},

		isTextNode : function (node) {
			return (typeof(node) != 'undefined' && node && typeof(node.tagName) == 'undefined');
		}

	}

}
