// ==============================================================
// XmlDataSource
// ==============================================================
function XmlDataSource(empty, xmlObject) {
	var xds = this;
	if (xmlObject == null) {
		xds.xmlObject = new ActiveXObject(ctxApp.xmlParser);
	}
	else {
		xds.xmlObject = xmlObject;
		empty = false;
	}
	xds.xmlObject.setProperty("SelectionLanguage", "XPath");
	xds.sendOk = false;

	// metody
	xds.initEPromakDocument   = _xdsInitEPromakDocument;
	xds.setAction             = _xdsSetAction;
	xds.getAction             = _xdsGetAction;
	xds.appendDatasetNode     = _xdsAppendDatasetNode;
	xds.appendRecord          = _xdsAppendRecord;
	xds.getDatasetNode        = _xdsGetDatasetNode;
	xds.sendData              = _xdsSendData;
	xds.getData               = _xdsGetData;
	xds.httpRequest           = _xdsHttpRequest;
	xds.restoreOrgXml         = _xdsRestoreOrgXml;

	xds.appendRootDatasetNode = _xdsAppendRootDatasetNode;
	xds.createFilteredXml     = _xdsCreateFilteredXml;
	xds.xmlPathInfoAction     = _xdsXmlPathInfoAction;
	xds.xmlAction             = _xdsXmlAction;
	xds.xmlAppAction          = _xdsXmlAppAction;
	xds.loginAction           = _xdsLoginAction;
	xds.signedChallengeAction = _xdsSignedChallengeAction;
	xds.rdfAction             = _xdsRdfAction
	xds.demonAction = _xdsDemonAction
	
	xds.isTask2SignatureVerify     = _xdsIsTask2SignatureVerify;
	xds.isSignedAck           = _xdsIsSignedAck;
	// inicjalizacja
	if (empty == null || empty) {
		xds.initEPromakDocument();
	}
}

function _xdsInitEPromakDocument() {
	var xds = this;
	var rootNode = xds.xmlObject.appendChild(xds.xmlObject.createElement("EPROMAK"));
	// utworzenie nod-a błędów
	var errNode = rootNode.appendChild(xds.xmlObject.createElement("ERR"));
	errNode.setAttribute("code",0);
	// ustawienie akcji
	var actNode = rootNode.appendChild(xds.xmlObject.createElement("ACT"));
	actNode.setAttribute("name", "");
	// ustawienie kontekstu
	var actNode = rootNode.appendChild(xds.xmlObject.createElement("CTX"));
}

function _xdsGetDatasetNode(setName) {
	var xds = this;
	var argv = _xdsGetDatasetNode.arguments;
	var argc = argv.length;
	if (argc < 1) {
		alert("Zbyt mała liczba parametrów wywołania funkcji _xdsGetDatasetNode");
	}
	else {
		var path="/EPROMAK/dataset[@name=\""+setName+"\"]";
		for (var i = 1; i < argc; i++) {
			path=path + "/dataset[@name=\"" + argv[i] + "\"]";
		}
		return xds.xmlObject.selectSingleNode(path);
	}
}

function _xdsSetAction(action) {
	var xds = this;
	xds.xmlObject.selectSingleNode("/EPROMAK/ACT").setAttribute("name", action);
}

function _xdsGetAction() {
	var xds = this;
	var retAction = "";
	var nd = xds.xmlObject.selectSingleNode("/EPROMAK/ACT/@name");
	if(nd) {
		retAction = nd.nodeValue;
	}
	return retAction;
}

function _xdsAppendRootDatasetNode(setName) {
	var xds = this;
	var argv = _xdsAppendRootDatasetNode.arguments;
	var argc = argv.length;
	var datasetNode = xds.xmlObject.createElement("dataset");
	datasetNode.setAttribute("name", setName);

	for (var i = 1; i < argc; i++) {
		var fieldAndValue = argv[i];
		var attrValue;
		var attrName = fieldAndValue[0];
		if (attrName == null) {
			alert("Brak wartości parametru w metodzie appendDatasetNode");
			break;
		}
		else {
			attrValue = fieldAndValue[1];
		}
		datasetNode.setAttribute(attrName, attrValue);
	}

	xds.xmlObject.documentElement.appendChild(datasetNode);
	return datasetNode;
}

