/* library for createWizard */


// ============================================= Show list of current instruments, or accept name for new instrument ===========================

// =======================
// shows a list of currently defined instruments (in a div)
// instListA: a space delimited list of instrument names (that may have a $project_name syntax)      (string)
//  maxInrow : maximum number of columns in table                 (inteter)
// funcCall : name of the function to call when clicked (a string). Call using
//    funcCall(projName,0:
//    or
//    funcCall(instName,1)   (instname may contain the $project suffict)
// returns an html table listing the instruments (grouped by project)



function makeInstrumentsTable(instListA,maxInRow,funcCall) {
var atable,m,mm,tt,aname,wasproj,aproj,aproj0;
var glob1 ;
var instList2=[];
var projList={};

var instList=getWord(instListA);           // instList is a global
instList=instList.sort();

atable='<table border="1">';

// parse out projects and names from list of instrument files
for (m=0 ;m<instList.length;m++) {
  instList2[m]=[];
  ainst=strip(instList[m]);
  instList2[m]=extractProjectName(ainst)
  if (instList2[m][1]!=='') projList[instList2[m][1]]=1;
}
wasproj='';
mct=0;
//for (m=0 ;m<instList.length;m=m+6) {
for (m=0 ;m<instList.length;m++) {
  mct++;
  ainst=strip(instList[m]);
  aname=instList2[m][0];
  aproj=instList2[m][1];

  if (mct==maxInRow || aproj!==wasproj) {
        atable=atable+'</tr> ';
        mct=1;
        wasproj=aproj;
  }
  aproj0=aproj;
  if (aproj0=='') aproj0='(none)';
  if (mct==1) atable=atable+'<tr><td style="background-color:#dedede"><tt>'+'<a title="Click to use this project" href="#" onClick="'+funcCall+'(\''+aproj+'\',0); return false">'+aproj0+'</a></tt> ';

  tt='<a href="#" title="click to chose this instrument" onClick="'+funcCall+'(\''+ainst+'\',2); return false">'+aname+'</a> ';
  atable=atable+'<td>'+tt+'</td>';
}
atable=atable+'</tr> \n ';
atable=atable+'</table> ';

return atable ;


}

function retrieveInsts() {
   Get_File(getInstrumentsURL,'instList0','retrieving list of instruments ','retrieveInsts2',1,1) ;
   return 1 ;
}
function retrieveInsts2() {
 var id1=document.getElementById('instListDiv');
 var atable=makeInstrumentsTable(instList0,7,'instClicked') ;
 id1.innerHTML=atable;
 instListG=instList0;
 return 1;
}


//=================================================================================================================
// this is called when an existing instrument (that is displayed on the select-an-instrumenbt-to-modify-menu) is clicked
// instrument descirptor file to: instDescNode
// param files retrievedto: allowedNode,refParamsNode,generalParamsNode
// module and spec files retrieved to: modules1Node, specsNode, specElementsNode

function instClicked(ainst,iwas,ido) {
  var goo,uu;

if (arguments.length<3) ido=1 ;

if (ido==1) {                        // first call ....

  if (iwas==0) {                     // a hack: copy project name (of existing project) to project name field of create a new instrument)
     var id1=document.getElementById('newProject');
     id1.value=ainst;
     return 0;
   }

   writeToStatus("Modifying instrument: "+ainst);

   var goo=ainst.split('.');
   uu=extractProjectName(ainst);

   instrumentNames[0]=goo[0];                    // the full name (droppping the .xml)
   instrumentNames[1]=uu[0];                      // name of instrument (droppoing the project)
   instrumentNames[2]=uu[1];                      // project of instrument


// 1) get descriptor file  (similar to the modifyInstDesc function)

  writeToStatus('Retrieving instrument descriptor file '+ainst);
  toget=getInstrumentURL+ainst;
  Get_xmlFile(toget,['instDescNode','instDescCode'],'retrieving xml instrument file ','instClicked',ainst,0,2);
  return 0;
}

// 2: parse dewscriptor file
if (ido==2) {
  if (instDescCode!==200) {
      alert('Error '+instDescCode+': unable to retrieve instrument descriptor file for: '+ainst);
      return 0;
  }
   oldvars=getDescriptorVar('createWizard',instrumentNames[0]);
   oldvars2=getWord(oldvars,0,',');

 // shortcut: variable values: refDataType,instType,instDesc ,messOpt,maxUsers,reqPassword,defPassword,uniqueNames,getContact,getNickname;
   refDataType=oldvars2[0];
   instType=oldvars2[1];
   instDesc=unescape(oldvars2[2]);
   messOpt=oldvars2[3];
   maxUsers=oldvars2[4];
   reqPassword=oldvars2[5];
   defPassword=unescape(oldvars2[6]);
   uniqueNames=oldvars2[7];
   getContact=oldvars2[8];
   getNickname=oldvars2[9];
   writeToStatus(' retrieved: '+ainst +' ('+oldvars+')' );

   getParamsFiles(1,1);                    // read parameter files (1 signals " return to instClicked with arg of 3
   return 0;
}


if (ido==3) {                                 // after retrieving parameter files, now get modules1, spec, and spec_elements
  writeToStatus('Retrieving modules and spec files ');
  paramFilesExist=[];
  usenam=instrumentNames[0];
  toget=getModules1XML_1.replace(/\$NAME\$/g,usenam) ;
  Get_xmlFile([toget,1],['modules1Node','modules1Code','1'],'retrieving modules1 file ','instClicked',usenam,0,31) ;
  return 0;
}

if (ido==31) {

  if (modules1Code=='200') {
     paramFilesExist=paramFilesExist.concat('modules1');
  }
  usenam=instrumentNames[0];
  toget=getSpecsXML_1.replace(/\$NAME\$/g,usenam) ;
  Get_xmlFile([toget,1],['specsNode','specsCode','1'],'retrieving specs file ','instClicked',usenam,0,32) ;
  return 0;
}

if (ido==32) {

    if (specsCode=='200') {
     paramFilesExist=paramFilesExist.concat('specs');
  }
  usenam=instrumentNames[0];
  toget=getSpecElementsXML_1.replace(/\$NAME\$/g,usenam) ;
  Get_xmlFile([toget,1],['specElementsNode','specElementsCode','1'],'retrieving spec_elements file ','instClicked',usenam,0,33) ;
  return 0;
}

if (ido==33) {

  if (specElementsCode=='200') {
     paramFilesExist=paramFilesExist.concat('spec_elements');
  }
  writeToStatus(' retrieved: '+paramFilesExist );
  ido=4 ;
}

// done getting files ....  perhaps we should show the modify parameter files menu?
if (ido==4) {
 hideDivs(1);
 if (refParamsNode==null || generalParamsNode==null || (refDataType==3 && allowedNode==null)) {   // a missing parameters file -- so ask for it
    changeInstParams(1) ;
 }
}


return 0;
}

//=================================================================================================================
// ============================================= show instrument status ===========================
//=================================================================================================================
// instrument descirptor file to: instDescNode
// param files retrievedto: allowedNode,refParamsNode,generalParamsNode
// module and spec files retrieved to: modules1Node, specsNode, specElementsNode

function showInstStatus(ido) {
  var ii1,tmp,stuff;

displayDiv('showStatus','block');
  var ii1=document.getElementById('showInstNameStatus');
  ii1.innerHTML='('+instrumentNames[1] ;
  if (instrumentNames[2]!=='') ii1.innerHTML=ii1.innerHTML+' in project '+instrumentNames[2];
  ii1.innerHTML=ii1.innerHTML+')';
stuff='<table border="1"><tr><th>File</th><th>status</th></tr>';

stuff=stuff+'<tr><td>Descriptor file</td>';
if (instDescNode!==null) {
    stuff=stuff+'<td>'+readModified(instDescNode,'descinfo')+'</td></tr>\n';
} else {
   stuff=stuff+'<td>Descriptor file <b>not</b> created</td></tr>\n';
}

stuff=stuff+'<tr><td>General parameters</td>';
if (generalParamsNode!==null) {
    stuff=stuff+'<td>'+readModified(generalParamsNode,'descinfo')+'</td></tr>\n';
} else {
   stuff=stuff+'<td>General parameters file <b>not</b> created</td></tr>\n';
}

stuff=stuff+'<tr><td>Participant-specific (reference) parameters</td>';
if (refParamsNode!==null) {
    stuff=stuff+'<td>'+readModified(refParamsNode,'descinfo')+'</td></tr>\n';
} else {
   stuff=stuff+'<td>Participant-specific parameters file <b>not</b> created</td></tr>\n';
}

if (refDataType==3) {
stuff=stuff+'<tr><td>allowedUsers</td>';
if (allowedNode!==null) {
    stuff=stuff+'<td>'+readModified(allowedNode,'descinfo')+'</td></tr>\n';
} else {
   stuff=stuff+'<td>allowedUsers file <b>not</b> created</td></tr>\n';
}
} else {
    stuff=stuff+'<tr><td colspan=2">allowedUsers file <b>not</b> used (participant specific data is <u>not</u> <tt>By name</tt>)</td></tr>\n';
}


// module and spec files retrieved to: modules1Node, specsNode, specElementsNode
stuff=stuff+'<tr><td>Modules</td>';
if (modules1Node!==null) {
    stuff=stuff+'<td>'+readModified(modules1Node,'descinfo')+'</td></tr>\n';
} else {
   stuff=stuff+'<td>Module file <b>not</b> created</td></tr>\n';
}

stuff=stuff+'<tr><td>Specification file</td>';
if (specsNode!==null) {
    stuff=stuff+'<td>'+readModified(specsNode,'descinfo')+'</td></tr>\n';
} else {
   stuff=stuff+'<td>Specification file <b>not</b> created</td></tr>\n';
}

stuff=stuff+'<tr><td>Specification-elements file</td>';
if (specElementsNode!==null) {
    stuff=stuff+'<td>'+readModified(specElementsNode,'descinfo')+'</td></tr>\n';
} else {
   stuff=stuff+'<td>Specification-elements file <b>not</b> created</td></tr>\n';
}


stuff=stuff+'</table>';
var ii1=document.getElementById('showStatus1');
ii1.innerHTML=stuff;
return 0;
}

//=================================================================================================================
// ============================================= modify existing instrument  functions ===========================
//=================================================================================================================


