

var $jsxt = function() {
	var templates = Array.fromObject(arguments);
	var res = {
		"apply": function(node) {
			if(!node)
				return;
			if(typeof node == "string")
				node = document.getElementById(node);
			if(node.documentElement)
				node = node.documentElement;
			var flag = true;
			for(var i=0; i<templates.length; i++) {
				if(templates[i].predicate(node)) {
					flag = templates[i].action.call(res, node);
					break;
				}
			}
			if(flag || flag==undefined) {
				$dom.childNodes(node).foreach(function(v) {
					res.apply(v);
				});
			}
		},
		"transform": function(nd) {
			if(!nd)
				return undefined;
			if(typeof nd == "string")
				nd = document.getElementById(nd);
			if(nd.documentElement)
				nd = nd.documentElement;
			for(var i=0; i<templates.length; i++) {
				if(templates[i].predicate(nd))
					return templates[i].action.call(res, nd);
			}
			return undefined;
		}
	}
	return res;
}

$jsxt.template = function(predicate, fn) {
	return {
		"predicate": predicate,
		"action": fn
	}
}

$jsxt.pTrue = function() {
	return function(v) {
		return true;
	}
}

$jsxt.pFalse = function() {
	return function(v) {
		return false;
	}
}

$jsxt.pNot = function(p) {
	return function(v) {
		return !p(v);
	}
}

$jsxt.pAnd = function() {
	var args = Array.fromObject(arguments);
	return function(v) {
		for(var i=0; i<args.length; i++)
			if(!(args[i])(v))
				return false;
		return true;
	}
}

$jsxt.pOr = function() {
	var args = Array.fromObject(arguments);
	return function(v) {
		for(var i=0; i<args.length; i++)
			if((args[i])(v))
				return true;
		return false;
	}
}

$jsxt.pId = function(s) {
	return function(v) {
		return v.id == s;
	}
}

$jsxt.pClass = function(s) {
	return function(v) {
		if(v.className) {
			return v.className.split(/\s+/).accumulate(false, function(res, v) {
					return res || v==s;
				});
		} else
			return false;
	}
}

$jsxt.pName = function(s) {
	return function(v) {
		return v.nodeName.toUpperCase() == s.toUpperCase();
	}
}

$jsxt.pParent = function(p) {
	return function(v) {
		return v.parentNode && p(v.parentNode);
	}
}

$jsxt.pChild = function(p) {
	return function(v) {
		for(var i in $dom.childNodes(v))
			if(p(i))
				return true;
		return false;
	}
}