function _xdsAppendDatasetNode(Node, setName) {
	var xds = this;
	var argv = _xdsAppendDatasetNode.arguments;
	var argc = argv.length;
	var datasetNode = Node.ownerDocument.createElement("dataset");
	datasetNode.setAttribute("name", setName);

	for (var i = 2; i < argc; i++) {
		var fieldAndValue = argv[i];
		var attrValue;
		var attrName = fieldAndValue[0];
		if (attrName == null) {
			alert("Brak wartości parametru w metodzie appendDatasetNode");
			break;
		}
		else {
			attrValue = fieldAndValue[1];
		}
		datasetNode.setAttribute(attrName, attrValue);
	}

	Node.appendChild(datasetNode);
	return datasetNode;
}

function _xdsAppendRecord(Node) {
	var xds = this;
	var recordName = Node.getAttribute("name");
	var argv = _xdsAppendRecord.arguments;
	var argc = argv.length;
	if (argc < 2) {
		alert("Zbyt mała liczba parametrów wywołania metody appendRecord");
	}
	else {
		var recordNode = Node.ownerDocument.createElement(recordName);
		Node.appendChild(recordNode);
		for (var i = 1; i < argc; i++) {
			var fieldAndValue = argv[i];
			var attrValue;
			var attrName = fieldAndValue[0];
			if (attrName == null) {
				attrName = argv[i];
				attrValue = "";
			}
			else {
				attrValue = fieldAndValue[1];
			}
			try {
			recordNode.setAttribute(attrName, attrValue);
			}
			catch (e) {
				alert("Błąd dodawania rekordu: \n" + recordNode.xml + "\n" +
					attrName + " = " + attrValue);
			}
		}
		return recordNode;
	}
	return null;
}

function _xdsXmlAction(action, path, appName, asyncHandle ) {
	var xds = this;
	xds.setAction(action);
	var stsCard = true;
	// ewentualne tworzenie podpisu elektronicznego
	if(ctxApp.userData.isUser2SignatureVerify()) {
		if(xds.isTask2SignatureVerify(action)) {
			stsCard = ctxApp.signMngr.signDocument(xds.xmlObject);
		}
	}
	
	if(!stsCard) {
		return new XmlDataSource();
	}
	else {
		if (path == null) {
			path = "";
		}
		else {
			path = "/" + path;
		}
		return xds.sendData("/epromak/dbwrite" + path, appName, asyncHandle);
	}		
}

function _xdsSignedChallengeAction(action, appName) {
	var xds = this;
	xds.setAction(action);
	var stsCard = true;
	stsCard = ctxApp.signMngr.signDocument(xds.xmlObject);
	if(!stsCard) {
		return new XmlDataSource();
	}
	else {
		return xds.sendData("/epromak/signedchallenge", appName);
	}
}

function _xdsRdfAction(action, path, asyncHandle) {
	var xds = this;
	xds.setAction(action);
	if (path == null) {
		path = "";
	}
	else {
		path = "/" + path;
	}
	return xds.sendData("/epromak/notowbuf" + path, "epmntw", asyncHandle);
}

function _xdsXmlAppAction(action, path, appName, asyncHandle) {
	var xds = this;
	xds.setAction(action);
	if (path == null) {
		path = "";
	}
	else {
		path = "/" + path;
	}
	return xds.sendData("/epromak/appact" + path, appName, asyncHandle);
}

function _xdsLoginAction(action, appName) {
	var xds = this;
	xds.setAction(action);
	return xds.sendData("/epromak/logowanie", appName, null); 
}


function _xdsXmlPathInfoAction(pathInfo, action, appName) {
	var xds = this;
	xds.setAction(action);
	return xds.sendData("/epromak/" + pathInfo, appName, null); 
}