// get existing instrument desriptor file
function modifyInstDesc(ainst,ido) {
var oldvars,oldvars2,toget,m,i11,oldDesc;
  if (arguments.length<2) ido=1
//  var uu=extractProjectName(ainst);

//  alert('in modifgda '+ido+','+ainst);

 hideDivs(1);

if (ido==1) {
    writeToStatus('Retrieving instrument descriptor file '+ainst);
    toget=getInstrumentURL+ainst;
    Get_xmlFile(toget,'instDescNode','retrieving xml instrument file ','modifyInstDesc',ainst,3);
    return 0;
}

if (ido==3) {                                        // called after ido=1 (skipped if immediately called by instClicked
// update some instDesc globals, using  shortcut: refDataType,instType,instDesc ,messOpt,maxUsers,reqPassword,defPassword,uniqueNames,getContact,getNickname;
   oldvars=getDescriptorVar('createWizard',instrumentNames[0]);
   oldvars2=getWord(oldvars,0,',');
   refDataType=oldvars2[0];
   instType=oldvars2[1];
   instDesc=unescape(oldvars2[2]);
   messOpt=oldvars2[3];
   maxUsers=oldvars2[4];
   reqPassword=oldvars2[5];
   defPassword=unescape(oldvars2[6]);
   uniqueNames=oldvars2[7];
   getContact=oldvars2[8];
   getNickname=oldvars2[9];
   writeToStatus(' retrieved: '+ainst +' ('+oldvars+')' );
}

// now populate a form  (ido=4, or after ido=3)

instDescFrom=1;
// got descriptor -- get the createmodified stuff

 displayDiv("show2","block");

  var ii1=document.getElementById('showInstName2');
  ii1.innerHTML='('+instrumentNames[1] ;
  if (instrumentNames[2]!=='') ii1.innerHTML=ii1.innerHTML+' in project '+instrumentNames[2];
  ii1.innerHTML=ii1.innerHTML+')';

  displayDiv('retainInstPrior','inline');                    // no changes option

  oldDesc=readModified(instDescNode,'descInfo');


// update form using above
document.instOptions.adesc.value=instDesc  ;

il1=document.instOptions.type1.length ;

for (var m=0;m<il1;m++) {
  document.instOptions.type1[m].checked=false ;
  if (instType-1 == m) document.instOptions.type1[m].checked=true ;
}

// assignData
il1=document.instOptions.type2.length ;
ido=0;
for (var m=0;m<il1;m++) {
  document.instOptions.type2[m].checked=false ;
  if (refDataType-1 == m) document.instOptions.type2[m].checked=true ;
 }

 // password
reqPassword=strip(reqPassword);
defPassword=strip(defPassword);
if (defPassword=='0') defPassword='';
document.instOptions.reqPassword.checked=false  ;
if (reqPassword==1) document.instOptions.reqPassword.checked=true;

document.instOptions.defPassword.value=defPassword  ;

document.instOptions.nameCheck.checked=false  ;
if (uniqueNames==1) document.instOptions.nameCheck.checked=true ;

document.instOptions.aContact.checked=false  ;
if (getContact==1) document.instOptions.aContact.checked=true ;

document.instOptions.aNickname.checked=false  ;
if (getNickname==1) document.instOptions.aNickname.checked=true ;

maxUsers=strip(maxUsers);
if (maxUsers=='0') maxUsers='';
document.instOptions.maxUsers.value=maxUsers;


// message opts
il1=document.instOptions.mess1.length ;
ido=0;
for (var m=0;m<il1;m++) {
  document.instOptions.mess1[m].checked=false ;
  if (messOpt-1 == m) document.instOptions.mess1[m].checked=true ;
 }

writeToStatus('Last modified: '+oldDesc);
}


//


// ============================================= Create new instrument  functions ===========================
//==========================
// create a new instrument, starting with template
function createNewInst(ainst) {

 var useName;
 var id1=document.getElementById('newName');


 var  vname=strip(id1.value);
 if (strip(vname)=='') {
   alert('You must specify a single-word name for this instrument');
   return 0 ;
 }

 var idp=document.getElementById('newProject');
 var  pname=strip(idp.value);
 if (pname!=='') {
    var zz=getWord(pname);
    if (zz.length>1) {
        alert(' Error. Your project ('+pname+') has more than one word in it.')
       return 0;
    }
 }

  if (pname!=='')     {
      useName='$'+pname+'_'+vname;
  } else {
      useName=vname;
  }
  useName=strip(useName.toUpperCase());

  var instList=getWord(instListG.toUpperCase());           // instList is a global
  instList=instList.sort();
  for (var i=0;i<instList.length;i++) {
       tmp0=parseAt(instList[i],'.')
       tmp1=strip(tmp0[0]).toUpperCase() ;
       if (useName==tmp1) {
          amess='Error.  There already is an instrument with the name: '+vname;
          if (pname!=='') amess=amess+' (in project '+pname+')';
          alert(amess+'. Please use a different 1-word name! ');
          return 0;
       }
  }

 instrumentNames=[useName,vname,pname];  // global (full name, instrument name, project name)

  writeToStatus('Creating '+vname+' (in project '+pname+')');

  var toget=createDirectoriesURL+'&name='+useName;

  Get_File(toget,'makeDirs','creating directories for a new instrument ','createNewInst2',useName) ;

}
function createNewInst2(ainst) {
  writeToStatus(' Directories created for new instrument '+ainst+' :: '+makeDirs);
  hideDivs(1);
  displayDiv("show2","block");

  var ii1=document.getElementById('showInstName2');
  ii1.innerHTML='('+instrumentNames[1] ;
  if (instrumentNames[2]!=='') ii1.innerHTML=ii1.innerHTML+' in project '+instrumentNames[2];
  ii1.innerHTML=ii1.innerHTML+')';
  instDescFrom=0;
  writeToStatus('Creating new instrument descriptor file');


  return 1 ;
}




// ================
//  Called on a Submit from  the instrumento ptions screen
//    instrument type (lab, field, open-ended), how assign particiapnt data, unique names, password, get contact,
//     get nickname, max participants, message optio chosen
//
function doInstOptions(ith) {
var ido,i11,m;

if (ith==11) {               // nochange
   afterWriteInstDesc(instrumentNames[0],1) ;
    return 0;
}

// description
instDesc=strip(document.instOptions.adesc.value) ;
if (instDesc=='') {
 alert('You did not enter a short description');
 return 0;
}

// instrument type
 il1=document.instOptions.type1.length ;
ido=0;
for (var m=0;m<il1;m++) {
 if (document.instOptions.type1[m].checked) ido=document.instOptions.type1[m].value;
}
if (ido==0) {
 alert('You must choose an instrument type');
 return 0;
}
instType=ido;

// assignData
il1=document.instOptions.type2.length ;
ido=0;
for (var m=0;m<il1;m++) {
 if (document.instOptions.type2[m].checked) ido=document.instOptions.type2[m].value;
}
if (ido==0) {
 alert('You must choose how to assign participant-specific data');
 return 0;
}
refDataType=ido;

// password
reqPassword=0;
if (document.instOptions.reqPassword.checked) reqPassword=1;
defPassword=(document.instOptions.defPassword.value) ;
if (reqPassword!==1) defPassword='0';
if (reqPassword=='1' && (defPassword=='' || defPassword=='0') ) defPassword='1';

// uniquenames
uniqueNames=0;
if (document.instOptions.nameCheck.checked) uniqueNames=1;

// get contact info
getContact=0;
if (document.instOptions.aContact.checked) getContact=1;

// get nickname
getNickname=0;
if (document.instOptions.aNickname.checked) getNickname=1;


// maxp articpants
maxUsers=strip(document.instOptions.maxUsers.value) ;
if (maxUsers=='') {
 maxUsers=0
 } else {
   if (isNaN(maxUsers)) {
      alert('You must enter a nunber for Max Participants (or leave it blank) ');
      return 0;
   }
 }

// message opts
il1=document.instOptions.mess1.length ;
ido=0;
for (var m=0;m<il1;m++) {
 if (document.instOptions.mess1[m].checked) ido=document.instOptions.mess1[m].value;
}
if (ido==0) {
 alert('You must choose a message option');
 return 0;
}
messOpt=ido;

//  write descriptor file -- NOTE: starts with template and makes changes. Hence, any changes "made by hand"
//  to other variables in an existing instrument specification file will be lost.

getGenericDescriptor(1);
return 0;

}



//====================
// fancy stuff for passwords
function changeDefPwdBox(qq) {
  if (qq) {
      document.instOptions.defPassword.readonly=true ;
  } else {
      document.instOptions.defPassword.readonly=false ;
  }
}

//====================
// read the generic descriptor XML file (save to descriptorXML global variable), and modify its values
function getGenericDescriptor(ido) {
var ido,ado,usePassword;

if (arguments.length==0) ido=1 ;
if (ido==1) {
    Get_xmlFile('/dsurvey/admins/setups/descriptor.xml',['descriptorXML','descStatus1','1'],'retreive descriptor file','getGenericDescriptor',2);
    return 0;
 }
if (descStatus1!==200) {
   alert('Error reading descriptor.xml template: '+descStatus1);
}

// description
ado=changeDescValue('description',instDesc);
if (ado!==1) return 0 ;

//  instrument type (instType):1=lab, 2=field, 3=openended
// lab:   idWhich=0 (client generated id),  ref_max=0
// field: idWhich=0 (client generatd),  ref_max=0
// openEnded: idWhich=1 (server generated), ref_max=READ
if (instType==1 || instType==2) {
  ado=changeDescValue('id_which',0);
     if (ado!==1) return 0 ;
  ado=changeDescValue('ref_max',0);
     if (ado!==1) return 0 ;
}
if (instType==2) {
  ado=changeDescValue('id_which',0);
     if (ado!==1) return 0 ;
  ado=changeDescValue('ref_max',0);
     if (ado!==1) return 0 ;
}
if (instType==3) {
  ado=changeDescValue('id_which',1);
  if (ado!==1) return 0 ;
  ado=changeDescValue('ref_max','READ');
     if (ado!==1) return 0 ;
}


// how to pull reference data
// 1: none
// 2: cycle
// 3: by name
if (refDataType==1) {                   //
  ado=changeDescValue('how_assign','none');
  if (ado!==1) return 0 ;
 ado=changeDescValue('allowed_users','0');
  if (ado!==1) return 0 ;
}
if (refDataType==2) {                   //
 ado=changeDescValue('how_assign','cycle');
   if (ado!==1) return 0 ;
 ado=changeDescValue('allowed_users','0');
  if (ado!==1) return 0 ;
}
if (refDataType==3) {                   //
  ado=changeDescValue('how_assign','0');
  if (ado!==1) return 0 ;
 ado=changeDescValue('allowed_users','=FILE');
  if (ado!==1) return 0 ;
}

// uniquenames
 ado=changeDescValue('name_check',uniqueNames);
  if (ado!==1) return 0 ;

// get_contact and get Nickname
 ado=changeDescValue('get_contact',getContact);
  if (ado!==1) return 0 ;
 ado=changeDescValue('get_NickName',getNickname);
  if (ado!==1) return 0 ;

// password
reqPassword=strip(reqPassword);
if (reqPassword=='0' || reqPassword=='') {   // password not requird
   usePassword='0';
} else {
  usePassword=strip(defPassword);
  if (usePassword=='0' || usePassword=='') usePassword='1';   // require overrides defPassword of '' or
}

ado=changeDescValue('use_password',usePassword);
if (ado!==1) return 0 ;

// maxUsers
if (strip(maxUsers)=='') maxUsers='0';
 ado=changeDescValue('max_users',maxUsers);
  if (ado!==1) return 0 ;

// messages messOpt
if (messOpt==1) {                   // disabled
  ado=changeDescValue('message_options','disable');
  if (ado!==1) return 0 ;
}
if (messOpt==2) {                   // notesonly
  ado=changeDescValue('message_options','enable,show,notesonly');
  if (ado!==1) return 0 ;
}
if (messOpt==3) {                   // sendAdmin
  ado=changeDescValue('message_options','enable,show,notes,adminSend');
  if (ado!==1) return 0 ;
}
if (messOpt==4) {                   // sendall
  ado=changeDescValue('message_options','enable,show,notes,sendAll');
  if (ado!==1) return 0 ;
}


var vv=new Date ;
var nowdate=vv.toLocaleDateString()+ ' ' +vv.toLocaleTimeString() ;

var vall=refDataType+','+instType+','+escape(instDesc) +','+escape(messOpt)+','+maxUsers+','+reqPassword+','+escape(defPassword)+','+uniqueNames+','+getContact+','+getNickname;

changeModified(' Modified by createWizard on '+nowdate,vall,'refDataType,instType,instDesc ,messOpt,maxUsers,reqPassword,defPassword,uniqueNames,getContact,getNickname',descriptorXML);

// in liew of changeModified(' modified by createWizard on '+
glob1=descriptorXML.innerHTML ;
glob2='<?xml version="1.0" encoding="UTF-8" ?>\n<!-- Descriptor file for: '+instrumentNames[0];
glob2=glob2+'\nCreated (by createWizard): '+nowdate+' --> \n\n<descriptor>\n ';
glob1=glob2+glob1+'\n</descriptor>';

toWrite=postNewDescriptor+'&file='+instrumentNames[0]+'.XML&content='+escape(glob1);

Post_toServer(postFileURL,toWrite,'saveNewDescriptor','saving new XML descriptor file','afterWriteInstDesc',instrumentNames[0]) ;
return 1;


}

