JavaLikeCalc.JavaScript
using Special.FLibSYS;

if(f_start) {
	if(!name_.length)	name_ = this.attr("name");
	viewSet_geomY_ = viewSet_geomY, viewSet_geomH_ = viewSet_geomH;
	pAddr = pName.slice(0, pName.lastIndexOf("/"));
	if(!(pObj=SYS.nodeAt(pAddr)))	return;
	scLog = (pObj.nodeAt("a_log").get() == true);
	aLst = pObj.nodeList("a_");
	this.attrSet("name", name_+": "+SYS.nodeAt(pName).get());

	selTab = "view";

	//View mode clean up
	view_value = ""; view_geomH = geomH-view_geomY-1;

	//Standard parameters
	stdPrms = "var;sp;out;auto;aMin;aMax;wMin;wMax;com;close;stop;st_open;st_close;";
	//pColors = new Array("darkmagenta", "orange", "blue", "lightgreen", "cyan", "tomato", "magenta", "wheat", "lightyellow", "darkcyan");

	//Trends prepare
	trN = 0, trNMax = 10, trNClr = 0; trDigN = 0;
	trendsList_items = "<tbl sel='row' colsWdthFit='1'><h><s width='0px'>"+tr("ID")+"</s><s width='50%'>"+tr("Name")+"</s><s edit='1' width='25%'>"+tr("Minimum")+"</s><s edit='1' width='25%'>"+tr("Maximum")+"</s></h>";
	trendsList_value = "";
	trObj = this.wdgAt("trends");
	trObj.attrSet("sclVer", scLog?6:2);
	trObj.attrSet("parNum", trNMax);
	// Clear previous trends
	for(iTr = 0; iTr < trNMax; iTr++) trObj.attrSet("prm"+iTr+"addr", "");
	for(off = 0; (sP=stdPrms.parse(0,";",off)).length && trN < trNMax; ) {
		if(!(aObj=pObj.nodeAt("a_"+sP)) ||
			(sP == "aMin" && ((tV=aObj.get()) >= pObj.nodeAt("a_aMax").get() || tV <= pObj.nodeAt("a_min").get())) ||
			(sP == "aMax" && ((tV=aObj.get()) <= pObj.nodeAt("a_aMin").get() || tV >= pObj.nodeAt("a_max").get())) ||
			(sP == "wMin" && ((tV=aObj.get()) >= pObj.nodeAt("a_wMax").get() || tV <= pObj.nodeAt("a_min").get())) ||
			(sP == "wMax" && ((tV=aObj.get()) <= pObj.nodeAt("a_wMin").get() || tV >= pObj.nodeAt("a_max").get())))	continue;
		isBool = (typeof(aObj.get())=="boolean");
		trObj.attrSet("prm"+trN+"addr", pAddr+"/a_"+sP);
		trObj.attrSet("prm"+trN+"color", (trClr=this.attr("labColorGrph"+(trNClr+1)))+(isBool?"-127":""));
		trObj.attrSet("prm"+trN+"width", 2);
		if((sP == "var" || sP == "sp" || sP == "aMin" || sP == "aMax" || sP == "wMin" || sP == "wMax") && pObj.nodeAt("a_min")) {
			trObj.attrSet("prm"+trN+"bordL", pObj.nodeAt("a_min").get()).attrSet("prm"+trN+"bordU", pObj.nodeAt("a_max").get()).attrSet("prm"+trN+"scl",0);
			if(sP == "aMin" || sP == "aMax" || sP == "wMin" || sP == "wMax")
				trObj.attrSet("prm"+trN+"addr","line:"+aObj.get()).attrSet("prm"+trN+"color",(trClr=(sP[0]=="a")?"red":"yellow"));
		}
		else if(sP == "out") trObj.attrSet("prm"+trN+"bordL",0).attrSet("prm"+trN+"bordU",100).attrSet("prm"+trN+"scl",2);
		else if(isBool) { trObj.attrSet("prm"+trN+"bordL", -trDigN).attrSet("prm"+trN+"bordU", 20-trDigN).attrSet("prm"+trN+"scl",2); trDigN++; }
		else trObj.attrSet("prm"+trN+"scl",2);
		trendsList_items += "<r><s>"+trN+"</s>"
											"<s color='"+trClr.parse(0,"-")+"'>"+strEnc2HTML(aObj.descr())+"</s>"
											"<r>"+trObj.attr("prm"+trN+"bordL")+"</r>"
											"<r>"+trObj.attr("prm"+trN+"bordU")+"</r></r>";
		trN++; trNClr++;
	}
	for(iA = 0; iA < aLst.length && trN < trNMax; iA++) {
		aId = aLst[iA].slice(2);
		if(stdPrms.indexOf(aId+";") != -1 || !(aObj=pObj.nodeAt(aLst[iA])) || !aObj.arch()) continue;
		isBool = (typeof(aObj.get())=="boolean");
		trObj.attrSet("prm"+trN+"addr", pAddr+"/a_"+sP);
		trObj.attrSet("prm"+trN+"color", this.attr("labColorGrph"+(trNClr+1))+(isBool?"-127":""));
		trObj.attrSet("prm"+trN+"width", 2);
		if(isBool) { trObj.attrSet("prm"+trN+"bordL", -trDigN).attrSet("prm"+trN+"bordU", 20-trDigN); trDigN++; }
		trendsList_items += "<r><s>"+trN+"</s>"
											"<s color='"+this.attr("labColorGrph"+(trNClr+1))+"'>"+strEnc2HTML(aObj.descr())+"</s>"
											"<s>"+trObj.attr("prm"+trN+"bordL")+"</s>"
											"<s>"+trObj.attr("prm"+trN+"bordU")+"</s></r>";
		trN++; trNClr++;
	}
	trendsList_items += "</tbl>";
	sel_trends_en = trN;

	//Data table prepare
	dtALst = new Array();
	dtPeriod = 1;
	for(off = 0; (sP=stdPrms.parse(0,";",off)).length; )
		if((aObj=pObj.nodeAt("a_"+sP)) && aObj.arch()) {
			dtALst.push(aObj);
			dtPeriod = max(dtPeriod, ceil(aObj.arch().cfg("BPER")));
		}
	for(iA = 0; iA < aLst.length; iA++) {
		aId = aLst[iA].slice(2);
		if(stdPrms.indexOf(aId+";") == -1 && (aObj=pObj.nodeAt(aLst[iA])) && aObj.arch()) {
			dtALst.push(aObj);
			dtPeriod = max(dtPeriod, ceil(aObj.arch().cfg("BPER")));
		}
	}
	sel_data_en = dtALst.length;
	if(!sel_trends_en && !sel_data_en)	 { view_geomH += view_geomY-sel_view_geomY; view_geomY = sel_view_geomY; }
}
if(f_stop) viewSet_geomY = viewSet_geomY_, viewSet_geomH = viewSet_geomH_;

