/**
 *	Create DOM namespace
 */
var DOM = {};

/**
 * Define the several node type values
 */
DOM.NodeType = {};
DOM.NodeType.Element			= 1;
DOM.NodeType.Attribute			= 2;
DOM.NodeType.Text				= 3;
DOM.NodeType.Comment			= 8;
DOM.NodeType.Document			= 9;
DOM.NodeType.DocumentFragment 	= 11;

// Tests if sth is really an element -
// we have to check for tagName != '!' because
// IE includes comments in its element collections.
//
DOM.IsElement = function($Node) {
	return ($Node && ($Node.nodeType == DOM.NodeType.Element) && $Node.tagName != '!') ? true : false;
}

/** 
 * Finds one or more elements in a document tree.
 * Tries searching by id, by name and by tag name.
 * Returns an array with all elements found or just
 * one element if the argument count was one.
 */
DOM.Get = function()
{
	var Elements =  new Array();
	
	for(var i = 0; i < arguments.length; ++i)
	{
		var Argument = arguments[i];
		
		// The arguments have to be strings of course.
		//
		if(typeof Argument != 'string') 
		{
			if(arguments.length == 1) {
				return Argument;
			} else {
				continue;
			}
		}
		
		// If the argument is an id we'll handle
		// it a bit different, so we can return it
		// immediately if this one's all we are
		// looking for.
		//
		if(Argument.StartsWith('#'))
		{
			var Elem = document.getElementById(Argument.slice(1));
		
			if(arguments.length == 1) {
				return Elem;
			}
			
			Elements.push(Elem);
		}
		else
		{
			// No id - search by name or tag name if necessary.
			// We have to indicate an id with # because of a bug
			// in IE/Opera: Their implementation of getElementById
			// does find the first occurance of an element with a name,
			// matching the argument, too.
			//
			var ElemArray = document.getElementsByName(Argument);

			if(ElemArray.length > 0) 
			{
				Elements = Elements.concat(ElemArray);
			} 
			else
			{
				Elements = Elements.concat(document.getElementsByTagName(Argument));
			}
		}
	}
	
	return Elements;
}

DOM.CreateElement = function($Name)
{
	var $Element 	= document.createElement($Name.toUpperCase());
	var $Attributes	= arguments[1] || {};
	var $CssStyles	= arguments[2] || {};

	for(var $Name in $Attributes) 
	{
//		if($Element.setAttribute) {
//			$Element.setAttribute($Name, $Attributes[$Name]);
//		} else {
			$Element[$Name == 'class' ? 'className' : $Name] = $Attributes[$Name];
//		}
	}
	
	for(var $Style in $CssStyles) {
		DOM.Element.SetStyle($Element, $Style.Camelize(), $CssStyles[$Style]);
	}	

	return $Element;
}

DOM.InsertBefore = function($Element)
{
	$Element = DOM.Get($Element);

	for(var $i = 1; $i < arguments.length; ++$i) {
		$Element.parentNode.insertBefore(arguments[$i], $Element); 
	}
}

DOM.InsertAfter = function($Element)
{
	$Element = DOM.Get($Element);
	
	for(var $i = 1; $i < arguments.length; ++$i) {
		$Element.parentNode.insertBefore(arguments[$i], $Element.nextSibling);
	}	
}

DOM.InsertTop = function($Element)
{
	$Element = DOM.Get($Element);
	
	for(var $i = arguments.length - 1; $i > 0; --$i) {
		$Element.insertBefore(arguments[$i], $Element.firstChild);
	}
}

DOM.InsertBottom = function($Element)
{
	$Element = DOM.Get($Element);
	
	for(var $i = 1; $i < arguments.length; ++$i) {
		$Element.appendChild(arguments[$i]);
	}
}

DOM.Replace = function($NewNode, $OldNode)
{
	if($NewNode && $OldNode) {
		$OldNode.parentNode.replaceChild($NewNode, $OldNode);
	}
}

DOM.Traverse = function($Node, $Func, $Options)
{
	if(!$Node) {
		return;
	}
	
	$Func($Node);
	
	if(DOM.IsElement($Node))
	{
		for(var $i = 0; $i < $Node.childNodes.length; ++$i)
		{
			DOM.Traverse($Node.childNodes[$i], $Func, $Options);
		}
	}
}