//===============
// done writing descriptor, so no ask about parameter files
function afterWriteInstDesc(aname,nochange) {
if (arguments.length<2) nochange=0 ;
hideDivs(1);

if (nochange==1) {
   writeToStatus(' No changes to instrument descriptor file for  '+aname);
 } else {
    if (instDescFrom=0) {
      writeToStatus(' Status of writing instrument descriptor file for  '+aname+'='+saveNewDescriptor);
   } else {
     writeToStatus(' Status of updating instrument descriptor file for '+aname+'='+saveNewDescriptor);
   }
}                      // == 0

 toget=getInstrumentURL+instrumentNames[0]+'.xml';
 Get_xmlFile(toget,'instDescNode','re retrieving xml instrument file ','changeInstParams',1);


// changeInstParams(1) ;
 return 0;
}

// =======================
function changeDescValue(avar,avalue) {
dd=E2_getNodes(descriptorXML,avar,1);
if (dd.length<1) {
  alert('Error: no <'+avar+'> in descriptor.xml');
  return 0;
}
dd2=E2_getNodes(dd[0],'value',1);
if (dd2.length<1) {
  alert('Error: no <'+avar+'><VALUE> in descriptor.xml');
  return 0;
}
dd2[0].firstChild.nodeValue=avalue ;
return 1 ;

}


//=================================================================================================================
// =================================== general & refereence parameters modifiy/create functions ========================
//=================================================================================================================

// ask which parameter files to change
function changeInstParams(ith) {
 var i1;
 hideDivs(1);
 displayDiv('show3','block');

//refDataType,instType,instDesc ,messOpt,maxUsers,reqPassword,defPassword,uniqueNames,getContact,getNickname

displayDiv('allowedChoiceNo','block') ;
displayDiv('allowedChoice','none')

if (reqPassword!=='0' && reqPassword!=='') {
    displayDiv('allowedUsersPassword','block');
}
if (refDataType==3) {
    displayDiv('allowedUsersRef','block');
    displayDiv('allowedChoice','block') ;
    displayDiv('allowedChoiceNo','none') ;
}

i1=document.getElementById('show3Name');
i1.innerHTML=instrumentNames[0];

getParamsFiles(1);                      // refresh (perhaps they have changed?)

// read existing general and reference params (or note if they don't exist)

return 0 ;
}


// =======================================
// retrieve general & reference & allowedUsers paramters files for an instrument
// retreive to allowedNode,refParamsNode,generalParamsNode
function getParamsFiles(i1,returnInit) {

if (arguments.length<2) returnInit=0;   // returnInit=1 means "return to instClicked" after all files read

var usenam,toget,id1;
if (i1==1) {
  paramFilesExist=[];
  usenam=instrumentNames[0];
  writeToStatus('About to retrieve parameter files for '+usenam);
  toget=getInstrumentGeneralXML_1.replace(/\$NAME\$/g,usenam) ;
  Get_xmlFile([toget,1],['generalParamsNode','generalParamsCode','1'],'retrieving a general data file ','getParamsFiles',2,returnInit) ;
  return 0;
}
if (i1==2) {
  id1=document.getElementById('genParamsStatus');
  if (generalParamsCode!='200') {
     id1.innerHTML='Create new ';
  } else {
     id1.innerHTML='Modify existing ';
     paramFilesExist=paramFilesExist.concat('general');
  }

  usenam=instrumentNames[0];
  toget=getInstrumentReferenceXML_1.replace(/\$NAME\$/g,usenam) ;
  Get_xmlFile([toget,1],['refParamsNode','refParamsCode','1'],'retrieving a reference data file ','getParamsFiles',3,returnInit) ;
  return 0;
}

if (i1==3) {
  id1=document.getElementById('refParamsStatus');
  if (refParamsCode!='200') {
     id1.innerHTML='Create new ';
  } else {
     id1.innerHTML='Modify existing ';
     paramFilesExist=paramFilesExist.concat('reference');
  }

  usenam=instrumentNames[0];
  toget=getInstrumentAllowedUsersXML_1.replace(/\$NAME\$/g,usenam) ;
  Get_xmlFile([toget,1],['allowedNode','allowedCode','1'],'retrieving allowedUsers file ','getParamsFiles',4,returnInit) ;
  return 0;

}

if (i1==4) {
  id1=document.getElementById('allowedStatus');
  if (allowedCode!='200') {
     id1.innerHTML='Create new ';
  } else {
     id1.innerHTML='Modify existing ';
     paramFilesExist=paramFilesExist.concat('allowedUsers');
  }

  writeToStatus(' ...   parameter files retrieved: '+paramFilesExist );

// caleld by instClicked? Then return to it
   if (returnInit==1) instClicked(instrumentNames[0],0,3);

}

return 0;

}

//==============================
// modify  allowedUsers file for an instrument
function makeAllowedUsers(i0) {
 var i1,datarecs ;
 hideDivs(1);
displayDiv('show4c','block');
i1=document.getElementById('show4cName');
i1.innerHTML=instrumentNames[0];

if (refParamsNode==null) {
    alert('Sorry, you must first create participant specific parameters before you can specify allowedUsers');
    displayDiv('show4c1','none');
    displayDiv('show4','none');
    changeInstParams(1);
    return 0;
}

datarecs=readRefParamsNode(1);
refIdsList=datarecs['refidslist'];
refIds=datarecs['refids'] ;

refDatarecs=datarecs ;

if (allowedCode!='200' || i0=='2') {        // i0=2 means "force creation
  displayDiv('show4c','block');
  displayDiv('show4c1','block');   // show the "how many users     " input box
  displayDiv('show4c2','none');
} else {
  changeAllowedUsers(1);             // table of existing parameters
}
return 0;

}


//================
//  fill table with values from existing variables
function changeAllowedUsers(i1){
  displayDiv('show4c','block');
  displayDiv('show4c1','none');
  displayDiv('show4c2','block');

 dvals=readAllowedUsers(1);
 lastMod=readModified(allowedNode,'descInfo');
 writeToStatus('Allowed users last modified: '+lastMod);

 changeAllowedUsersNew(0,dvals) ;

 return 0;
}


//================
// read allowedUsers data into an object
function readAllowedUsers(i) {
 var datarecs={},dd,dd2,dd3,m,mm,aname,tmp=[] ;
 var aname,apwd,refid,adesc ;

 dd=E2_getNodes(allowedNode,'users',1);

  if (dd.length>0) {
    dd2=E2_getNodes(dd[0],'user');
    for (var mm=0;mm<dd2.length;mm++) {
       aname='';apwd='';refid='';adesc='';

       dd3=E2_getNodes(dd2[mm],'NAME',1);
       if (dd3.length==0) continue ;
       aname=dd3[0].innerHTML;

       if (aname=='') continue ;
       aname=strip(aname).toUpperCase() ;

       tmp=tmp.concat(aname);
       datarecs[aname]={};

       dd3=E2_getNodes(dd2[mm],'PASSWORD',1);
       if (dd3.length==0) continue ;
       apwd=dd3[0].innerHTML;
       datarecs[aname].pwd=apwd;

       dd3=E2_getNodes(dd2[mm],'REFID',1);
       if (dd3.length==0) continue ;
       arefid=dd3[0].innerHTML;
       datarecs[aname].refid=arefid;

       dd3=E2_getNodes(dd2[mm],'COMMENT',1);
       if (dd3.length==0) continue ;
       adesc=dd3[0].innerHTML;
       datarecs[aname].desc=adesc;

    }
  }
  datarecs._list=tmp ;
  return datarecs ;
}