//View update
if(pObj && view_en) {
	view_items = "<tbl sel='row' colsWdthFit='1'><h><s width='0px'>"+tr("ID")+"</s><s width='60%'>"+tr("Name")+"</s><s width='30%'>"+tr("Value")+"</s></h>";
	for(iA = 0; iA < aLst.length; iA++) {
		if(!hideAttrs.isEVal() && hideAttrs.match("(;|^)"+aLst[iA].slice(2)+"(;|$)").length)	continue;
		aObj = pObj.nodeAt(aLst[iA]);
		view_items += "<r><s>"+aLst[iA]+"</s>"
									"<s>"+strEnc2HTML(aObj.descr())+"</s>"
									"<s>"+strEnc2HTML(aObj.get())+"</s></r>";
	}
	view_items += "</tbl>";
}

//Data update
if(pObj && data_en) {
	data_tmpl = "<body docProcLang='JavaLikeCalc.JavaScript'>\n"
		"<table class='data' cellpadding='2' cellspacing='0' export='1' valign='middle' width='100%'>\n";
	// Header
	data_tmpl += "<tr><th>Date</th>";
	for(iA = 0; iA < dtALst.length; iA++)
		data_tmpl += "<th>"+strEnc2HTML(dtALst[iA].descr())+"</th>";
	data_tmpl += "</tr>\n";

	// Date
	curTime = SYS.time();
	for(i_rec = curTime; i_rec > (curTime-100*dtPeriod); i_rec-=dtPeriod) {
		data_tmpl += "<tr><td>"+SYS.strftime(i_rec,"%d %m %H:%M:%S")+"</td>";
		for(iA = 0; iA < dtALst.length; iA++) {
			i_rec_ = i_rec;
			data_tmpl += "<td>"+strEnc2HTML(dtALst[iA].get(i_rec_))+"</td>";
		}
		data_tmpl += "</tr>\n";
	}
	data_tmpl += "</table></body>\n";
}

