﻿/*
DAPMX core 0.1.7
Copyright 2008,2009 Maxim Sajin <joox@dapmx.org>
Regarding licensing information please refer http://dapmx.org
*/

var isIE=(navigator.appName == 'Microsoft Internet Explorer');
if(!window.onload)window.onload=function(){dapDocument(document.body,daQueryString())}

function xhrExecute(url,form,method,async){
	if(!method)method="get";
	if(!form)form="";
	if(!async)async=false;
	var req=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('Msxml2.XMLHTTP');	
	switch(method.toLowerCase()){
	//	case"soap":
		case"post":
			req.open(method,url,async);
			req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
			req.send(form);
			break;
		case"get":
			req.open(method,url+form,async);
			req.setRequestHeader("Content-Type","text/xml");
			req.send(null);
			break;
	}
	if(req.status==200)
		try{return req.responseXML?req.responseXML.documentElement:req.responseText}
		catch(e){daFail("Problem with URL: ["+url+"]\n"+e.description)}
	return emptyXML;
}

var emptyPath=[""],emptyXML=document.createElement("empty"),E=[],T={},dapx={},
spaces=/\s+/g, leadspace=/^\s+/, tailspace=/\s+$/, splitdigits=/\B(?=(...)*$)/g,
token_sep=" ", step_sep="; ", step_junk=/;\s+(\/\/[^;]*)*\s*;\s/g,
xLFW=/\n\s*/, xWSC=/\s*:/;