// ================= create a form for specifying allowedUsers entries
// isnew=0 means "use values in the  dvals array
function changeAllowedUsersNew(isnew,dvals) {

  var nallowed,atable,arow,m0,arow,acell,vv2,bname,apwd ;
  if (isnew==1) {
     nallowed=document.show4c1Form.numAllowedRecords.value
  } else {
     nallowed=dvals._list.length ;
  }

  atable='<form name="allowedUsersTable"> \n';
  if (isnew==1) {
     atable=atable+'<input type="hidden" name="ismod" value="0" />\n';
  } else {
     atable=atable+'<input type="hidden" name="ismod" value="1" />\n';
  }

  atable=atable+' <table cellpadding="5" rules="rows"> \n';
  atable=atable+'<tr><td>#';
  atable=atable+'</td><th>Name</th><th>Password</th><th>Reference<br/> record</th><th>Comment</th></tr>\n'

  apwd=strip(getDescriptorVar('use_password','..'));
  if (apwd=='..') apwd='';

  for (var m0=0;m0<nallowed;m0++) {
    m=m0+1;


    if (isnew==0)  {
       arow='<tr><td><span style="font-size:70%">'+m+'</span><input title="check to remove this entry" type="checkbox" value="1" name="remUser'+m+'"/></td>';
    } else {
       arow='<tr><td><span style="font-size:70%">'+m+'</span></td>';
    }

    bname='';
    if (isnew==0) bname=dvals._list[m0];
    arow=arow+'<td style="background-color:#efefef"><input title="Participant name" type="value" size="35" name="userName'+m+'" value="'+bname+'">' ;

    vv2='';
    if (isnew==0) vv2=strip(dvals[bname].pwd) ;
    if (vv2=='1') vv2='';
    if (apwd!=='') {
       arow=arow+'<td style="background-color:#efefef"><input  title="Password (optional). If not specified the generic password ('+apwd+') is used; if \'0\' then no password is needed)" type="value" size="15" name="userPwd'+m+'" value="'+vv2+'">';
    } else {
       arow=arow+'<td style="background-color:#efefef"><input style="background-color:#dddddd" title="Password (note that use of password is NOT currently enabled)" type="value" size="15" name="userPwd'+m+'" value="'+vv2+'">';
    }

    vv2='';
    if (isnew==0) vv2=dvals[bname].refid ;
    arow=arow+'<td style="background-color:#efefef"><input title="Record id  type="value" size="5" name="userRefId'+m+'" value="'+vv2+'">';

    vv2='';
    if (isnew==0) vv2=dvals[bname].desc ;
    arow=arow+'<td style="background-color:#efefef"><input title="Comment (optional) type="value" size="35" name="userDesc'+m+'" value="'+vv2+'"></td>';
    atable=atable+arow+'</tr>\n';
  }

  if (isnew==0) {
     arow='';
     m=parseInt(nallowed)+1;
     arow=arow+'<tr><td><tt>'+m+'</tt><span style="background-color:#abcdab"><em>new</em></span></td>';
     arow=arow+'<td style="background-color:#efefef"><input  type="value" size="35" title="You can add a new participant on this row (leave blank to NOT add a new participant)" name="userName'+m+'" value="">';
     arow=arow+'<td style="background-color:#efefef"><input title="Password" type="value" size="15" name="userPwd'+m+'" value="">';
     arow=arow+'<td style="background-color:#efefef"><input title="Record id  type="value" size="5" name="userRefId'+m+'" value="">';
     arow=arow+'<td style="background-color:#efefef"><input title="Comment (optional) type="value" size="35" name="userDesc'+m+'" value=""></td>';
     atable=atable+arow+'</tr>\n' ;
  }

  atable=atable+'</table>';
  atable=atable+'<input name="gg1" type="button" value="Save these allowed users" onClick="changeAllowedUsersSave(1,'+nallowed+')" />';
  atable=atable+'  <input name="can" type="button" value="cancel" title="Do not save changes" onClick="changeInstParams(1)" /> ';
  atable=atable+ '<span style="margin-left:20px;border:1px solid cyan">Or, do you want to <a title="Click here to create, from scratch, a new set of allowedUsers (prior allowedUser records will be discarded)" href="#" onClick="makeAllowedUsers(2); return false">generate a new set of allowed participants</a>';

  atable=atable+'<div style="margin:15px 5% 5px 5%;margin:1px dotted cyan"><b>Notes:</b>';
  atable=atable+'<ul>'
  atable=atable+'<li>Particpant names are case-insensitive</li><li>The reference record points to a record in the reference data</li>';
  if (apwd!=='0' && apwd!=='') {
     atable=atable+'<li>If you do not specify a password, the default password ('+apwd+') will be used for a participant.<br/>A password of <tt>0</tt> means <em>no password required for this participant</em></li>\n';
  } else {
     atable=atable+'<li>Currently, use of passwords is <b>not</b> specified (in the <b>specify features of this instrument</b> page)' ;
     atable=atable+'<li>If you intend to enable passwords in the future, there is nothing wrong with specifying passwords now (say if you intend to enable passwords in the future)</li>\n';
  }
   atable=atable+'<li>Values for the  <b>reference record</b> should be one of the following: ';
   atable=atable+'<div style="background-color:#cdcdcd;border:1px solid #dcdcdc">'+refIdsList['all'].join(' ')+'</div></li>';
  atable=atable+'</ul>\n';
  atable=atable+'</div>';
  atable=atable+'</form> ';
 id1=document.getElementById('show4c2');
 id1.innerHTML=atable;


 displayDiv('show4c1','none');
 displayDiv('show4c2','block');

}

// ========================
// save changes to allowed users
//       remUser userName userPwd userRefId userDesc
//
//              <user  ><name>name</name> <password>apwd</password>   <refid>referenceID</refid>
//                        <comment> optional comment</comment>
//               </user>

function changeAllowedUsersSave(i0,nallowed) {
 var ismod,m,auser,apwd,arefid,adesc,stuff,rlist,nn0;
 var iusers=[];
 nn0=nallowed;
 ismod=document.allowedUsersTable['ismod'].value;
 if (ismod=='1')  nn0=nn0+1;

if (i0==1) {                           // create allowedUsers file
   stuff='<?xml version="1.0" encoding="UTF-8" ?>\n';
   stuff=stuff+'<!-- allowedUsers file for instrument '+instrumentNames[0]+' -->\n';
   stuff=stuff+'<allowedUsers>\n\n';
   stuff=stuff+'\n\n<users>\n\n';
    for (var m=1;m<=nn0;m++) {                // add 1 for "new" var stuff
      aname=document.allowedUsersTable['userName'+m].value; aname=strip(aname).toUpperCase();
      if (aname=='') continue ;
      if (ismod==1 && m!==nallowed+1) {                                  // a remove button exists (and not a "new entry" row
         qrem=document.allowedUsersTable['remUser'+m].checked;
         if (qrem) continue ;
      }
      apwd=document.allowedUsersTable['userPwd'+m].value; apwd=strip(apwd);
         if (apwd=='')  apwd='1'  ;
      arefid=document.allowedUsersTable['userRefId'+m].value; arefid=strip(arefid).toUpperCase();
      if (arefid=='') {
         alert('Error: you did not specify a reference ID for: '+aname);
         return 0;
      }
      if (typeof(refIdsList[arefid])=='undefined') {
          alert('Error: reference ID '+arefid+' (for user '+aname+') is not specified (in the database of participant specific paramters) ');
          return 0;
      }
      iusers=iusers.concat(arefid) ;
      adesc=document.allowedUsersTable['userDesc'+m].value; adesc=strip(adesc);

      arow='<user>  <name>'+aname+'</name> <password>'+apwd+'</password>  <refid>'+arefid+'</refid>\n<comment>'+adesc+'</comment>\n</user>\n';

      stuff=stuff+arow;
  }
  stuff=stuff+'\n\n</users>\n\n';

  var vv=new Date ;
  var nowdate=vv.toLocaleDateString()+ ' ' +vv.toLocaleTimeString() ;

  var  tmp='\n<createWizard><descInfo>Modified by createWizard on '+nowdate+'</descInfo>\n<desc>'+iusers.length+'</desc><value>'+iusers.join(' ')+'</value>\n</createWizard>\n';
  stuff=stuff+tmp;
  stuff=stuff+'\n</allowedUsers>\n' ;

  var toWrite=postAllowedUsersData+'&name='+instrumentNames[0]+'&content='+escape(stuff);

   Post_toServer(postFileURL2,toWrite,'genAllowedUsersStatus','saving allowedUsers','changeAllowedUsersSave',2) ;
   return 0;

}           // i0=1

if (i0==2) {
writeToStatus('Saving allowedUsers file for '+instrumentNames[0]+': '+genAllowedUsersStatus);

alert('Note: the allowedUsers file you just created is instrument specific. If each session has its own set of participants, you should modify the session-specific allowedUsers file (after you create a new session).');

displayDiv('show4c1','none');
displayDiv('show4','none');
changeInstParams(1);

}


}
//                        createWizard


//==============================
// modify general paramters file for an instrument
function makeGenData(i0) {

hideDivs(1);
displayDiv('show4','block');

var i1=document.getElementById('show4aName');
i1.innerHTML=instrumentNames[0];
if (generalParamsCode!='200' || i0=='2') {        // i0=2 means "force creation of new gen parameters file
  displayDiv('show4a2','none');   // show the "how many parameters" input box
  displayDiv('show4a1','block');   // show the "how many parameters" input box
} else {
  changeGenParams(1);             // table of existing parameters
}
return 0;
}

//  fill table with values from existing variables
function changeGenParams(i1){
  var dd,lastMod,iarr,vList,vallist,arraylist,desclist,iarr,m0;
  var atable,arow,nrows,m,aname,adesc,id1,dd2,noden,nodev,aval,arvals;
  var vList=[],  vallist={},  arraylist={},  desclist={};

  dd=E2_getNodes(generalParamsNode,'general',1);
  if (dd.length<1) {
      alertD('Error: no <general> in general parameters file ');
      return 0;
  }

  dd2=E2_getNodes(dd[0],'*');
  for (var m=0;m<dd2.length;m++) {
    noden=strip(dd2[m].nodeName).toUpperCase();
    nodev=strip(dd2[m].innerHTML);
    if (noden=='DESC') {
      aname=strip(getAttributes(dd2[m],'value','0')).toUpperCase();
      desclist[aname]=nodev;
    } else {
      vList[vList.length]=noden;
      vallist[noden]=nodev ;
      arraylist[noden]=getAttributes(dd2[m],'array','-1');
    }
  }

  atable='<form name="genParamsTable"> \n';
  atable=atable+'<input type="hidden" name="ismod" value="1" />\n';
  atable=atable+' <table cellpadding="5" rules="rows"> \n';
  arow='<tr><td><span style="font-size:70%" title="check to remove this variable"># [remove]</span></td><th>Variable<br/>Name</th><th>value</th><th>Description</th></tr>'
  atable=atable+arow+'\n';
  nrows=vList.length;

  for (var m0=0;m0<nrows;m0++) {
    m=m0+1;
    aname=vList[m0];
    if (typeof(desclist[aname])=='undefined') {
      adesc='n.a.';
    } else {
      adesc=desclist[aname];
    }
    iarr=arraylist[aname];
    aval=vallist[aname];
    arow='<tr><td><span style="font-size:70%">'+m+'</span><input title="check to remove this variable" type="checkbox" value="1" name="remVar'+m+'"/></td>';
    if (iarr<1) {
       arow=arow+'<td style="background-color:#efefef"><input title="Name of variable" readonly type="value" size="16" name="genVar'+m+'" value="'+aname+'">';
    } else {
       arvals=aval.split(',');
       iarr=arvals.length;
       arow=arow+'<td style="background-color:#efefef"><input title="Name of '+iarr+' element array variable" readonly type="value" size="16" name="genVar'+m+'" value="'+aname+'"><span style="font-size:80%" title="array variable"> ['+iarr+']</span>';
    }
    arow=arow+'<input type="hidden" value="'+iarr+'"  name="genArray'+m+'" ></td>';
    if (iarr<0) {
       arow=arow+'<td><input title="Value." type="value" size="25" name="genValue'+m+'" value="'+aval+'"></td>';
    } else {
        arow=arow+'<td>';
        for (var mv0=0;mv0<iarr;mv0++) {
          mv=mv0+1;
          arow=arow+'<input title="Element '+mv+' value" type="value" size="8" name="genValue'+m+'_'+mv+'" value="'+arvals[mv0]+'">';
        }
        arow=arow+'</td>';
    }
    arow=arow+'<td style="background-color:#efefef"><input title="Description of this variable" readonly type="value" size="35" name="genDesc'+m+'" value="'+adesc+'"></td>';
    atable=atable+arow+'</tr>\n';
  }

// for new variables
  arow='<tr bgcolor="#abcdab"><td><em>new</em></td>';
   m=nrows+1;
  arow=arow+'<td><input title="Name of NEW variable (leave blank if you do NOT want to add variable)"  type="value" size="16" name="genVar'+m+'" value="">';
  arow=arow+'<td><input title="Value (CSV if you want new variable to be an array)." type="value" size="45" name="genValue'+m+'" value=""></td>';
  arow=arow+'<td ><input title="Description of this variable"   type="value" size="35" name="genDesc'+m+'" value=""></td>';
  arow=arow+'</tr>\n';
  atable=atable+arow ;

  atable=atable+'</table>';
  atable=atable+'<input name="gg1" type="button" value="Save these variables" onClick="changeGenParamsSave(1,'+nrows+')" />';
  atable=atable+'  <input name="can" type="button" value="cancel" title="Do not save changes" onClick="changeInstParams(1)" /> ';
  atable=atable+ '<span style="margin-left:20px;border:1px solid cyan">Or, do you want to <a title="Click here to create, from scratch, a new set of general paramters (prior general parameters will be discarded)" href="#" onClick="makeGenData(2); return false">generate a new set of general parameters</a>';

  atable=atable+'<div style="margin:15px 5% 5px 5%;margin:1px dotted cyan">Note: if you want to add a new variable, enter its name, etc. on the ';
  atable=atable+' <span style="background-color:#abcdab"><em>new ...</em></span>  row of the table (or leave it blank to NOT enter a new variable).</div>';
  atable=atable+'</form> ';
 id1=document.getElementById('show4a2');
 id1.innerHTML=atable;



 displayDiv('show4a1','none');
 displayDiv('show4a2','block');
 lastMod=readModified(generalParamsNode,'descInfo');
 writeToStatus('General parameters last modified:'+lastMod);

}