function _xdsDemonAction(action, appName) {
	var xds = this;
	xds.setAction(action);
	return xds.sendData("/epromak/adm", appName);
}

function _xdsSendData(pathInfo,appName,asyncHandle) {
	var xds = this;
	return this.httpRequest("POST", pathInfo,appName,asyncHandle);
}

function _xdsGetData(dataInfo, appName, asyncHandle) {
	var xds = this;
	return this.httpRequest("GET", "/epromak/getdata/" + dataInfo, appName, asyncHandle);
}

function _xdsHttpRequest(method, pathInfo,appName,asyncHandle) {
	
	var xds = this;
	var xmlOutSource = null;
	var xmlHTTP = new ActiveXObject("MSXML2.XMLHTTP.3.0");
	var e;
	if (appName == null) appName = ctxApp.appName;
	var url = appName;
	if (url != "") { url = "/" + url; }
	url += pathInfo;
	xds.sendOk = true;

	if (asyncHandle == null) {
		ctxApp.frameset.status = "Trwa ładowanie danych ...";
	}
	if (asyncHandle != null) {
		xmlHTTP.onreadystatechange = asyncHandle;
	}
	try {
		xmlHTTP.open(method, url, (asyncHandle != null));
		
		var ctxNode = xds.xmlObject.selectSingleNode("/EPROMAK/CTX");
		try	{
			if(ctxApp.userData.login)	{
				ctxNode.setAttribute("login", ctxApp.userData.login);
				ctxNode.setAttribute("sessnum", ctxApp.userData.sessnum);
				if (appName == "epmntw") {
					xmlHTTP.setRequestHeader("login", ctxApp.userData.login);
					xmlHTTP.setRequestHeader("sessnum", ctxApp.userData.sessnum);
				}
			}
			else {
				ctxNode.setAttribute("login", "");
				ctxNode.setAttribute("sessnum", "");
			}
		}
		catch(e) {
			ctxNode.setAttribute("login", "");
			ctxNode.setAttribute("sessnum", "");
		}
		if (method == "POST") {
			xmlHTTP.send(xds.xmlObject.xml);
		}
		else {
			xmlHTTP.send();
		}
	}
	catch (e) {
		if (asyncHandle != null) {
				ctxApp.frameset.status = ctxApp.frameset.defaultStatus;
				return null;
		}
	}
	if (asyncHandle != null) {
		ctxApp.frameset.status = ctxApp.frameset.defaultStatus;
		return xmlHTTP;
	}
	
	if (xmlHTTP.status != 200) {
		ctxApp.errDesc = "HTTP status: " + xmlHTTP.status + " " + xmlHTTP.statusText;
		xds.sendOk = false;
	}
	else {
		ctxApp.errDesc = "Odpowiedź=" + xmlHTTP.responseText;
		xmlOutSource = new XmlDataSource(false, xmlHTTP.responseXML);
		xmlOutSource.xmlObject.async = false;
		ctxApp.setError(0, "", "");
		if (xmlOutSource.xmlObject == null || xmlOutSource.xmlObject.xml == "") {
			var respStr = xmlHTTP.responseText;
			var errLoc = respStr.indexOf('!ERR:');
			if (errLoc == -1) {
				ctxApp.errDesc = "Blad=" + xmlHTTP.responseText;
			}
			else {
				errLoc = errLoc + 5;
				respStr = respStr.substring(errLoc);
				errLoc = respStr.indexOf(";");
				respStr = respStr.substring(0, errLoc);
				ctxApp.errDesc = respStr;
			}
			xds.sendOk = false;
		}
		if (! xds.sendOk) {
			window.alert(ctxApp.errDesc);
		}
		else {
			var errAttribs = xmlOutSource.xmlObject.selectSingleNode("//ERR").attributes
	
			var code = errAttribs.getNamedItem("code")
			var klasa = errAttribs.getNamedItem("class")
			var desc = errAttribs.getNamedItem("desc")
			ctxApp.setError(
				( code != null ? code.nodeValue : 0 ),
				( klasa != null ? klasa.nodeValue : "" ),
				( desc != null ? desc.nodeValue : "" ))
	
			if (ctxApp.errCode != 0) {
				xds.sendOk = false;
				if (ctxApp.errClass == "W") {
					window.alert(ctxApp.errDesc);
				}
				if (ctxApp.errClass == "R") {
					if (window.dialogArguments != null) {
						window.close();
					}
					ctxApp.logout(false);
				}
			}
		}
	}
	xmlHTTP = null
	ctxApp.frameset.status = ctxApp.frameset.defaultStatus;
	return xmlOutSource;
}

