/*##makeElement*/
function makeBr(){
	return makeElement({tag:'br'});
}

function makeText(){
	return document.createTextNode(
		reduce(function(acc,x){return acc+(typeof(x)=='string'?x:getText(x))},'',arguments)
	);
}

function makeElement(element){
	element.content = element.content || [];
	if(element.name==undefined)var out = document.createElement(element.tag);
	else{
		try{
			var tmp = '<'+element.tag+' name="'+element.name+'"'+'>',out = document.createElement(tmp);
			if(out.tagName.toLowerCase()!=element.tag || out.name!=element.name)throw('not_created error: '+out.tagName+' '+out.name);
		}catch(e){
			var out = document.createElement(element.tag);
			if(element.name!=undefined)out.setAttribute('name',element.name);
		}
	}
	var content = element.content.reduce(function(acc,x){return acc+(typeof(x)=='string'?x:getText(x))},'');
	if(content.length>0)out.innerHTML = content;
	
	if(element.child!=undefined){
		/*for(var i in element.child){
			if(element.child[i].tagName!=undefined)out.appendChild(element.child[i]);
			else out.appendChild(makeElement(element.child[i]));
		}
		element.child.each(function(ele){
			if(ele.tagName!=undefined)out.appendChild(ele);
			else out.appendChild(makeElement(ele));
		});*/
		element.child.map(function(ele){return ele.tagName?ele:makeElement(ele)}).each(out.appendChild.bind(out));
	}
	['className','id','style','href','src','type','value','rows','cols','title','colspan',
	'method','action','enctype','selected','form'].filter(function(e){return element[e]!=undefined}).
		each(function(e){
			var atr = typeof(element[e])=='string'?element[e]:getText(element[e]);
			if(e=='className')out.setAttribute('class',atr);
			else if(e=='colspan')out.setAttribute('colSpan',atr);
			else out.setAttribute(e,atr);
		});
	
	['click','mouseover','mousemove','mouseout','load','unload',
	'deactivate'].filter(function(e){return element[e]!=undefined}).
		each(function(e){LEM.addEvent(out,e,element[e])});

	return out;
}
/*##makeTable*/
function makeRow(fields){
	var row = document.createElement('tr');
	if(arguments.length==1)fields.each(function(ele){ele.tag='td';row.appendChild(makeElement(ele))});
	else each(function(ele){ele.tag='td';row.appendChild(makeElement(ele))},arguments);
	return row;
}

function makeTable(rows,def){
	if(arguments.length==1)var tab = document.createElement('table');
	else{
		def.tag = 'table';
		var tab = makeElement(def);
	}
	var tbody = document.createElement('tbody');
	tab.appendChild(tbody);
	rows.each(tbody.appendChild.bind(tbody));
	return tab;
}

/*##domQuery*/
function $(){
	if(arguments.length==1){
		var ele = document.getElementById(arguments[0]);
		if(ele && (ele.id==arguments[0]))return ele;
	}
	var out = new Array();
	for(var i=0;i<arguments.length;i++){
		var xs = arguments[i];
		var ele = document.getElementById(xs);
		if(ele && (ele.id==xs)){
			out.push(ele);
			continue;
		}
		var ele = document.getElementsByName(xs);
		for(var j=0;j<ele.length;j++){
			out.push(ele[j]);
		}
		if(ele.length>0)continue;
		var ele = document.getElementsByTagName(xs);
		for(var j=0;j<ele.length;j++){
			out.push(ele[j]);
		}
	}
	return out;
}

function $C2(searchClass,tag,node){
	var p = ([].push)?function(a,b){a.push(b)}:function(a,b){a[a.length]=b};
 	node = node || document;
 	tag = tag || '*';
 
 if(document.evaluate){
  var xpr = document.evaluate([".//",tag,"[contains(concat(' ',@class,' '),' ",searchClass," ')]"].join(''),node, null, 0, null);
  els = new Array();
  while(t=xpr.iterateNext())p(els,t);
  return els;
 }


 var els = node.getElementsByTagName(tag);
 pattern = new RegExp(["(^|\\s)",searchClass,"(\\s|$)"].join(''));
 ce = new Array();

 for(var i=0, max=els.length; i<max; i++)if(pattern.test(els[i].className))p(ce,els[i]);
 return ce;
}

function $T(xml){
	var out = new Array();
	for(var i=1;i<arguments.length;i++){
		var xs = arguments[i];
		var ele = xml.getElementsByTagName(xs);
		for(var j=0;j<ele.length;j++){
			out.push(ele[j]);
		}
	}
	return out;
}

function getText(node){
	if(!node)return '';
	var out='';
	for(var i=0;i<node.childNodes.length;i++){
		if(node.childNodes.item(i).nodeType==3)out+=node.childNodes[i].nodeValue;
	}
	return out;
}

function $TV(xml,node){
	return getText($T(xml,node)[0]);
}

/*##c2v2*/
var $C2v2 = function (className, tag, elm){
	if (document.getElementsByClassName) {
		getElementsByClassName = function (className, tag, elm) {
			elm = elm || document;
			var elements = elm.getElementsByClassName(className),
				nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
				returnElements = [],
				current;
			for(var i=0, il=elements.length; i<il; i+=1){
				current = elements[i];
				if(!nodeName || nodeName.test(current.nodeName)) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	else if (document.evaluate) {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "),
				classesToCheck = "",
				xhtmlNamespace = "http://www.w3.org/1999/xhtml",
				namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
				returnElements = [],
				elements,
				node;
			for(var j=0, jl=classes.length; j<jl; j+=1){
				classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
			}
			try	{
				elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
			}
			catch (e) {
				elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
			}
			while ((node = elements.iterateNext())) {
				returnElements.push(node);
			}
			return returnElements;
		};
	}
	else {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "),
				classesToCheck = [],
				elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
				current,
				returnElements = [],
				match;
			for(var k=0, kl=classes.length; k<kl; k+=1){
				classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
			}
			for(var l=0, ll=elements.length; l<ll; l+=1){
				current = elements[l];
				match = false;
				for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
					match = classesToCheck[m].test(current.className);
					if (!match) {
						break;
					}
				}
				if (match) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	return getElementsByClassName(className, tag, elm);
};