//  create table with specified number of rows (for general parametesr)

function changeGenParamsNew(nrows){
  var n,atable,arow,acell,id2,goo;
  nrows=strip(nrows);
  if (isNaN(nrows)){
     alert("Error: you must enter a number ");
     return 0;
  }
  atable='<form name="genParamsTable">  \n';
  atable=atable+'<input type="hidden" name="ismod" value="0" />\n';
  atable=atable+'<table cellpadding="5" rules="rows"> \n';
  arow='<tr><td><span style="font-size:70%">#</span></td><th>Variable<br/>Name</th><th>Array<br/>Length</th><th>value</th><th>Description</th></tr>'
  atable=atable+arow+'\n';
  for (var m=1;m<=nrows;m++) {
    arow='<tr><td><span style="font-size:70%">'+m+'</span></td>';
    arow=arow+'<td><input title="Enter variable name (no spaces!)(leave blank to skip) " type="value" size="16" name="genVar'+m+'" value=""></td>';
    arow=arow+'<td><input title="If this is an array, enter array length (0 or blank means scalar)" type="value" size="9" name="genArray'+m+'" value=""></td>';
    arow=arow+'<td><input title="Value. If array, seperate values with commas " type="value" size="25" name="genValue'+m+'" value=""></td>';
    arow=arow+'<td><input title="Description of this variable. " type="value" size="55" name="genDesc'+m+'" value=""></td>';
    atable=atable+arow+'</tr>\n';
  }
  atable=atable+'</table>';
  m=parseInt(nrows)+1;
  atable=atable+'<input type="hidden" value="" name="genVar'+m+'"/>';  // a hack to prevent problems with new vars

  atable=atable+'<input name="gg1" type="button" value="Save these variables" onClick="changeGenParamsSave(1,'+nrows+')" /></form> ';
 id1=document.getElementById('show4a2');
 id1.innerHTML=atable;
 displayDiv('show4a1','none');
 displayDiv('show4a2','block');
 writeToStatus('Creating new general parameters file ('+nrows+' variables)');
 Global_Stuff=atable;
// Display_Content('Global_Stuff','xx');

 return 1 ;
}

//  ========= save the gen params

function changeGenParamsSave(i0,nrows){
 var    stuff='',m,aname,aaray,avalue,adesc,tmp,varlist='',mv,nvars=0,qrem ;
 var ismod;
 ismod=document.genParamsTable['ismod'].value;

if (i0==1) {                           // create general params file
   stuff='<?xml version="1.0" encoding="UTF-8" ?>\n';
   stuff=stuff+'<!-- general parameters file for '+instrumentNames[0]+' -->\n';
   stuff=stuff+'<parameters>\n\n<general>\n';
   for (var m=1;m<=nrows+1;m++) {                // add 1 for "new" var stuff
      aname=document.genParamsTable['genVar'+m].value; aname=strip(aname).toUpperCase();
      if (aname=='') continue ;
      if (ismod==1 && m!==nrows+1) {                                  // a remove button exists
         qrem=document.genParamsTable['remVar'+m].checked;
         if (qrem) continue ;
      }
      nvars++ ;
        if (varlist=='') {
           varlist=aname
        } else {
           varlist=varlist+','+aname;
        }

      if (m!==nrows+1 ){
        aarray=document.genParamsTable['genArray'+m].value;
        aarray=strip(aarray); if (aarray=='') aarray=0;
        if (isNaN(aarray)) {
            alert('Error: you entered a non-number in the array field for '+aname);
            return 0;
        }
      }
//      alert(m+',===='+aarray);
      if (aarray<0 || ismod!=='1' || m==nrows+1 ){
         avalue=strip(document.genParamsTable['genValue'+m].value);
         if (avalue.indexOf(',')>-1) {
             goo=avalue.split(','); aarray=goo.length;
         }
      } else {
         avalue='';
         for (var mv=1;mv<=aarray;mv++) {
           aval1=document.genParamsTable['genValue'+m+'_'+mv].value;
           if (avalue=='') {
             avalue=escape(strip(aval1));
           } else {
             avalue=avalue+','+escape(strip(aval1));
           }
        }    //for
      }
      adesc=document.genParamsTable['genDesc'+m].value;

      arow='<desc value="'+aname+'">'+adesc+'</desc>\n';

      if (aarray<=1) {
         arow=arow+'<'+aname+'>'+avalue+'</'+aname+'>\n\n';
      } else {
         tmp=avalue.split(',');
         if (tmp.length!=aarray) {
            alert('Error: array variable '+aname+' has '+tmp.length+' elements, but you specified a length of '+aarray);
            return 0;
         }
         arow=arow+'<'+aname+' array="1">'+avalue+'</'+aname+'>\n\n';
      }
      stuff=stuff+arow;
   }
   stuff=stuff+'\n</general>';

  var vv=new Date ;
  var nowdate=vv.toLocaleDateString()+ ' ' +vv.toLocaleTimeString() ;

 var  tmp='\n<createWizard><descInfo>Modified by createWizard on '+nowdate+'</descInfo>\n<desc>'+nvars+'</desc><value>'+varlist+'</value>\n</createWizard>\n';
 stuff=stuff+tmp;
 stuff=stuff+'\n</parameters>\n' ;

 toWrite=postGeneralData+'&name='+instrumentNames[0]+'&content='+escape(stuff);

 Post_toServer(postFileURL2,toWrite,'genParamsStatus','saving general params','changeGenParamsSave',2) ;
 return 0;

}

writeToStatus('Saving general parameters file for '+instrumentNames[0]+': '+genParamsStatus);

displayDiv('show4a1','none');
displayDiv('show4','none');
changeInstParams(1);


}


//==============================
// modify reference paramters file for an instrument
function makeRefData(i01) {
hideDivs(1);
displayDiv('show4b','block');
var i1=document.getElementById('show4bName');
i1.innerHTML=instrumentNames[0];
nRefParams=0;

if (refParamsCode!='200' || i01==2) {
  displayDiv('show4b1','block');   // show the "how many parameters" input box
  displayDiv('show4b2','none');
} else {
   changeRefParams(1);             // read ref vars and  table of existing parameters
}
return 0;
}


//==============================
//  create table using current ref params file
function changeRefParams(i0,nrecs,nparams,data) {
var nrecs,vv,varlist,nparams,dd,dd2,aname,desclist,lastmod,refNode,datarecs;
var aid,aelem,mm,dd3;

refNode=E2_getNodes(refParamsNode,'reference',1);
if (refNode.length<0) {
    alert(dd.length+' Error: no <REFERENCE> in reference data file '+refParamsNode.innerHTML);
    return 0;
}
refNode=refNode[0];
lastmod=readModified(refParamsNode,'descInfo') ;
if (i0!==3) writeToStatus('Reference data last modified: '+lastmod);
nrecs=readModified(refParamsNode,'desc') ;
vv=strip(readModified(refParamsNode,'value')) ;

vv='0,'+vv.toUpperCase();
varlist=vv.split(',');

nparams=varlist.length-1 ;
dd=E2_getNodes(refNode,'DESCRIPTIONS',1);
if (dd.length<1) {
    alert(dd.length+' Error: no <DESCRIPTIONS> in reference data file '+refParamsNode.innerHTML);
    return 0;
}

dd2=E2_getNodes(dd[0],'var');
desclist=[0];

for (m=0;m<dd2.length;m++) {
  aname=strip(getAttributes(dd2[m],'name','')).toUpperCase();

  if (aname!=varlist[m+1]) {
      alert('Error: mistmatch in descriptions order :: var, desc name: '+varlist[m+1]+','+aname);
      return 0;
  }
  desclist[m+1]=dd2[m].innerHTML;
}
refVarList=varlist;
refDescList=desclist;

datarecs=readRefParamsNode(1);

refIdsList=datarecs['refidslist'];
refIds=datarecs['refids'] ;
refDatarecs=datarecs ;

if (i0==3) {                            // after saving, so go back to chose-which-data-to-modify menu
   writeToStatus('Re-retrieved reference parameters (for '+refIds.length+' records) ');
    changeInstParams(1);
    return 0;
}

displayDiv('show4b2','block');
changeRefParamsNew(22,nrecs,nparams,datarecs) ;
return 0;
}