var dap={

	pun	:{concat:"",space:" ",comma:",",colon:":",semi:";",dot:".",bar:"|",mesh:"#",star:"*",lf:"\n",lf2:"\n\n"},

	model:{
		daplist	:daL([daList,daProto]),
		dataset	:daL([daList,daHash]),
		library	:daL([daHash,daList,daProto]),
		config	:daL([daHash])
	},

	convert	:{
		""	:function(value){return String(value)},
		
		esc	:function(value){return escape(value)},		/// escape
		usc	:function(value){return unescape(value)},	/// unescape
		pun	:function(value){return dap.pun[value]},
				
		"?"	:function(bool){return bool?true:false},	/// test
		"!"	:function(bool){return bool?false:true},	/// test inverse
		"#"	:function(bool){return bool?"+":"-"},		/// test as +/-
		
		"+?":function(num){return parseFloat(num)>0},	/// test positive
		"-?":function(num){return parseFloat(num)<0},	/// test negative
		"0?":function(num){return parseFloat(num)==0},	/// test zero
		
		"+"	:function(num){return (num=parseFloat(num))?String(Math.abs(num)):""},	/// abs
		"-"	:function(num){return (num=parseFloat(num))?String(-num):""},			/// neg
		"~"	:function(num){return (num=parseFloat(num))?(num>0?"+":"-"):"0"},		/// sgn
		
		count:function(ds){if(ds instanceof Array && ds.length>0)return ds.length},	/// rowset length
		
		csv	:function(value){return daSplit(value,",")},	/// x1,x2,x3 (comma-separated values)
		bar	:function(value){return daSplit(value,"|")},	/// x1|x2|x3 (bar-separated values)
		nvp	:function(value){return daSplit(daSplit(value,";"),":")},	/// x1:y1:z1;xN:yN:zN (named after "name:value"-pairs)
		lfc	:function(cdata){return daSplit(daSplit(daTrim(cdata),xLFW),xWSC)}, /// linefeed-colon
			
		"#get"	:function(url){return xhrExecute(url,null,"get")},					/// raw XML
		"#js"	:function(url){try{return eval(xhrExecute(url,null,"get"))}catch(e){fail("Bad js: "+url+"\n"+e)}},		/// JSON, or any other javascript
		"#cfg"	:function(url){return daModel(xhrExecute(url),dap.model.config)},	/// XML as a tree
		"#dat"	:function(url){return daModel(xhrExecute(url),dap.model.dataset)},	/// XML as a rowset
		"#lib"	:function(url){	/// XML as dap extension library
					var xml=xhrExecute(url),dapns=xml.nodeName,lib=daModel(xml,dap.model.library),x;
					xml.ownerDocument.documentElement.setAttribute("dapns",dapns);
					if(lib[""])	/// root's CDATA section of the lib is eval'd, the result is integrated into dap namespace
						try{for(var i in x=eval(lib[""]))if(dap[i])dap[i][dapns]=x[i];}catch(e){daFail("problem with lib: "+url+"\n"+e)}
					return lib;
				}
	},
	
	flatten	:{
		"void"	:function(feed){},
		"" 		:function(feed){var d={};for(var i in feed)if(a=feed[i].tag)d[a]=feed[i].value;return d},	/// flat datum {@a:v1,@b:v2}

		"+"		:function(feed){var sum=0;for(var i in feed)sum+=parseFloat(feed[i].value);return String(sum)},
		"-"		:function(feed){var sub=parseFloat(feed[0].value)*2;for(var i in feed)sub-=parseFloat(feed[i].value);return String(sub)},

		"?"		:function(feed){for(var i in feed)if(feed[i].value)return feed[i].value;return false},	/// first non-empty
		"!"		:function(feed){for(var i in feed)if(!feed[i].value)return true; return false},			/// succeeds if empty token found

		"?@"	:function(feed){for(var i in feed)if(feed[i].value==feed[i].tag)return true;return false},	/// any match
		"!@"	:function(feed){for(var i in feed)if(feed[i].value!=feed[i].tag)return false;return true},	/// all match
		
		eq		:function(feed){for(var i in feed)if(feed[i].value!=feed[0].value)return false;return true},
		dsc		:function(feed){var a=parseInt(feed[0].value);for(var i in feed)if(a<(a=parseInt(feed[i].value)))return false;return true},
		asc		:function(feed){var a=parseInt(feed[0].value);for(var i in feed)if(a>(a=parseInt(feed[i].value)))return false;return true},
		
		concat	:function(feed){var string="";for(var i in feed)if(feed[i].value)string+=feed[i].value;return string},
		space	:function(feed){return daConcat(feed," ")},
		url		:function(feed){var url="",a,n;for(var i in feed)if(a=feed[i].value)url+=(n=feed[i].tag)?"&"+n+"="+encodeURI(a):a;return url},//
		
		csv	:function(feed){return daConcat(feed,",")},	/// x1,x2,x3 (comma-separated values)
		bar	:function(feed){return daConcat(feed,"|")},	/// x1|x2|x3 (bar-separated values)
		nvp	:function(feed){var value="";for(var i=0;i<feed.length;value+=feed[i].alias+":"+feed[i].value+";");return value},	/// alias:value;alias:value (named after "name:value"-pairs)
		
		/// selectors
				
		"@"	:function(feed){return daConvey(feed,dap.conveyor["@"],{out:[]}).out},
		"#"	:function(feed){return daConvey(feed,dap.conveyor["#"],{out:[]}).out}
	},

	mapper	:{ /// see dap mappers reference at http://dapmx.org/0.1.7/#mappers
		""	:function(value,alias,node,D){D[alias]=value},
		"!"	:function(value,alias,node,D,$){daPhase.d(node,value,$)},

		"+"	:function(value,alias,node,D){D[alias]=D[alias]?value||true:false},
		"-"	:function(value,alias,node,D){D[alias]=D[alias]?false:value||true},
		"~"	:function(value,alias,node,D){var a=D[alias];D[alias]=(!a)?(value||true):(!value)?(!a):(a==value)?false:a},

		"?"	:function(value,alias,node){if(alias)return(value!=alias)&&E;else return(!value)&&E},
		attr:function(value,alias,node){node.setAttribute(alias,value)},
		ui	:function(value,alias,node){daActivateNode(value,alias,node)},
		
		own	:function(value,alias,node,D){D[alias]=D[alias]||""},
		"%"	:function(value,alias,node,D){if(alias)value=daMap(value,alias.split(","));for(var i in value)D[i]=value[i]},
		"^"	:function(value,alias,node,D){if(value)D[alias]=da15(node.$.D,value)},
		"*"	:function(value,alias,node,D){return daMapGrid((value instanceof Array)?value:[value],alias)},
		"_"	:function(feed){return E}
	},
	
	conveyor:{
	
		"@":{///select by value
			"!"	:function(bin,value,alias){bin.out.push(value)},
			$	:function(bin,value,alias){if(alias==bin.$)bin.out.push(value)}
		},
		
		"#":{///select by name
			"?"	:function(bin,value){if(bin.$[value])bin.out.push(bin.$[value])},
			$	:function(bin,value){bin.out.push(bin.$[value]||"")}
		}
		
	}
	
};

