﻿if(typeof(Element) == "undefined")
{
	Element = function()
	{
	}
	Element.saveDocGetById = document.getElementById;
	Element.saveDocGetByName = document.getElementsByName;
	Element.saveDocGetByTagName = document.getElementsByTagName;
	Element.saveDocCreateElement = document.createElement;
	Element.applyAllProperties = function(element)
	{
		if(element == null) return null;
		if(element._applyAllPropertiesDone || element.nodeName == "#text") return element;
		for(var i in Element.prototype)
			element[i] = Element.prototype[i];
		element._applyAllPropertiesDone = true;
		
		Element.applyAllProperties(element.parentNode);
		
		return element;
	}
	Element.applyAllPropertiesArray = function(elementArray)
	{
		if(elementArray == null) return null;
		for(var i = 0; i < elementArray.length; ++i)
		{
			Element.applyAllProperties(elementArray[i]);
		}
		return elementArray;
	}
	document.getElementById = function(id)
	{
		return Element.applyAllProperties(Element.saveDocGetById(id));
	}
	document.getElementsByName = function(name)
	{
		return Element.applyAllPropertiesArray(Element.saveDocGetByName(name));;
	}
	document.getElementsByTagName = function(tagName)
	{
		return Element.applyAllPropertiesArray(Element.saveDocGetByTagName(tagName));;
	}
	document.createElement = function(tagName)
	{
		return Element.applyAllProperties(Element.saveDocCreateElement(tagName));
	}
	Element.prototype.get_ChildNodes = function()
	{
		return Element.applyAllPropertiesArray(this.childNodes);
	}
}
else
{
	Element.prototype.get_ChildNodes = function()
	{
		return this.childNodes;
	}
}
Element.prototype.getSelectionStart = function() 
{
	if(this.selectionStart != null)
	{
		return this.selectionStart;
	}

	var oSel = document.selection.createRange();
	oSel.moveEnd ('character', this.value.length);
	return this.value.length - oSel.text.length;
};

Element.prototype.getSelectionEnd = function()
{
	if(this.selectionEnd != null)
	{
		return this.selectionEnd;
	}
	var oSel = document.selection.createRange();
	oSel.moveStart ('character', -this.value.length);
	return oSel.text.length;

};
Element.prototype.setSelection = function(start, end)
{
	if(this.setSelectionRange != null)
	{
		this.setSelectionRange(start, end);
		return;
	}
	// assumed IE
	var range = this.createTextRange();
	range.collapse(true);
	range.moveStart("character", start);
	range.moveEnd("character", end - start);
	range.select();
};
Element.prototype.addClass = function(className)
{
	if(this.className.indexOf(className) == -1)
		this.className += " " + className;
}
Element.prototype.removeClass = function(className)
{
	this.className = this.className.replace(className + " ", "").replace(" " + className, "").replace(className, "");
}

//Element.create = function(tagName)
//{
//	return document.createElement(tagName);
//}
Element.prototype.$$ = function(path, all)
{
	if(all == null) all = false;

	path = Element.preparePath(path);
	
	
	if(all)
		result = new Array();
	for(var i = 0; i < this.childNodes.length; ++i)
	{
		var elem = this.childNodes[i];
		if(path.check(elem))
		{
			if(Element.applyAllProperties)
				Element.applyAllProperties(elem);
			if(all)
				result.push(elem);
			else
				return elem;
		}
	}
	if(all)
		return result;
	else
		return null;
}
Element.prototype.PerformRecursive = function(action)
{
	if(action(this) === true)
		return true;
	for(var i = 0; i < this.get_ChildNodes().length; ++i)
	{
		if(this.get_ChildNodes()[i].PerformRecursive != null)
		{
			if(this.get_ChildNodes()[i].PerformRecursive(action) === true)
				return true;
		}
	}
	return false;
}
Element.prototype.$$$ = function(path, all)
{
	if(all == null) all = false;

	path = Element.preparePath(path);
	
	var result = new Array();
	var c = Element.$$$_Recursive(result, this, path, all);
	if(all)
		return result;
	else
		return c;
}
Element.$$$_Recursive = function(result, curElem, path, all)
{
	for(var i = 0; i < curElem.childNodes.length; ++i)
	{
		var c = curElem.childNodes[i];
		if(path.check(c))
		{
			if(Element.applyAllProperties)
				Element.applyAllProperties(c);
			if(all)
				result.push(c);
			else
				return c;
		}
		var t = Element.$$$_Recursive(result, c, path, all);
		if(!all && t != null)
			return t;
	}
	return null;
}
Element.preparePath = function(path)
{
	rgxTagName = new RegExp("([^.]*)?(?:\.(.*))?");
	path = rgxTagName.exec(path);
	path.tagNames = path[1] == null ? "" : path[1].toUpperCase();
	path.classNames = path[2] == null ? "" : path[2].toUpperCase();
	
	var rgx = new RegExp("[^|]+");
	
	var matches = rgx.Matches(path.tagNames);
	path.tagNames = new Array();
	for(var i = 0; i < matches.length; ++i)
		path.tagNames.push(matches[i][0]);
		
	matches = rgx.Matches(path.classNames);
	path.classNames = new Array();
	for(var i = 0; i < matches.length; ++i)
		path.classNames.push(matches[i][0]);
		
	path.check = Element.checkPath;
	
	return path;	
}
Element.checkPath = function(elem)
{
	var tagOk = this.tagNames.length == 0, 
		classOk = this.classNames.length == 0;
	if(elem.tagName == null) return false;
	var tagName = elem.tagName, className = elem.className.toUpperCase();
	for(var i = 0; i < this.tagNames.length; ++i)
	{
		if(tagName == this.tagNames[i])
		{
			tagOk = true;
			break;
		}
	}
	for(var i = 0; i < this.classNames.length; ++i)
	{
		if(className == this.classNames[i])
		{
			classOk = true;
			break;
		}
	}
	return tagOk && classOk;
}
if(document.createElement("div").contains == null)
{
	Element.prototype.contains = function(child)
	{
		while(child != null && child != this)
			child = child.parentNode;
		return (child == this);
	}
}
function $(id)
{
	return document.getElementById(id);
}
function $$(path, all)
{
	if(all == null) all = false;
	
	path = Element.preparePath(path);
	var tagNames = path.tagNames;
	path.tagNames = new Array();
	
	if(all)
		result = new Array();
	for(var i = 0; i < tagNames.length; ++i)
	{
		var temp = document.getElementsByTagName(tagNames[i]);
		for(var i = 0; i < temp.length; ++i)
		{
			var elem = temp[i];
			if(path.check(elem))
			{
				if(Element.applyAllProperties)
					Element.applyAllProperties(elem);
				if(all)
					result.push(elem);
				else
					return elem;
			}
		}
	}
	if(all)
		return result;
	else
		return null;
}