function _xdsCreateFilteredXml(dsNameIn, dsNameOut, selectCond, sortCond) {
	var xds = this;
	var xslXml = new ActiveXObject(ctxApp.xmlParser);
	xslXml.setProperty("SelectionLanguage", "XPath");
	
	if (dsNameOut == null || dsNameOut == "") {
		dsNameOut = dsNameIn;
	}
	if (selectCond == null) {
		selectCond = "";
	}
	var xslStr = '<?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >' +
	  '<xsl:template match="/"><EPROMAK><ERR/><ACT/><dataset name="' + dsNameOut + '"><xsl:for-each select="EPROMAK/dataset/' + dsNameIn + selectCond + '">';
	if (sortCond != null) {
		var sortOrder = "ascending";
		var sortDataType = "text";
		if (sortCond[0] == null) { 
			sortCond = "@" + sortCond;
		}
		else {
			if (sortCond[0][0] != null) {
				var ile = sortCond.length;
				for (var j = 0; j < ile; j++) {
					var sortCnd = sortCond[j][0];
					sortOrder = sortCond[j][1];
					sortDataType = sortCond[j][2];
					if (j < ile - 1) {
						xslStr += '<xsl:sort select="' + sortCnd + '" order="' + sortOrder + '" data-type="' + sortDataType + '"/>';
					}
					else {
						sortCond = sortCnd;
					}
				}
			}
			else {		
				if (sortCond[1]!=null) {
					sortOrder = sortCond[1];
				}
				if (sortCond[2] != null) {
					sortDataType = sortCond[2];
				}
				sortCond = sortCond[0];
			}
		}
		xslStr += '<xsl:sort select="' + sortCond + '" order="' + sortOrder + '" data-type="' + sortDataType + '"/>';
	}
	xslStr += '<' + dsNameOut + '>' + '<xsl:copy-of select="@*"/><xsl:copy-of select="node()"/></' + dsNameOut +  '></xsl:for-each>' +
			'</dataset></EPROMAK></xsl:template></xsl:stylesheet>';
	xslXml.loadXML(xslStr);
	var xmlwyj = new ActiveXObject(ctxApp.xmlParser);
	xmlwyj.setProperty("SelectionLanguage", "XPath");
	
	xds.xmlObject.transformNodeToObject(xslXml, xmlwyj);
	return xmlwyj;
}