//conveyor gear
function daConvey(feed,conveyor,subj){
	var op,tag,value;
	for(var i in feed)if((op=feed[i])&&(value=op.value))
		if(tag=op.tag)
			if(op=conveyor[tag]||conveyor.$)subj=op(subj,value,tag)||subj;
			else fail("unknown op: "+tag+":"+value);
		else subj.$=value;
	return subj;
};

//node creation shortcuts
function newElem(e){return document.createElement(e)};
function newText(t){return document.createTextNode(t)};
function newElemText(e,t){var e=newElem(e);e.appendChild(newText(t));return e};
function newStub(c){return document.createComment(c)};

newElemNS=isIE?
function(ns,e){return document.createElement(e)}: // I hate IE
function(ns,e){return document.createElementNS(ns,e)};

//ui nodes highlight
function enstyle(node,cls){if(node.className)node.className+=" "+cls;else node.className=cls;return node};
function destyle(node,cls){if(node.className)node.className=node.className.replace(new RegExp("\\s*"+cls,"g"),"");return node};
function daOver(e){evStop(e);enstyle(this,"over")}
function daOut(e) {evStop(e);destyle(this,"over")}
function daEvent(e){evStop(e);daPhase.u(this);return true};
function evStop(e){if(e&&e.stopPropagation)e.stopPropagation();else event.cancelBubble=true};
var daActivateNode=document.addEventListener?function(handler,event,node){
		enstyle(node,"ui");
		node.addEventListener("mouseover",daOver,false);
		node.addEventListener("mouseout",daOut,false);
		node.addEventListener(event||"click",handler?da4(da2(handler),window):daEvent,false);
}	:	function(handler,event,node){ //I hate IE
		enstyle(node,"ui");
		node.onmouseover=daOver;
		node.onmouseout=daOut;
		node["on"+(event||"click")]=handler?da4(da2(handler),window):daEvent;
}

//string works
function daConcat(feed,separator){
	var a,out=[];
	for(var i in feed)if(a=feed[i].value)out.push(a);
	return out.join(dap.pun[separator]||separator);
};
function daSplit(value,separator){
	if(value instanceof Array)for(var i in value)value[i]=daSplit(value[i],separator);
	else if(value&&value.split)value=value.split(separator);
	return value;
};
function daTrim(str){
	if(str&&str.replace)return str.replace(leadspace,"").replace(tailspace,"");
};
function daSplitDigits(n){
	return String(n).replace(splitdigits," ");
};

//datum models
function daL(a){for(var i=a.length,L=[a[--i]];i-->0;L=[a[i],L]);return L};
function daModel(node,model){return model[0](node,model[1]||model)};

function daProto(node){
	return {markup:node};
};
function daList(node,model){
	var list=[],m0,m1;if(model)m0=model[0],m1=model[1]||model;
	for(var n=node.childNodes,i=0,a;i<n.length;i++)switch(n[i].nodeType){
		case 1:list.push(m0?m0(n[i],m1):n[i]);break;
		case 3:case 4:if((a=n[i].nodeValue).replace(spaces,""))list.push(a);break;
	}return list;
};