//==============================
//  create table with specified number of rows & vars as read from show4b1Form form (for ref parametesr)
function changeRefParamsNew(i0,nrecs,nparams,datarecs) {
  var n,atable,arow,acell,id2,id1,igoo,desclist,varlist,tmp2;
  var m,n,acolor,colorm,tmp,vname,vnameM,vnameE,vnames,tvname,fname ;
  var newVarName,newVarDesc,usenam,toget;

  var rcolors=['#b1b1b1','#bbbbbb','#c1c1c1','#cccccc','d2d2d2','#dddddd','#e5e5e5','#eeeeee','#f5f5f5'];

  if (i0==1) {                // aks for variable names

    nrecs=strip(document.show4b1Form.numRefRecords.value) ;
    nparams=strip(document.show4b1Form.numRefParams.value) ;
    if (isNaN(nrecs)){
       s("Error: you must enter a number for the number of records ");
       return 0;
    }
    if (isNaN(nparams)){
       alert("Error: you must enter a number for the number of parameters ");
     return 0;
    }

    atable='<form name="refVarsTable"> <b>First, specify variable names and descriptions....</b> \n';
    atable=atable+'<input type="hidden" name="ismod" value="0" />\n';
    atable=atable+'<table cellpadding="5" rules="rows"> \n';
    arow='<tr><td><span style="font-size:70%">#</span></td><th>Variable<br/>Name</th><th>Description</th></tr>'
    atable=atable+arow+'\n';
    for (var m=1;m<=nparams;m++) {
      arow='<tr><td><span style="font-size:70%">'+m+'</span></td>';
     arow=arow+'<td><input title="Enter variable name (no spaces!) -- you can specify an array element using [n]. Leave blank to skip " type="value" size="16" name="refVar'+m+'" value=""></td>';
      arow=arow+'<td><input title="Description of this variable. " type="value" size="65" name="refDesc'+m+'" value=""></td>';
      atable=atable+arow+'</tr>\n';
    }
    atable=atable+'</table>';
    atable=atable+'<input name="gg1" type="button" value="Save these variables names" onClick="changeRefParamsNew(2,'+nrecs+','+nparams+')" /></form> ';
    atable=atable+'<tt>Note on variable names:</tt> you can specify array-like variable names by including a <tt>[n]</tt> ';
    atable=atable+'at the end of the variable name. Examples: <tt>xx[1]</tt> and <tt>xx[2]</tt>.\n';

   id1=document.getElementById('show4b2');
   id1.innerHTML=atable;

    displayDiv('show4b1','none');
    displayDiv('show4b2','block');

   writeToStatus('Creating reference '+nparams+' variables ');
   return 1 ;
}                             // io=1

if (i0==2 || i0==22) {                     // ask for values for all parameters and all records

  atable='<form name="refParamsTable">';
  atable=atable+' <b>Specify reference variable values ...</b> \n';
  atable=atable+'<span style="border:1px solid cyan">Or, <a title="Click to enter values using a comma-seperated-values format" href="#" onClick="enterRefCSV(1);return false">use CSV</a></span> ';
  atable=atable+'<input type="hidden" name="ismod" value="0" />\n';
  varlist=[];
  desclist=[];

  csvStuff='';  // global used to populate csv entry textArea

  atable=atable+'<table cellpadding="5" rules="rows"> \n';

  arow='<tr><td bgcolor="#ababab">RecordID</td>';
  atable=atable+arow ;
  arow='<td><table><tr>';
  igoo=0;
  colorm=-1 ;

  for (var m=1;m<=nparams;m++) {                      // header row
    igoo++;
    if (igoo>5) {
        arow=arow+'</tr>';
        atable=atable+arow;
        arow='<tr>';
       igoo=1;
    }

    if (i0==2) {
      varlist[m]=document.refVarsTable['refVar'+m].value ;
      desclist[m]=document.refVarsTable['refDesc'+m].value ;
    } else {
       varlist[m]=refVarList[m];
       desclist[m]=refDescList[m];
    }
    colorm++ ;
    if (colorm>=rcolors.length) colorm=0;
    acolor=rcolors[colorm];
//alert('m== '+m+','+varlist[m]);
    arow=arow+'<th><div style="margin:4px"><input title="'+desclist[m]+'" type="value" size="14" value="'+varlist[m]+'" readonly="1" style="background-color:'+acolor+'" /></div></th>';
  }
   arow=arow+'<td ><div style="padding:3px;background-color:#eeeeaa"><input name="refNewVar" title="Check to add a new variable" type="checkbox" ></div></td';

  arow=arow+'</tr></table></td></tr>';
  atable=atable+arow ;

  for (var n=1;n<=nrecs;n++) {                                            // do the data records
    arow='<tr><td bgcolor="#ababab"><tt>'+n+'</tt></td>';
    csvStuff=csvStuff+n;

//    arow='<tr><td bgcolor="#ababab"><tt>'+n+'</tt> <span style="font-size:80%"><input type="checkbox" title="Check this remove this record" name="refRemove'+n+'"">Drop</span></td>';
    atable=atable+arow ;
    arow='<td><table>\n<tr>';
    igoo=0; colorm=-1 ;
    for (var m=1;m<=nparams;m++) {
      igoo++;
      if (igoo>5) {
        arow=arow+'</tr>';
        atable=atable+arow;
        arow='<tr>';
        igoo=1;
      }

      colorm++ ;
      if (colorm>=rcolors.length) colorm=0;
      acolor=rcolors[colorm];
      fname=varlist[m]+'.'+n ;
      if (i0==22) {
        if (typeof(datarecs[fname])=='undefined') {
           vv2='';
        } else {
           vv2=datarecs[fname];
        }
      } else {
         vv2='';
      }
      if (vv2.indexOf(',')>-1) {
          csvStuff=csvStuff+',"'+vv2+'"';
      } else {
           csvStuff=csvStuff+','+vv2;
      }
      arow=arow+'<td bgcolor="'+acolor+'"><div style="margin:4px"><input size="14" type="value" value="'+vv2+'" name="'+fname+'" title="'+varlist[m]+' for record '+n+'" /></div></td>';
    }
   arow=arow+'<td> <div style="padding:3px;background-color:#eeeeaa"><input size="14" type="value" value="" name="refNew.'+n+'" title="New variable for record '+n+'" /></div></td>';

   arow=arow+'</tr></table>\n</td></tr>';
   csvStuff=csvStuff+'\n';
   atable=atable+arow ;
  }

// add a new record?
  n=parseInt(nrecs)+1 ;
  arow='\n<tr bgcolor="#abcdab"><td bgcolor="#ababab"><input type="checkbox" title="Check this to add a new record" name="refNewRecord">New?</td>';
  atable=atable+arow ;
  arow='<td><table><tr>';
  igoo=0; colorm=-1 ;
  for (var m=1;m<=nparams;m++) {
      igoo++;
      if (igoo>5) {
        arow=arow+'</tr>';
        atable=atable+arow;
        arow='<tr>';
        igoo=1;
      }

      colorm++ ;
      if (colorm>=rcolors.length) colorm=0;
      acolor=rcolors[colorm];
      vv2='';
      fname= varlist[m]+'.'+n ;
      arow=arow+'<td bgcolor="'+acolor+'"><div style="margin:4px"><input size="14" type="value" value="'+vv2+'" name="'+fname+'" title="'+varlist[m]+' for new record " /></div></td>';
  }

 arow=arow+'<td> <div style="padding:3px;background-color:#eeeeaa"><input size="14" type="value" value="" name="refNew.'+n+'" title="New variable for new record " /></div></td>';

 arow=arow+'\n</tr></table></td></tr>';

 atable=atable+arow ;


// done with table
  atable=atable+'</table>';
  atable=atable+'<input name="gg1" type="button" value="Save these values" onClick="changeRefParamsNew(3,'+nrecs+','+nparams+')" />';
  atable=atable+'  <input name="can" type="button" value="cancel" title="Do not save changes" onClick="changeInstParams(1)" /> ';
  atable=atable+ '<span style="margin-left:20px;border:1px solid cyan">Or, do you want to   ';
  atable=atable+'   <a   title="Click here to create, from scratch, a new set of reference paramters (prior reference parameters will be discarded)" ';
  atable=atable+'     href="#" onClick=" makeRefData(2); return false">generate a new set of reference parameters</a>';

  atable=atable+'</form> ';

  refVarList=varlist; refDescList=desclist ;
  refNparams=nparams;refNrecs=nrecs;
  refDatarecs=datarecs;


//  Global_Stuff=atable ;
//Display_Content('Global_Stuff','xx');
  id1=document.getElementById('show4b2');
  id1.innerHTML=atable;
  writeToStatus('Specifying reference parameters  ('+nparams+ ' variables and '+nrecs+' records)');

  return 0;
}                     // io=2

//=== save stuff in form to reference data file

if (i0==3) {
  newVarName='';
  if (document.refParamsTable.refNewVar.checked){          // add new variable to all records
      newVarName=strip(prompt('What is the (one-word) name of the new variable?'));
      newVarDesc=strip(prompt('Description of new variable '));
   }
   if (newVarName!=='') {
       newVarName=newVarName.toUpperCase();
       refVarList[refVarList.length]=newVarName ;
       refDescList[refDescList.length]=newVarDesc;
   }

   stuff='<?xml version="1.0" encoding="UTF-8" ?>\n';
   stuff=stuff+'<parameters>\n\n';
   stuff=stuff+'<REFERENCE expanded="1"> \n ';

   arow='\n<VARS>';
   for (var m=1;m<refVarList.length;m++) {
      arow=arow+' '+refVarList[m] ;
   }

   arow=arow+' </VARS> \n\n';
   stuff=stuff+arow;

   arow='<DESCRIPTIONS>\n';
   for (var m=1;m<refVarList.length;m++) {
     arow=arow+'    <VAR name="'+refVarList[m]+'" >'+refDescList[m]+' </VAR>\n';
   }
   stuff=stuff+arow+'\n</DESCRIPTIONS>\n\n';


   for (var n=1;n<=nrecs;n++) {

//     tmp='refRemove'+n;
//     if (document.refParamsTable[tmp].checked) continue ;             // drop this record

     stuff=stuff+'<RECORD id="'+n+'" >\n';

     for (var m=1;m<=nparams;m++) {
        vname=strip(refVarList[m]); tvname=vname.toUpperCase();
        tmp=vname+'.'+n ;
        aval=document.refParamsTable[tmp].value;
        if (vname.indexOf('[')>-1) {
            vnames=parseArrayIndex(vname);
            tvname=strip(vnames[0]).toUpperCase();
            vnameE=vnames[1];
            stuff=stuff+'    <'+tvname+' element="'+vnameE+'">'+aval+'</'+tvname+'>\n';
        } else {
            stuff=stuff+'    <'+tvname+'>'+aval+'</'+tvname+'>\n';
        }
     }
     if (newVarName!=='') {                                                             // add new variable
        tmp='refNew.'+n;
        aval=document.refParamsTable[tmp].value;
        if (newVarName.indexOf('[')>-1) {
            vnames=parseArrayIndex(newVarName);
            tvname=strip(vnames[0]).toUpperCase();
            vnameE=vnames[1];
            stuff=stuff+'    <'+tvname+' element="'+vnameE+'">'+aval+'</'+tvname+'>\n';
        } else {
            stuff=stuff+'    <'+newVarName+'>'+aval+'</'+newVarName+'>\n';
        }
     }

     stuff=stuff+'</RECORD>\n\n';
   }

// new record?
   if (document.refParamsTable.refNewRecord.checked) {
      n=nrecs+1;
      stuff=stuff+'<RECORD id="'+n+'" >\n';
      for (var m=1;m<=nparams;m++) {
        vname=strip(refVarList[m]); tvname=vname.toUpperCase();
        tmp=vname+'.'+n ;
        aval=document.refParamsTable[tmp].value;
        if (vname.indexOf('[')>-1) {
            vnames=parseArrayIndex(vname);
            tvname=strip(vnames[0]).toUpperCase();
            vnameE=vnames[1];
            stuff=stuff+'    <'+tvname+' element="'+vnameE+'">'+aval+'</'+tvname+'>\n';
        } else {
            stuff=stuff+'    <'+tvname+'>'+aval+'</'+tvname+'>\n';
        }
      }
     if (newVarName!=='') {                                                             // add new variable
        tmp='refNew.'+n;
        aval=document.refParamsTable[tmp].value;
        if (newVarName.indexOf('[')>-1) {
            vnames=parseArrayIndex(newVarName);
            tvname=strip(vnames[0]).toUpperCase();
            vnameE=vnames[1];
            stuff=stuff+'    <'+tvname+' element="'+vnameE+'">'+aval+'</'+tvname+'>\n';
        } else {
            stuff=stuff+'    <'+newVarName+'>'+aval+'</'+ newVarName+'>\n';
        }
     }

      stuff=stuff+'</RECORD>\n\n';
   }

   stuff=stuff+'\n</REFERENCE>\n\n';

   var vv=new Date ;
   var nowdate=vv.toLocaleDateString()+ ' ' +vv.toLocaleTimeString() ;
   tmp='\n<createWizard><descInfo>Modified by createWizard on '+nowdate+'</descInfo>\n';
   tmp2=refVarList[1];
   for (var m=2;m<refVarList.length;m++)tmp2=tmp2+','+refVarList[m];
   tmp=tmp+'<desc>'+nrecs+'</desc><value>'+tmp2+'</value>\n</createWizard>\n\n';
   stuff=stuff+tmp ;
   stuff=stuff+'</parameters>\n';

    toWrite=postReferenceData+'&name='+instrumentNames[0]+'&content='+escape(stuff);

    Post_toServer(postFileURL2,toWrite,'refParamsStatus','saving reference params','changeRefParamsNew',4) ;
    return 0;
}

// io=4
writeToStatus('Saving refererence parameters file for '+instrumentNames[0]+': '+refParamsStatus);

displayDiv('show4b','none');
displayDiv('show4b1','none');

usenam=instrumentNames[0];
toget=getInstrumentReferenceXML_1.replace(/\$NAME\$/g,usenam) ;
Get_xmlFile([toget,1],['refParamsNode','refParamsCode','1'],'re retrieving a reference data file ','changeRefParams',3) ;


//changeInstParams(1);

//globalStuff=stuff;
//Display_Content('globalStuff','xxx') ;

return 0;

}