function _xdsRestoreOrgXml() {
	var xds = this;
	var xslStr = '<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:template match="@*|node()"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:template>';
	xslStr += '<xsl:template match="dataset[@schema]"><xsl:for-each select="."><xsl:element name="dataset"><xsl:copy-of select="@*"/><xsl:call-template name="_convert"/></xsl:element></xsl:for-each></xsl:template>';
	xslStr += '<xsl:template name="_convert"><xsl:variable name="schema" select="@schema"/><xsl:variable name="nazwa" select="@name"/><xsl:for-each select="r"><xsl:element name="{$nazwa}"><xsl:call-template name="_makeattrs"><xsl:with-param name="names" select="$schema"/><xsl:with-param name="values" select="@v"/></xsl:call-template><xsl:apply-templates select="node()"/></xsl:element></xsl:for-each></xsl:template>';
	xslStr += '<xsl:template name="_makeattrs"><xsl:param name="names"/><xsl:param name="values"/><xsl:choose><xsl:when test="contains($names, \';\')"><xsl:attribute name="{substring-before($names,\';\')}"><xsl:value-of select="substring-before($values,\';\')"/></xsl:attribute><xsl:call-template name="_makeattrs"><xsl:with-param name="names" select="substring-after($names,\';\')"/><xsl:with-param name="values" select="substring-after($values,\';\')"/></xsl:call-template></xsl:when><xsl:otherwise><xsl:attribute name="{$names}"><xsl:value-of select="$values"/></xsl:attribute></xsl:otherwise></xsl:choose></xsl:template></xsl:stylesheet>';
	var xslXml = new ActiveXObject(ctxApp.xmlParser);
	xslXml.setProperty("SelectionLanguage", "XPath");	
	xslXml.loadXML(xslStr);	
	var xmlwyj = new ActiveXObject(ctxApp.xmlParser);
	xmlwyj.setProperty("SelectionLanguage", "XPath");
	xds.xmlObject.transformNodeToObject(xslXml, xmlwyj);
	return new XmlDataSource(false, xmlwyj);
}

function formatFloat(v, p){
	var i,mn,z,c
	z=""
	mn=Math.pow(10,p)
	if(isNaN(v))v="0"
	if(v<0){z="-";v=Math.abs(new Number(v))}
	if(p>0){cents=Math.floor((v*mn+0.5)%mn);c=","}else{cents="";c=""}
	if(p>0){v=Math.floor(new Number(v)).toString()}else{v=Math.floor(new Number(v)+0.5).toString()}
	i=cents.toString().length
	while(i<p){cents="0"+cents;i++}
	for(i=0;i<Math.floor((v.length-(1+i))/3);i++)
		v=v.substring(0,v.length-(4*i+3))+' '+v.substring(v.length-(4*i+3))
	return(z+v+c+cents)
}

function getAttr(node, attrName) {
	if (node == null || attrName == null) return "";
	var val = node.getAttribute(attrName);
	return (val == null)?"":val;
}

// Zwraca z arkusza stylów pirwszą regułę odpowidającą selektorowi obiektu
function getRule(ruleName){
	var rule=null;
	for (var ssIndex=0;ssIndex<ctxApp.frameset.document.styleSheets.length;ssIndex++){
		var styleSheet=ctxApp.frameset.document.styleSheets[ssIndex];
		var flaga=false;
		for (var rIndex=0; rIndex<styleSheet.rules.length; rIndex++){
			rule=styleSheet.rules[rIndex]
			if ((rule.selectorText=="."+ruleName)||(rule.selectorText==ruleName)){
				var flaga=true;
				break;
			}								
		}
		if ( flaga ) break;
	
	}
	return rule;
}

// Sprawdzenie, czy task (action) wymaga podpisu elektronicznego 
// dla któregokolwiek z datasetów
function _xdsIsTask2SignatureVerify(action) {
	var ret = false;
	var xds = this;
	var node = xds.xmlObject.documentElement;
	if(node) {
		for(var i = 0; i < node.childNodes.length; i++) {
			if(node.childNodes.item(i).nodeName == "dataset") {
				if(ctxApp.isTask2SignatureVerify(getAttr(node.childNodes.item(i), "name"), action)) {
					ret = true;
					break;
				}
			}
		}
	}
	return ret;
}

function _xdsIsSignedAck () {
	var xds = this;
	var hasREQUEST = false;
	var hasSignature = false;
	var node = xds.xmlObject.documentElement;
	if(node) {
		for(var i = 0; i < node.childNodes.length; i++) {
			if(node.childNodes.item(i).nodeName == 'REQUEST') {
				hasREQUEST = true;
			}
			if(node.childNodes.item(i).nodeName == 'Signature') {
				hasSignature = true;
			}
		}
	}
	return hasREQUEST && hasSignature;
}