//Events process
ev_rez = "";
for(off = 0; true; ) {
	sval = event.parse(0, "\n", off);
	if(!sval.length) break;
	//SYS.messInfo("ObjProps","Event: "+sval);
	if(sval.slice(0,16) == "ws_BtPress:/sel_") selTab = sval.slice(16);
	else if(sval == "ws_TableChangeSel:/view" && (aObj=pObj.nodeAt(view_value))) {
		if(!(aObj.flg()&0x04)) {
			if(typeof(aObj.get()) == "string" && aObj.flg()&0x08) {
				this.viewSet.attrSet("elType",1);	//Text editor
				viewSet_geomY = viewSet_geomY_ - viewSet_geomH_*3;
				viewSet_geomH = viewSet_geomH_*4;
				view_geomH = viewSet_geomY - view_geomY - 1;
			}
			else {
				this.viewSet.attrSet("elType",0).attrSet("view",1);	//Combo box
				this.viewSet.attrSet("cfg", (aObj.flg()&0x01) ? aObj.values().split(";").join("\n") : "");
				viewSet_geomH = viewSet_geomH_, viewSet_geomY = viewSet_geomY_;
				view_geomH = viewSet_geomY - view_geomY - 1;
			}
			this.viewSet.attrSet("value",aObj.get());
		}
		else view_geomH = geomH-view_geomY-1;
	}
	else if((sval == "ws_LnAccept:/viewSet" || sval == "ws_TxtAccept:/viewSet") && (aObj=pObj.nodeAt(view_value))) aObj.set(this.viewSet.attr("value"));
	else if(sval == "ws_TableChangeSel:/trendsList")
		for(i_tr = 0; i_tr < trN; i_tr++)
			trObj.attrSet("prm"+i_tr+"width", ((i_tr==trendsList_value)?3:2));
	else if((reRez=sval.match("ws_TableEdit_(\\d+)_(\\d+)\\:\\/trendsList")).length)
		trObj.attrSet("prm"+trendsList_value+((reRez[1]==2)?"bordL":"bordU"), trendsList_set);
	else ev_rez += sval+"\n";
}
event = ev_rez;

//Tab selection process
if(f_start || selTab != prevTab) {
	wLs = this.nodeList("wdg_");
	for(iW = 0; iW < wLs.length; iW++) {
		wId = wLs[iW].slice(4);
		wObj = this.wdgAt(wId);
		if(wId.indexOf("sel_") != -1)	wObj.attrSet("color",(wId.slice(4)==selTab)?backColorButtonSel:backColorButton);
		else if(wId.indexOf(selTab) != -1) wObj.attrSet("en",true);
		else if(wId.indexOf(prevTab) != -1) wObj.attrSet("en",false);
	}
	prevTab = selTab;
}