//==========================
// create refDataRecs global array -- contents of reference data saved as refDataRecs[varname.n]
function readRefParamsNode(i) {
  var datarecs,dd,nrecs,refids,refidslist,tmp1,mm,aname,aelem,m;
  var refNode ;

datarecs={};
refNode=E2_getNodes(refParamsNode,'reference',1);
if (refNode.length<0) {
    alert(dd.length+' Error: no <REFERENCE> in reference data file '+refParamsNode.innerHTML);
    return 0;
}
refNode=refNode[0];


dd=E2_getNodes(refNode,'RECORD');
nrecs=0;
refids=[];                    // global for storing referenceData ids
refidslist={};
tmp1=[];
for (var m=0;m<dd.length;m++) {
   aid=getAttributes(dd[m],'id','0');
   refidslist[aid]=m;                      // record number m
   refids[m]=aid ;
   tmp1=tmp1.concat(aid);
   nrecs=Math.max(nrecs,aid);
   dd3=E2_getNodes(dd[m],'*');
   for (var mm=0;mm<dd3.length;mm++) {
     aname=dd3[mm].nodeName.toUpperCase();
     aelem=getAttributes(dd3[mm],'element','-1');
     if (aelem>-1) aname=aname+'['+aelem+']';
     aname=aname+'.'+aid;
     datarecs[aname]=dd3[mm].innerHTML ;
   }

}

refidslist['all']=tmp1;
datarecs['refidslist']=refidslist;
datarecs['refids']=refids;

return datarecs ;
}

//==========================
// enter ref vars using csv
function enterRefCSV(i1) {

var n,m,arow,aid,aname;

if (i1==1) {
  displayDiv('show4b2','none');
  displayDiv('show4b1','none');
  displayDiv('show4b3','block');
  var id1=document.getElementById('csvRefVarlist');
  id1.innerHTML=refVarList.join(' ');
  document.refCSVbox.refCSVvalues.value=csvStuff;
}

if (i1==2) {                                       // cancel
  displayDiv('show4b2','block');
  displayDiv('show4b1','none');
  displayDiv('show4b3','none');
}


if (i1==3) {                                       // update values in table
 vv=CSVToArray(document.refCSVbox.refCSVvalues.value);
 for (var n=0;n<vv.length;n++) {
   arow=vv[n];

   aid=strip(arow[0]);
   if (aid=='') continue ;

   refNrecs=Math.max(refNrecs,aid);
   if (arow.length!==refNparams+1) {
      alert('Error: incorrect number of values ('+arow.length+') in  row '+(n+1));
      return 0;
   }

   if (isNaN(aid)) {
      alert('Error: bad ID = '+aid);
      return 0;
   }
   if (aid<1 ) {
      alert('Error: aid must be > 0 ');
      return 0;
   }

   for (var m=1;m<refVarList.length;m++) {          // 0th element not used
      aname=refVarList[m]+'.'+aid;
      refDatarecs[aname]=arow[m];
   }
 }
 changeRefParamsNew(22,refNrecs,refNparams,refDatarecs) ;
 displayDiv('show4b2','block');
 displayDiv('show4b1','none');
 displayDiv('show4b3','none');
// 1,110,45,aa,dd566
}

return 1;


}

//=================================================================================================================
// ============================================= modify modules functions ===========================
//=================================================================================================================

function modifyModules(ido) {
var usenam,toget,aa,m,mgot,nmods,atable,i1,arow,arem ;

var bgcolors=['#ababab','#cbcbcb'];
var icc=0;

if (ido==1) {               // read modules file (again?)
  usenam=instrumentNames[0];
  toget=getModules1XML_1.replace(/\$NAME\$/g,usenam) ;
  Get_xmlFile([toget,1],['modules1Node','modules1Code','1'],'retrieving modules1 file ','modifyModules',2) ;
  return 0;
}

if (ido==2) {
  module1List={};                                                                // zap a global
  module1List['list 1']=[];
  if (modules1Code=='200') {                                                  // no such file, so create
    mgot=E2_getNodes(modules1Node,'module');
    for (var m=0;m<mgot.length;m++) {
       aa={};
       aid=strip(getAttributes(mgot[m],'id',''));
       if (aid=='') continue ;
       module1List['list 1']=module1List['list 1'].concat(aid);
       module1List[aid]={};
       module1List[aid].desc=getAttributes(mgot[m],'desc','');
       var vv=xmlToString(mgot[m],1);                                        // note: using innerHTML has problems (/> are converted to >
//       alert(vv);
//       alert(mgot[m].innerHTML);
       module1List[aid].content=vv ;
    }
  }
}

// here after or removing a moudle, or on first read  (uses module1List global )
  atable='<table cellpadding="5" border="1"><tr><th>Module Name </th><th>Description</th></tr>\n';
  for (var m=0;m<module1List['list 1'].length;m++) {
     aid=module1List['list 1'][m] ;
     aid=strip(aid);
     if (aid=='') continue ;                       // perhaps this module was "removed"
     icc=1-icc ;

     arem='<input type="button" value="rem" style="font-size:70%;color="brown" onClick="removeModule('+m+')" /> ';
     arow='<tr bgcolor="'+bgcolors[icc]+'"><td>'+arem+' <a href="#" onClick="changeModule('+m+');return false">'+aid+'</a></td><td><tt>'+module1List[aid].desc+'</tt></td></tr>\n';
     atable=atable+arow;
  }
  atable=atable+'</table>';

  hideDivs(1);
  displayDiv('show5','block');
  displayDiv('show5a','block');
  displayDiv('show5b','none');
  i1=document.getElementById('show5Name');
  i1.innerHTML=instrumentNames[0];

  i1=document.getElementById('show5a');
  i1.innerHTML=atable;
  return 0;


}

//=================
// save modules

function saveModules(ith) {
var stuff,arow,aid,tstuff,i;
stuff='<?xml version="1.0" encoding="UTF-8" ?>\n';
stuff=stuff+'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n';
stuff=stuff+'<modules>\n\n';

var vv=new Date ;
var nowdate=vv.toLocaleDateString()+ ' ' +vv.toLocaleTimeString() ;
var tmp=module1List['list 1'];

var goon=[];
for (var i=0;i<tmp.length;i++) {
   if (tmp[i]!=='') goon=goon.concat(tmp[i]);
}

stuff=stuff+'<createWizard><descInfo>Modified by createWizard on '+nowdate+'</descInfo>\n<desc>'+goon.length+'</desc><value>'+goon.join(' ')+'</value>\n</createWizard>\n\n';
tstuff='';
for (var i=0;i<module1List['list 1'].length;i++) {
   aid=module1List['list 1'][i];
   if (aid=='') continue ;       // a removed module
   tmp=module1List[aid].content ;
//   tmp=tmp.replace(/\<br\s*\>/gi,'<br />');
   arow='<!-- =================================== -->\n\n<module id="'+aid+'" desc="'+module1List[aid].desc+'">'+tmp+'</module>\n\n';
   tstuff=tstuff+arow;
}

stuff=stuff+tstuff+'</modules> \n\n ';

if (ith==1) {                         // first pass: check syntax!
  checkXMLsyntax(1,instrumentNames[0],tstuff,'modules') ;
  return 0;
}

var toWrite=postModules1+'&name='+instrumentNames[0]+'&content='+escape(stuff);

Post_toServer(postFileURL2,toWrite,'modules1Status','saving allowedUsers','saveModules2',goon.length) ;

//globalStuff=stuff;
//Display_Content('globalStuff','oy');


}

function saveModules2(ith) {
  hideDivs(1);
  writeToStatus('Modules saved ('+ith+'): '+modules1Status);
  return 0;
}

//=================
// change module

function changeModule(ith) {
var stuff,aid,acontent,i1,adesc;
aid=module1List['list 1'][ith];
adesc=module1List[aid].desc ;
acontent=module1List[aid].content;

displayDiv('show5a','none');
stuff='<h3>Modify a module ...</h3><form name="newModule"> ';
stuff=stuff+'<input type="button" title="After modifying the module, click here to save it" value="Save" onClick="addModule2(1)" />' ;
stuff=stuff+'<input type="button" title="Do not save these changes" value="Cancel" onClick="modifyModules(3)" />' ;

stuff=stuff+'<table cellpadding="6" border="1"><tr><th>Name</th><th>Description</th></tr>';
stuff=stuff+'<tr><td><input style="background-color:#ababba"  value="'+aid+'" type="value" size="20" name="newName" title="Module name" readonly="1" /></td>';
stuff=stuff+'<td><input value="'+adesc+'" type="value" size="80" name="newDesc" title="You can modify the description" /></td>';
stuff=stuff+'</tr></table>';
stuff=stuff+'<div style="background-color:#efefed;margin:5px 5% 5px 5%"><em>Enter content of the module here ...</em><br/>';
stuff=stuff+'<textarea name="content" rows="15" cols="100"></textarea>';
stuff=stuff+'</form>';

i1=document.getElementById('show5b');
i1.innerHTML=stuff;
displayDiv('show5b','block');
//alert('acontent=== '+acontent);
document.newModule.content.value=acontent ;
return 0;
}



//=================
// removew module

function removeModule(ith) {
var aid=module1List['list 1'][ith];
module1List['list 1'][ith]='';
delete module1List[aid];
modifyModules(3);                       // redisplay module list, with new module added
return 0;
}

//=================
// create new module

function addModule(ith) {
var stuff,i1;

displayDiv('show5a','none');
stuff='<h3>Create a new module ...</h3><form name="newModule"> ';
stuff=stuff+'<input type="button" title="After specifying the module, click here to save it" value="Save" onClick="addModule2(1)" />' ;
stuff=stuff+'<input type="button" title="Do not add this new module" value="Cancel" onClick="modifyModules(3)" />' ;
stuff=stuff+'<table cellpadding="6" border="1"><tr><th>Name</th><th>Description</th></tr>';
stuff=stuff+'<tr><td><input type="value" size="20" name="newName" title="Enter name of new module here" /></td>';
stuff=stuff+'<td><input type="value" size="80" name="newDesc" title="Enter short description of new module here" /></td>';
stuff=stuff+'</tr></table>';
stuff=stuff+'<div style="background-color:#efefed;margin:5px 5% 5px 5%"><em>Enter content of the module here ...</em><br/>';
stuff=stuff+'<textarea  a name="content" rows="15" cols="100"></textarea>';
stuff=stuff+'</form>';

i1=document.getElementById('show5b');
i1.innerHTML=stuff;
displayDiv('show5b','block');

return 0;
}

