if(!com){var com=new Object();}
if(typeof com.cgo=="undefined"){com.cgo=new Object();}
if(typeof com.cgo.utils=="undefined"){com.cgo.utils=new Object();}
if(typeof com.cgo.utils.DomUtils=="undefined"){com.cgo.utils.DomUtils=new Object();}

com.cgo.utils.DomUtils = function(){
}
/**
 * Injector{tag_name:String, attribute_maps:Object)
 *
*/
com.cgo.utils.DomUtils.createAttributesInjector = function(tag_name, attribute_maps)
{
	return {tag_name:tag_name, attribute_maps:attribute_maps};
}
com.cgo.utils.DomUtils.createAttributeMap = function (attribute_name, map)
{
	return {attribute_name:attribute_name, map:map};
}
com.cgo.utils.DomUtils.getDefaultAttributes = function (allowed_attributes)
{
	var isInArray = com.cgo.utils.DomUtils.isInArray;
	var default_attributes = ["id", "src", "href", "class"];
	for(var i=0; i<allowed_attributes.length; i++){
		var attribute = allowed_attributes[i];
		if(!isInArray(attribute, default_attributes)){
			default_attributes.push(attribute);
		}
	}
	return default_attributes;
}
//TODO: provide full support for attributes
com.cgo.utils.DomUtils.innerHTML = function (src_obj, attributes_injectors, allowed_attributes, tags_to_ignore)
{
	var InnerHTML = com.cgo.utils.DomUtils.innerHTML;
	var getNodeAttributes = com.cgo.utils.DomUtils.getNodeAttributes;
	var getInjectedAttributes = com.cgo.utils.DomUtils.getInjectedAttributes;
	var removeComments = com.cgo.utils.DomUtils.removeComments;
	var str_out='';

	var children=src_obj.childNodes;

	for (var i=children.length-1; i>=0; i--)
	{
		var c_node=children[i];


		if(c_node.nodeType==1) // element
		{
			var tag_name = c_node.tagName.toLowerCase();
			if( !(tags_to_ignore != null && com.cgo.utils.DomUtils.isInArray(tag_name, tags_to_ignore))){
				attr_str = getNodeAttributes(c_node, allowed_attributes);
				if (attributes_injectors != null){
					var id = com.cgo.utils.DomUtils.getNodeAttribute(c_node, "id");
					if(id != null){
						var attr_inj_str = getInjectedAttributes(tag_name, id, attributes_injectors);
						attr_str += attr_inj_str;
					}
				}
				str_out = '<' + tag_name + attr_str + '>' + InnerHTML(c_node, attributes_injectors, allowed_attributes, tags_to_ignore) + '</' + tag_name + '>' + str_out;
			}
		}else if(c_node.nodeType==8) // comment
		{
		}else{// 3 = text
			str_out = c_node.nodeValue + str_out;
		}
	}

	str_out = str_out.replace(/\u2018/g, "'");
    str_out = str_out.replace(/\u2019/g, "'");
    str_out = str_out.replace(/\u201c/g, '"');
    str_out = str_out.replace(/\u201d/g, '"');
    str_out = str_out.replace(/\u2013/g, '-');
    str_out = str_out.replace(/\u2014/g, '--');
    str_out = str_out.replace(/\u2026/g, '...');
    str_out = str_out.replace(/\uFFFD/g, "'");
	str_out = str_out.replace(/\+/g, "&#43;");

	return str_out;
}

com.cgo.utils.DomUtils.getInjectorByTagName = function(tag_name, attributes_injectors)
{
	for(var i=0; i<attributes_injectors.length; i++)
	{
		var injector = attributes_injectors[i];
		if(injector.tag_name.toLowerCase() == tag_name.toLowerCase()) return injector;
	}
	return null;
}

com.cgo.utils.DomUtils.getInjectedAttributes = function(tag_name, id, attributes_injectors)
{
	var injector = com.cgo.utils.DomUtils.getInjectorByTagName(tag_name, attributes_injectors);
	if(injector == null) return "";
	var res = "";
	var attribute_maps = injector.attribute_maps;
	for(var i=0; i<attribute_maps.length; i++){
		var attribute_map = attribute_maps[i];
		var attribute_name = attribute_map.attribute_name;
		var attribute_value = attribute_map.map[id];
		if(attribute_value != null)	res += " " + attribute_name + "=\"" + attribute_value + "\"";
	}
	return res;
}

com.cgo.utils.DomUtils.getNodeAttribute = function($node, $attribute)
{
	var attributes = com.cgo.utils.DomUtils.getNodeAttributesArray($node);
	for(var i=0; i<attributes.length; i++){
		var attribute = attributes[i];
		if(attribute.nodeName.toLowerCase() == $attribute.toLowerCase()) return attribute.nodeValue;
	}
	return null;
}

com.cgo.utils.DomUtils.getNodeAttributesArray = function($node)
{
	return $node.attributes ? $node.attributes : $node.getAttributes();
}

com.cgo.utils.DomUtils.getNodeAttributes = function($node, allowed_attributes){
	var isInArray = com.cgo.utils.DomUtils.isInArray;
	var attr_node;
	var attr_name;
	var res = "";
	if (allowed_attributes != null && $node.getAttribute != null) {
		// optimize performance, especially on IE since each dom element has an incredible amount of attributes
		for (var i = 0; i < allowed_attributes.length; i++) {
			attr_name = allowed_attributes[i];
			attr_node = $node.getAttribute(attr_name);
			// IE uses className instead of class
			if(attr_node == null && attr_name == "class")
				attr_node = $node.getAttribute("className");
			if (attr_node != null){
				res += " " + attr_name + "=\"" + attr_node + "\"";
			}
		}
	}
	else {
		var arr = com.cgo.utils.DomUtils.getNodeAttributesArray($node);
		for (var j = 0; j < arr.length; j++) {
			attr_node = arr[j];
			attr_name = attr_node.nodeName.toLowerCase();
			if (allowed_attributes != null) {
				if (isInArray(attr_name, allowed_attributes)) {
					res += " " + attr_name + "=\"" + attr_node.nodeValue + "\"";
				}
			}
			else {
				res += " " + attr_name + "=\"" + attr_node.nodeValue + "\"";
			}
		}
	}
	return res;
}
com.cgo.utils.DomUtils.isInArray = function ($element, $array){
	for(var i=0; i<$array.length; i++){
		if($array[i] == $element) return true;
	}
	return false;
}
