<job>
<script language="JScript">

//*******************************************************************************
// Name: UtilScript.wsf
// Desc: utility script for cybro mini scada
// Goal: universal mini scada with nad autodetect
// Operation:
// - find controllers with specified program_id
// - select controller from the pop-up dialog
// - search/replace through xml file
// - restart mini scada
// Requirement: CyBroComServer.exe within the same directory
// Usage:
// <shortpress>
//   <action>
//     <type>command</type>
//     <command>UtilScript.wsf</command>
//     <parameters>/autodetect file.xml</parameters>
//     <waitforexit>1</waitforexit>
//   </action>
// </shortpress>
//*******************************************************************************

var tmpFile = "temp.xml";
var program_id = "3";

//*******************************************************************************
// General utility functions
//*******************************************************************************

//exec command, hide window and wait for it to finish
function execCommand(aCommand){
  var objShell = new ActiveXObject("WScript.Shell");
  objShell.Run(aCommand,0,true);
}

//save string aTxt to file
function saveFile(aFile,aTxt){
  var fso = new ActiveXObject("Scripting.FileSystemObject"); // create object needed for working with files
  fsn = fso.OpenTextFile(aFile, 2, true); // open for writing
  fsn.Write(aTxt);
  fsn.Close();
  fsn = null;
}

//read text file and delete (or not) after reading
function readFile(aFile,aDeleteFile){
  var fso = new ActiveXObject("Scripting.FileSystemObject"); // create object needed for working with files
  var fsn = fso.OpenTextFile(aFile, 1); // open for reading
  var txt = fsn.ReadAll();
  fsn.Close();
  fsn = null;
  if (aDeleteFile) fso.DeleteFile(aFile);
  return txt;
}

// replace a regex match with a new string in a file globally
function regexReplaceInFile(aRegex,aReplace,aFile){
  txt = readFile(aFile,false);
  var rx = new RegExp(aRegex, "g");
  txt = txt.replace(rx,aReplace);
  saveFile(aFile,txt);
}

//*******************************************************************************
// XML and DOM functions
//*******************************************************************************

// delete a tag with specified attribute from DOM xml
function deleteTagWithAttribute(aTag,aAttribute,aValue,xml){
  // convert text to xml dom object
  var varRoot = xml.documentElement;
  var tagVar = varRoot.getElementsByTagName(aTag);

  // remove tags with specified attribute
  for (i=0; i<tagVar.length; i++){
    if (tagVar[i].getAttribute(aAttribute)==aValue){
      varRoot.removeChild(tagVar[i]);
    }
  }
}

// example function to delete pages with an attribute delete="yes"
function deletePagesDOM(aFile){
  txt=readFile(aFile,false);
  var xml = new ActiveXObject("Microsoft.XMLDOM");
  xml.loadXML(txt);
  deleteTagWithAttribute("page","delete","yes",xml);
  saveFile(aFile,xml.xml);
}

// !!! *** not working yet ****
function deletePageByName(xml,aName){
  //var rx = new RegExp("<page[\\S\\s]*?(?!delete)<name>"+aName+"[\\S\\s]*?<\\/page>", "g");
  //var rx = new RegExp("<page[\\S\\s]*?(?!delete<name>"+aName+"<\\/name>)[\\S\\s]*?<\\/page>", "g");
  var rx = new RegExp("^.*<page[\\S\\s]+?<name>"+aName,"m");
  //var rx = new RegExp("<page[\\S\\s]+?<name>"+aName+"[\\S\\s]+?<\\/page>","");
  WScript.Echo(rx);
  return xml.match(rx);
}

//*******************************************************************************
// CyBro specific functions
//*******************************************************************************

//returns array of detected CyBro network addresses (nads)
function detectCybros(aProgId){
  //scan for CyBros
  execCommand("cmd /c CybroComServer.exe /scan > " + tmpFile);
  var controllers=readFile(tmpFile,true);

  // convert controller list to xml dom object
  var cyXml = new ActiveXObject("Microsoft.XMLDOM");
  cyXml.loadXML(controllers);
  var cyRoot = cyXml.documentElement;

  // read program_id from CyBros
  var pgmIdVars="";
  var cyItem = cyRoot.getElementsByTagName("item");
  for (cybro=0; cybro<cyItem.length; cybro++){
     if (cybro==0){
       pgmIdVars = "c" + cyItem[cybro].childNodes[0].nodeValue + ".program_id";
     } else {
       pgmIdVars = pgmIdVars + "&c" + cyItem[cybro].childNodes[0].nodeValue + ".program_id";
     }
  }

  var arr = new Array();
  if (pgmIdVars!=""){
    execCommand("cmd /c CybroComServer.exe \"" + pgmIdVars + "\" > " + tmpFile);
    var variables=readFile(tmpFile,true);

    // convert variable list to xml dom object
    var varXml = new ActiveXObject("Microsoft.XMLDOM");
    varXml.loadXML(variables);
    var varRoot = varXml.documentElement;
    var cvar = varRoot.getElementsByTagName("var");

    // list only nads with required program_id
    for (cybro=0; cybro<cyItem.length; cybro++){
      programIdTag = "c" + cyItem[cybro].childNodes[0].nodeValue + ".program_id";
      for (v=0; v<cvar.length; v++){
        if (cvar[v].childNodes[0].childNodes[0].nodeValue==programIdTag){
          if (cvar[v].childNodes[1].childNodes[0].nodeValue==aProgId){
            arr.push(cyItem[cybro].childNodes[0].nodeValue);
          }
        }
      }
    }
  }
  return arr;
}

//replace nad in XML file with autodetected nad
function replaceNadWithDetected(fromNad,aFile,aProgID,noDetectedMsg){
  var nads=detectCybros(aProgID);
  if (nads.length>0){
    nad = getUserSelectedCyBro(nads);
    if (nad!=null){
      regexReplaceInFile(fromNad,"c"+nad,aFile);
    }
  } else if (noDetectedMsg!=""){
    WScript.Echo(noDetectedMsg);
  }
}

//find nad in XML file
function getNadFromXml(aFile){
  xml = readFile(aFile,false);
  var rx = new RegExp("<var>c\\d{1,}\\.", "");
  xml = xml.match(rx);
  if (xml!=null){
    rx = new RegExp("c\\d{1,}", "");
    xml = xml[0].match(rx);
  }
  return xml; //returns null if nothing found
}

function getUserSelectedCyBro(nadlist){
  var WshShell = new ActiveXObject("WScript.Shell");
  var oExec = WshShell.Exec('GetUserSelection.exe /s:12 /o:'+nadlist+' "/i:Select HIQ controller:"');  // switches: /s - font size, /o - nadlist, /i - label text, /t - window title
  while (oExec.Status == 0){
    WScript.Sleep(100);
  }
  if (oExec.ExitCode>=0){
    return nadlist[oExec.ExitCode];
  } else {
    return null;
  }
}

//*******************************************************************************
// Main program
//*******************************************************************************

function main(){
  // read cmdline arguments
  var args = WScript.Arguments;
  for (var i=0; i < args.length-1; i++){
    if (args(i)=="/autodetect"){
      file_name=args(i+1);
      old_nad=getNadFromXml(file_name);
      if (old_nad!=null) replaceNadWithDetected(old_nad,file_name,program_id,"No HIQ controllers detected");
    }
  }
}

main();

</script>
</job>