function addModule2(ith) {
  var aname,stuff,stuff2,adesc,acontent,aname,aa;

  aname=document.newModule.newName.value;
  adesc=document.newModule.newDesc.value ;
  acontent=document.newModule.content.value ;
  aname=strip(aname);
  if (aname=='') {
      alert('You must specify a name ');
      return 0;
  }
  aa=aname.split(' ');
  if (aa.length>1) {
      alert('Error: you must specify a one-word name');
      return 0;
  }
  if (aname.indexOf('"')>-1) {
     alert('Sorry, you can not include " in the module name ');
     return 0;
  }
  adesc=strip(adesc);
  if (adesc=='') {
      alert('You must enter a description ');
      return 0;
  }
  if (adesc.indexOf('"')>-1) {
     alert('Sorry, you can not include " in the module description ');
     return 0;
  }

  if (typeof(module1List[aname])=='undefined') {
     module1List['list 1']=module1List['list 1'].concat(aname);
     module1List[aname]={} ;
  }                         // else, use existing record
  module1List[aname].desc=adesc ;
  module1List[aname].content=acontent ;

  modifyModules(3);                       // redisplay module list, with new module added

// globalStuff='<?xml version="1.0" encoding="UTF-8" ?>\n';
// globalStuff=globalStuff+'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n';
// globalStuff=globalStuff+'<modules>\n\n';
// globalStuff=globalStuff+modules1Node.innerHTML+'\n\n'+stuff;
// var vv=new Date ;
// var nowdate=vv.toLocaleDateString()+ ' ' +vv.toLocaleTimeString() ;
// var  tmp='\n<createWizard><descInfo>Modified by createWizard on '+nowdate+'</descInfo>\n<desc>'+(module1List.length+1)+'</desc><value>xx</value>\n</createWizard>\n';
// globalStuff=globalStuff+'\n\n'+tmp;
// globalStuff=globalStuff+'\n\n</modules>';
// Display_Content('globalStuff','oy');

  return 0;
}

// =====================================================================================
// ============================================= Utility functions ===========================
// =====================================================================================

// read value from desciptor file (
function getDescriptorVar(avar,afile) {
var dd,dd2,avalue ;
dd=E2_getNodes(instDescNode,avar,1);
if (dd.length<1) {
  alertD('Error: no <'+avar+'> in '+afile);
  return 0;
}
dd2=E2_getNodes(dd[0],'value',1);
if (dd2.length<1) {
  alertD('Error: no <'+avar+'><VALUE> in '+afile) ;
  return 0;
 }
return dd2[0].innerHTML;

}


// read the createWizard field in whichnode
function readModified(whichnode,afield) {
  if (arguments.length<2) afield='value';
  dd=E2_getNodes(whichnode,'createWizard',1);
  if (dd.length<1) {
       alertD('Warning: no createWizard field in this dSurvey file (so it was not created by the create instrument wizard). Hit OK to continue anyways ');
       return '';
  }
   dd2=E2_getNodes(dd[0],afield,1);
   if (dd2.length<1) {
       alertD('Warning: no '+afield+' value specified  ');
       return '';
  }
  return dd2[0].innerHTML ;
}

// =======================
// change or make the createWizard field in whichnode (by default, whichNode=descriptorXML)
function changeModified(avalue,vall,vdesc,whichnode) {
  var dd,vv,vv1,vv1b,vv2,vv2b,v3,v3b;
  if (arguments.length<4) {
      dd=E2_getNodes(descriptorXML,'createWizard',1);
  } else {
      dd=E2_getNodes(whichnode,'createWizard',1);
  }
if (dd.length<1) {
  vv=document.createElement('createWizard');

  vv1=document.createElement('descInfo');
  vv1b=document.createTextNode(avalue);
  vv1.appendChild(vv1b);

  vv3=document.createElement('desc');
  vv3b=document.createTextNode(vdesc);
  vv3.appendChild(vv3b);

  vv2=document.createElement('value');
  vv2b=document.createTextNode(vall);
  vv2.appendChild(vv2b);

  vv.appendChild(vv1);
  vv.appendChild(vv3);
  vv.appendChild(vv2);
  descriptorXML.appendChild(vv);
} else {
   dd2=E2_getNodes(dd[0],'descInfo',1);
   if (dd2.length>0) {
     dd2[0].firstChild.nodeValue=avalue ;
   }
    dd2=E2_getNodes(dd[0],'desc',1);
   if (dd2.length>0) {
     dd2[0].firstChild.nodeValue=vdesc ;
   }

   dd2=E2_getNodes(dd[0],'value',1);
   if (dd2.length>0) {
     dd2[0].firstChild.nodeValue=vall  ;
   }
}
return 1 ;
}


//====================
// hide the various showN divs
function hideDivs(i) {
  for (var j=0;j<showdivs.length;j++) {
     displayDiv(showdivs[j],'none');
  }
  return 0;
}


//====================
function writeToStatus(amessage,notime) {
  var atime='';
  if (arguments.length<2) notime=0;
  if (notime!==1) {
     var vv=new Date ;
     var zz=vv.toLocaleTimeString();
     zz=zz.split(' ');
     atime='<span style="font-size:80%;color:blue;margin-right:8px">'+zz[0]+'</span>' ;
  }

  var id1=document.getElementById('statusMessages');
  if (amessage=='$$RESET$$') {
    id1.innerHTML='<div><b>Status messages:</b></div>';
  } else {
    id1.innerHTML=id1.innerHTML+'<div style="margin:10px 2% 3px 2%;border:1px dotted cyan">'+atime+amessage+'</div>';
  }
  return 0;
}


/* ============================================================
/* copy an xml node (tree under node) to a string.  Highly recursive. Note: apad not currently used  */
// if skip1=1, then do not write the outermost tagname
// if skipc=1, then do NOT write comments
function xmlToString(anode,skip1,skipc,docrlf) {
var astrg2,astrg,anatt,anattv,i,i2,atype,aname,anode,iss,docrlf2=0,vst,ivst,astrg2a;

if (arguments.length<2) skip1=0;
if (arguments.length<3) skipc=0;
if (arguments.length<4) docrlf=0;

if (docrlf!=0) {
   docrlf2=docrlf+2 ;
}

try {
   if (anode.childNodes.length==0) {
        if (anode.nodeType==1 && skip1==1) return '' ;
         skip1=0;
   }
}
catch(err) {
  if (anode==null)  return '';

//  if (anode.nodeType==1 && skip1==1) return '' ;
  skip1=0;
}

astrg='';
atype=anode.nodeType ;

//if (atype==3) alert(atype+'='+anode.innerHTML);

if (atype==8) {                         //comment
   if (skipc==1) return '' ;                            // comment, but
   astrg='<!--'+anode.nodeValue+'-->  '  ;
   if (docrlf!=0) astrg=astrg+  '\n';
   return astrg ;
}

if (atype==3) {                         //string       -- note: nodevalue inappropriately converts &entities to original character. So convert 'em back
//   return '['+anode.nodeValue+'_'+escape(anode.nodeValue)+'_'+anode.nodeValue.length+']' ;
   var t1=anode.nodeValue ; t1=t1.replace(/\&/g,'&amp;'); t1=t1.replace(/\</g,'&lt;'); t1=t1.replace(/\>/g,'&gt;');
   return t1 ;
//   return anode.nodeValue ;
}

aname=anode.nodeName.toLowerCase() ;

astrg='';
if (skip1!=1) {
  astrg='<'+aname+' ';
  if (docrlf!=0) {
         vst=''; for (var ivst=0; ivst<docrlf;ivst++) vst=vst+' ';
         astrg='\n'+vst+astrg;
  }
  for (var i=0;i<anode.attributes.length; i++) {
      if (!anode.attributes[i].specified) continue ;              // skip browser added attributes (might be a problem with ie)
      anatt=anode.attributes[i].nodeName ;
      anattv=anode.attributes[i].nodeValue ;
      astrg=astrg+anatt+'="'+anattv+'" ';
  }

  if (anode.childNodes.length==0) {
    astrg=astrg+'/>' ;
    return astrg ;
  }
  astrg=astrg+'> ';
}

for (var i2=0;i2<anode.childNodes.length;i2++) {
   astrg2=xmlToString(anode.childNodes[i2],0,skipc,docrlf2);
   if (docrlf>0) {                              // check for repetitive crlfs
        astrg2a=strip(astrg2);
        if (astrg2a.length==0) continue ;
   }
   astrg=astrg+astrg2 ;
}
if (skip1!=1) {
  astrg=astrg+'</'+aname+'> ' ;
}



return astrg ;

}               // xmltostring


//================================================
// syntax test
function checkXMLsyntax(ido,usenam,stuff,whattest) {
var myVal,myverify,goo,toget,oof,bverify,daval;
if (ido==1  ) {                    // first call -- upload/download to check veracity

 toget=getXMLtest_1.replace(/\$NAME\$/g,usenam) ;

  myVal='<?xml version="1.0" encoding="UTF-8" ?>\n\n<verifyTest>\n';
  myverify=svy_currentTime(1,1);
  myVal=myVal+'<verify value="'+myverify+'" /> \n\n '
  myVal=myVal+stuff+'\n\n</verifyTest>\n ';

  goo=postVerify+'&name='+usenam+'&content='+escape(myVal);
  writeToStatus('Please wait for syntax test of: '+whattest);
  Post_toServer(postFileURL2,goo,'saveVerifyResponse','verifying modified xml file ','checkXMLsyntax',2,usenam,myverify,whattest);
  return 0;
}

if (ido==2) {                    // after upload to check veracity

  writeToStatus('Syntax test: step 1 complete (test file uploaded to server)',1);

 if (saveVerifyResponse.substr(0,2)!=='ok') {
     alert('Syntax test failed! ');
     writeToStatus('Syntax test FAILURE (problem uploading file): '+saveVerifyResponse);
     return 1;
  }
  toget=getXMLtest_1.replace(/\$NAME\$/g,usenam) ;
  Get_xmlFile(toget,['testNode','testCode','1'],'retrieving quality check XML ','checkXMLsyntax',3,usenam,stuff,whattest);

  return 0 ;
}

if (ido==3) {                    // after retrieving the syntax test upload

  oof=E2_getNodes(testNode,'verify');
  if (oof.length==0) {
        daval=E2_getNodeText(testNode);
        daval=daval.replace(/\</g,'&lt;');
        daval=daval.replace(/\>/g,'&gt;');
       alert('Syntax test failed! ');
        writeToStatus('Syntax test FAILURE for: '+whattest+' modification :: <br/> '+daval);
        return 1;
  }
  bverify=getAttributes(oof[0],'value','noVerification');
  if (stuff!==bverify) {
       alert('Syntax test failed! ');
        writeToStatus('Syntax test FAILURE (bad verification string).  Expected='+stuff+' || Found='+bverify);
        return 1;
  }
 writeToStatus('Syntax test (for '+whattest+') PASSED');
 if (whattest=='modules') {
   saveModules(2)  ;
 }
}

return 0
}
