// extend Element with this method
Object.extend(Element,
{
	contains: Element.contains || function(element, child)
	{
		var containee = child;
		while (containee)
		{
			if (element == containee)
				return true;
			containee = containee.parentNode;
		}
		return false;
	}
});

var MBoxUtil =
{
	getElementComputedStyle: function(htmlElement, cssProperty, mozillaEquivalentCSS)
	{
		if (arguments.length == 2)
			mozillaEquivalentCSS = cssProperty;

		var el = $(htmlElement);
		if (el.currentStyle)
			// ie
			return el.currentStyle[cssProperty];
		else
			return document.defaultView.getComputedStyle(el, null).getPropertyValue(mozillaEquivalentCSS);
	},

	toString: function(node)
	{
		if (node.xml)
			return node.xml;
		else
		{
			var xmlSerializer = new XMLSerializer();
			return xmlSerializer.serializeToString(node);
		}
	},

	getContentAsString: function(parentNode)
	{
		return (parentNode.xml != undefined) ?
			this._getContentAsStringIE(parentNode) :
			this._getContentAsStringMozilla(parentNode);
	},

	toDocumentPosition: function(element)
	{
		if (navigator.userAgent.toLowerCase().indexOf("msie") == -1)
			return this._toDocumentPositionIE(element);
		else
			return this._toDocumentPositionMozilla(element);
	},


	checkmouseenter: function(element, event)
	{
		if (event.fromElement && element.contains)
			// ie
			return !element.contains(event.fromElement);
		else if (event.relatedTarget)
			// mozilla and others
			return !Element.contains(element, event.relatedTarget);
	},

	checkmouseleave: function(element, event)
	{
		if (event.toElement && element.contains)
			return !element.contains(event.toElement);
		else if (event.relatedTarget)
			return !Element.contains(element, event.relatedTarget);
	},

	getElementsByClassName: function(className, parentElement)
	{
		var children = ($(parentElement) || document.body).getElementsByTagName('*');
		return $A(children).inject([], function(elements, child)
			{
				if (Element.hasClassName(child, className))
					elements.push(child);
				return elements;
			});
	},

	getElementsByName: function(name, parentElement)
	{
		var children = ($(parentElement) || document.body).getElementsByTagName('*');
		return $A(children).inject([], function(elements, child)
			{
				if (child.getAttribute('name') == name)
					elements.push(child);
				return elements;
			});
	},

	/* inspired by mochi-kit */
	getElementsByTagAndClassName: function(tagName, className, /* optional */parent)
	{
		if (typeof(tagName) == 'undefined' || tagName == null)
			tagName = '*';
		if (typeof(parent) == 'undefined' || parent == null)
			parent = document;
		var children = parent.getElementsByTagName(tagName) || document.all;
		if (typeof(className) == 'undefined' || className == null)
			return children;

		var elements = [];
		for (var i = 0; i < children.length; i++)
		{
			var child = children[i];
			var classNames = child.className.split(' ');
			for (var j = 0; j < classNames.length; j++)
			{
				if (classNames[j] == className)
				{
					elements.push(child);
					break;
				}
			}
		}

		return elements;
	},

	findParentNode: function(element, tagName)
	{
		var el = element.parentNode;
		while (el && el.tagName != tagName)
			el = el.parentNode;
		return el;
	},
	
	viewport: function()
	{
		var width = 0;
		var height = 0;
		if (document.documentElement && document.documentElement.clientWidth)
		{
			width = document.documentElement.clientWidth;
			height = document.documentElement.clientHeight;
		}
		else
		{
			width = window.innerWidth;
			height = window.innerHeight;
		}

		return { width: width, height:  height, cssWidth: width+'px', cssHeight: height+'px' };
	}, 

	_getContentAsStringIE: function(parentNode, includeParent)
	{
		var contentStr = '';
		childNodes = parentNode.childNodes;
		for (var i = 0; i < childNodes.length; ++i)
			contentStr += childNodes[i].xml;
		return contentStr;
	},

	_getContentAsStringMozilla: function(parentNode, includeParent)
	{
		var xmlSerializer = new XMLSerializer();
		var contentStr = '';
		var childNodes = parentNode.childNodes;
		if (childNodes)
		{
			for (var i = 0; i < childNodes.length; ++i)
				contentStr += xmlSerializer.serializeToString(childNodes[i]);
		}
		return contentStr;
	},

	_toDocumentPositionIE: function(element)
	{
		var x = 0;
		var y = 0;
		var parent = element;
		while (parent)
		{
			var borderXOffset = 0;
			var borderYOffset = 0;
			if (parent != element)
			{
				var borderXOffset = parseInt(this.getElementComputedStyle(parent, 'borderLeftWidth'));
				var borderYOffset = parseInt(this.getElementComputedStyle(parent, 'borderTopWidth'));
				borderXOffset = isNaN(borderXOffset) ? 0 : borderXOffset;
				borderYOffset = isNaN(borderYOffset) ? 0 : borderYOffset;
			}

			x += parent.offsetLeft + borderXOffset;
			y += parent.offsetTop + borderYOffset;
			parent = parent.offsetParent;
		}

		return { x: x, y: y };
	},

	_toDocumentPositionMozilla: function(element)
	{
		var x = 0;
		var y = 0;
		var parent = element;
		while (parent)
		{
			x += parent.offsetLeft;
			y += parent.offsetTop;
			parent = parent.offsetParent;
		}

		return { x: x, y: y };
	}
};