function daHash(node,model){
	var hash={},t=null,text="",m0,m1;if(model)m0=model[0],m1=model[1]||model;
	for(var a=node.attributes,i=0;i<a.length;i++)hash[t=a[i].nodeName.toLowerCase()]=a[i].nodeValue;
	for(var n=node.childNodes,i=0;i<n.length;i++)switch(n[i].nodeType){
		case 1:
			t=n[i].nodeName.toLowerCase(),a=m0?m0(n[i],m1):n[i]
			if(hash[t])((hash[t]instanceof Array)?hash[t]:(hash[t]=[hash[t]])).push(a);
			else hash[t]=a;
			break;
		case 3:case 4:if((a=n[i].nodeValue).replace(spaces,""))text+=a;break;
	}if(t)hash[""]=text;else return text;
	return hash;
};

//rowset column mapping
function daMap(data,columns){
	var entry={};
	if(data instanceof Array)for(var i=data.length;i-->0;entry[columns[i]]=data[i]);
	else entry[columns[0]]=data;
	return entry;
};
function daMapGrid(grid,alias){
	if(!alias)return grid;
	var rowset=[];
	var columns=alias.split(",");
	for(var row=0; row<grid.length; row++ )rowset.push(daMap(grid[row],columns));
	return rowset;
};

//dap launch
function dapDocument(root,data){
	root.parentNode.$={};
	root.parentNode.replaceChild(da0(daProto(root),{S:[{}],D:[data]}),root);
}
function daQueryString(){
	var href=location.href.split("#"),an=href[1],qs=href[0].split("?")[1];
	var nv,hash={};
	if(qs)for(var i in qs=qs.split("&"))nv=qs[i].split("="),hash[nv[0]]=decodeURIComponent(nv[1]);
	if(an)for(var i in an=an.split(";"))nv=an[i].split(":"),hash[nv[0]]=decodeURI(nv[1]);
	return hash;
};
function daFail(reason,node){throw new Error("dap error <"+(node&&node.nodeName)+"> :: "+reason,false,0)}


//dap engine (compressed)
function da1(a){return a.split(",")};function da2(a,b){if(!a)return emptyPath;if(a=="..")return[b];var c=a.split(".");if(!c[0])c[0]=b||"";return c.reverse()};function da3(a,b){var c=da1(a),i=c.length;while(i-->0)c[i]=da2(c[i],b);return c};function da4(a,o){var i=a.length;while(o&&(i-->0))o=o[a[i]];return o};function da5(b,c){var i=b.length,a;while(i-->0)if(a=da4(b[i],c))b[i]=a;else return;return b};function da6(a,b){if(a&&b)for(var i in a)if(a[i]==b[i])return true;return};function da7(a){var n=newStub(a.nodeName);n.P=a.P;n.$=a.$;n.dn=a.dn;return n};function da8(a,b){if(da6(b,a.dn)){try{a.parentNode.replaceChild(da0(a.P,a.$),a)}catch(e){if(!e.lineNumber)daFail(e.message)}}else if(da6(b,a.$.S[0]))for(var i=0,nodes=a.childNodes,n;i<nodes.length;i++)if((n=nodes[i])&&n.$)da8(n,b)};function da0(P,$){if(P.nodeType)return P;if(!P.markup)return newText(P);if(!P.rules)da9(P);var a=P.markup.cloneNode(false);a.$=$,a.P=P;if(da13(a,P.rules.d)&&!a.childNodes.length)return da7(a);else return a};function da9(P){P.content=daModel(P.markup,dap.model.daplist);P.rules=da12s(P.markup,{d:P.content.length?da19:null,u:null});P.markup=da10(P.markup)};function da10(b){if(b.ownerDocument==document)return b;var n=newElemNS(b.namespaceURI,b.nodeName);for(var a=b.attributes,i=0;i<a.length;i++)n.setAttribute(a[i].nodeName,a[i].nodeValue);if(isIE&&(a=b.getAttribute("class")))n.className=a;return n};function da12s(b,c){var d=b.ownerDocument.documentElement.getAttribute("dapns"),a;for(var i in c)if(a=b.getAttribute(i))c[i]=da12(a,d,c[i]),b.removeAttribute(i);return c};function da12(b,c,R){if(!b)return R;var d=b.replace(step_junk,step_sep).split(step_sep),a;for(var s=d.length;s-->0;R=[e,R,d[s]])if(a=d[s]){var e=[];var f=a.split(token_sep);var g;for(var t=f.length;t-->0;e.push(g))if(a=f[t]){g={};if((a=a.split("=")).length>1)g.value=a[1];if((a=a[0].split("@")).length>1)g.alias=a[1];if((a=a[0].split(":")).length>1)g.convert=da5(da3(a[1],c),dap.convert)||daFail("missing converter "+a[1]+" :: "+b);if((a=a[0].split("$"))[0])g.field=da2(a[0],c);if(a.length>1)g.local=a[1]?da2(a[1]):[g.field[0]]||emptyPath;if(g.alias=="")g.alias=null;else if(!g.alias&&(a=g.local||(t&&g.field)))g.alias=a[0]}else g=null;if(g){if(e.length<2)e.push(T),e.reverse();if(g.value!=null)g.value=da4(da2(g.value,c),dap.flatten)||daFail("missing flattener "+g.value+" :: "+b);g.field=g.field?da4(g.field,dap.mapper)||daFail("missing mapper :"+g.field+" :: "+b):dap.mapper[""]}}else e=null;return R};function da13(b,R,c,$){if(!R)return;if(!$)$=b.$;var S=$.S,D=$.D,D0=D[0],nS,step;var d=true;if(D0 instanceof Array){for(var i=0;i<D0.length;i++)da13(b,R,c,{S:S,D:[D0[i],D]});return!i&&d}else while(R)if(step=R[0]){var e=[],i=step.length,a;var f=step[--i];for(var g=null;i-->0;e.push(g))if(g=step[i]){var h=g.value;if(a=g.field)h=da16(D,a,null,0)||h||"";if(a=g.local)if(h!=null)da17((c||nS)?S:S=($=b.$={S:[nS={},S],D:$.D}).S,a,c,h);else h=(da16(S,a,!c&&(b.dn||(b.dn={})),1)||daFail(a+" unaccessible :: "+R[2],b))[a[0]];if(a=g.convert)h=da14(h,a);g={tag:g.alias,value:h}}else g={value:b.P.content};R=R[1];if(f){var j=null,leave=true;var k=(a=f.local)?da17((c||nS)?S:S=($=b.$={S:[nS={},S],D:$.D}).S,a,c):D0;if(f.value)e=[{value:f.value(e)}];if(f.field)for(var i=0;i<e.length;i++)if(j=f.field(da14(e[i].value,f.convert),e[i].tag||f.alias,b,k,$))d=(!j.length||da13(b,R,c,{S:S,D:[j,D]}))&&d;else leave=false;if(leave)return d}}else return c};function da14(a,b){if(b)for(var i=b.length;i-->0;)a=b[i](a);return a};function da15($,a){if(!$)return;var b;if($[0]&&((b=$[0][a])!=null))return b;if(b=da15($[1],a))return $[0][a]=b};function da16($,a,b,c){var i=a.length;var e=a[--i],d=da15($,e);if(!d)return;if(b)b[e]=d;while(d&&(i-->c))d=d[a[i]];return d};function da17($,b,c,e){var i=b.length;var f=b[--i],d=c?(da15($,f)):$[0][f],a;if(!d)d=$[0][f]={};for(a=d;i-->0;a=a[b[i]]||(a[b[i]]={}));if(a[b[0]]!=e||e==null){if(e!=null)a[b[0]]=e;if(c)c[f]=d}return a};function da18(a,b,c){for(var i=b.length,tag=b[--i];i-->0;a=a[b[i]]||(a[b[i]]={}));a[tag]=c};var daPhase={d:function(a,P,$){if(!P)return;if(P instanceof Array)for(var i=0;i<P.length;daPhase.d(a,P[i++],$));else a.appendChild(da0(P,$))},u:function(b){for(var c=b,S,nS,a,n,ch={};(n=b.parentNode).$;b=n){if(!a)a=da13(b,b.P.rules.u,ch);if(n.$.S!=S&&da6(ch,(S=b.$.S)[0]))c=b}da8(c,ch)}},da19=da12("! ","",false);