// debug alerts used: # 13

// jcontrol.js - control panel support for controlling Jmol.

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// (frames only)
// The control.htm document and its javascript must complete loading
// before we try to run a script defined there in the jmol frame!
// Therefore we must not load jmol until after control.htm is loaded.

function startJmol()
{
	if (top.usingFrames)
		top.frameRight.document.location.replace("moldoc.htm");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function initFG()
{
	top.initTargetDivs();
// removed to facilitate use of "javascript" sitemeter.
//	showHelp2('makeBePatientHelp()');
	startJmol(); // frames only
//	slideit(); the image to change has not loaded yet, see startup.txt
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// writeToggleButton() is used to write each toggle button.
// Button numbers are predetermined to minimize confusion when switching
//   consurf <--> fg.
// The button numbers are used to take the correct action in: doToggleButton().
// The up and down command scripts, button state, and labels are
// kept in arrays.

var toggleIndex = 0;
var toggleUpSptName = new Array();
var toggleDownSptName = new Array();
var toggleIsDown = new Array();
var toggleHelpName = new Array();

var ligandIndex = 0;
var waterIndex = 1;
var slabIndex = 2;

var backgroundIndex = 3;
	toggleIsDown[backgroundIndex] = true; // default white background at outset
var spinIndex = 4;
var resetIndex = 5;

var qualityIndex = 6;

var savedButtonStates = new Array();

var isMac = navigator.appVersion.indexOf("Mac") != -1;
var thisBrowser = "unknown";
if (navigator.userAgent.toLowerCase().lastIndexOf("firefox") != -1)
	thisBrowser = "ff";

//var toggleIndexFromName = new Array(
//"ligands+", "water", "slab", "background", "spin");

// start is "up" or "down"
function writeToggleButton(downSptName, upSptName, label, start, helpName,
titleMsg)
{
	document.writeln(
	makeToggleButton(downSptName, upSptName, label, start, helpName, titleMsg));
}

function makeToggleButton(downSptName, upSptName, label, start, helpName,
titleMsg)
{

	// get pre-determined index
	if (match(label, "water"))
		toggleIndex = waterIndex;
	if (match(label, "ligand"))
		toggleIndex = ligandIndex;
	if (match(label, "slab"))
		toggleIndex = slabIndex;

	if (match(label, "background"))
		toggleIndex = backgroundIndex;
	if (match(label, "spin"))
		toggleIndex = spinIndex;

	if (match(label, "view1"))
		toggleIndex = resetIndex;

	if (match(label, "quality"))
		toggleIndex = qualityIndex;

	// remember up and down scripts
	toggleUpSptName[toggleIndex] = upSptName;
	toggleDownSptName[toggleIndex] = downSptName;
	toggleHelpName[toggleIndex] = helpName;

	var butwas = toggleIsDown[toggleIndex];
	if (typeof(butwas) != "undefined")
	{
		if (butwas)
			start = "down";
		else
			start = "up";
	}
	// else this is the first time the button was created, and so it
	// obeys the default start value.

	if (start == "up")
		toggleIsDown[toggleIndex] = false;
	else
		toggleIsDown[toggleIndex] = true;

	// supercede default with saved state

	if (typeof(titleMsg) == "undefined")
		titleMsg = "";

	var tog = "<a href='javascript: doToggleButton(" + toggleIndex + ")'>" +
"<img src='" + start + ".gif' border='0' name='toggle" + toggleIndex + "'" +
" title='" + titleMsg + "'\/><\/a>&nbsp;" + label;

	return tog;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// could have been named doButton  dtb
function doToggleButton(tognum)
{
//	alert("doToggleButton(" + tognum + ")");

// ======== REFUSE TOGGLE ================

	// DON'T USE WATER BUTTON DURING CONTACTS TARGET SELECTION
	if (selectMode != "" && tognum == waterIndex)
		if (confirm("To select water as a target for contacts,\n" +
			"please use the \"Show Water\" checkbox below.\n" +
			"OK to continue target selection, or\n" +
			"Cancel to quit target selection."))
			return;

	// SLAB can't be turned on during precontacts selection.
//	if (tognum == slabIndex && selectMode != "")
//	{
//		alert("Sorry, but slab mode is not compatible\n\
//with target selection.");
//		return;
//	}

	// SLAB can't be turned on during hiding.
//	if (tognum == slabIndex && hideMode != "")
//	{
//		alert("Sorry, but slab mode is not compatible\n\
//with hiding.");
//		return;
//	}

// ======== END REFUSE TOGGLE ================
// ======== BEGIN EXECUTE TOGGLE ================

	var sptname = toggleUpSptName[tognum];

	var spt;

	var imgnum = eval("document.toggle" + tognum);
	if (toggleIsDown[tognum]) // going up/off
	{
		imgnum.src = "up.gif";
		spt = eval(toggleUpSptName[tognum]);
		toggleIsDown[tognum] = false;
	}
	else // toggle is up, going on/down
	{
		showHelp2(toggleHelpName[tognum]);

		imgnum.src = "down.gif";
		spt = eval(toggleDownSptName[tognum]);
		toggleIsDown[tognum] = true;
	}

	// For background, refresh the PDB Id echo
	if (tognum == backgroundIndex)
		spt += makeEchoPdbIdSpt(""); // blank parameter means get color from toggle

	// if centering was on, and the button went down (except for bkg, spin),
	// now the centering controls are gone, so turn centering off.
	// Ditto for hiding & selecting.
	if (tognum != spinIndex && tognum != backgroundIndex)
	{
		if (toggleIsDown[tognum]) // button went down
		{
			// must be done before scriptToJmol!
			centerMode = false; // scriptToJmol turns off picking center

			// only Water or Ligands+ affect hiding, since Slab is refused above.
			top.hideMode = "";
			if (hiddenRangeStart != "")
			{
				hiddenRangeStart = "";
				spt += makeEchoSpt(""); // to blank "Range Starts at "
			}
			top.selectMode = "";
		}
	}

//	alert("jcontrol.js #3: doToggleButton(" + spt + ")");
	doMolViewSpt(spt); // in doToggleButton()
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function getPDBId()
{
	var pdbid = validPDBId;

	// CONSURF UPLOAD
	if (pdbid.length == 0 && consurfMode)
	{
    if (consurf_pdb_id.length == 4)
			pdbid = consurf_pdb_id;
	}
	// PEPSURF UPLOAD
	if (pdbid.length == 0 && pepsurfMode)
	{
    if (pepsurf_pdb_id.length == 4)
			pdbid = pepsurf_pdb_id;
	}
	// SELECTON UPLOAD
	if (pdbid.length == 0 && selectonMode)
	{
    if (selecton_pdb_id.length == 4)
			pdbid = selecton_pdb_id;
	}
	// EPITOPIA UPLOAD
	if (pdbid.length == 0 && epitopiaMode)
	{
    if (epitopia_pdb_id.length == 4)
			pdbid = epitopia_pdb_id;
	}
	return pdbid;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function makeInfoLinks()
{
	var pdbid = getPDBId();

	if (pdbid.length == 0) // can't get PDB ID
		return "";

	var info = "<b>" + pdbid.toUpperCase() + "</b>:&nbsp;";

// alignment options include
// POOR: middle (too low), texttop (too low)
// OK: center
// GOOD: absmiddle
// ALSO: absbottom, baseline, bottom, default, top

	info += 
		makeViewLink("keyExternalResources",
		'Key&nbsp;Resources..&nbsp;<img \
			src="proteopedia_w30.png" name="slideshow1" id="slideshow1" \
			align="absmiddle" border="0">',
		"makeKeyExternalResourcesHelp()",
		"Proteopedia, Quaternary Structure, PDB, Gaps, Conservation, Model Quality");

//	info += makePQS(pdbid);
//		info +=	"&nbsp;";
//	info += makeRCSB(pdbid);
//		info +=	"&nbsp;";
//	info += makeOCA(pdbid);
//		info +=	"&nbsp;";
//	info += makeGaps(pdbid);

	return (info);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// Write a pdb code-specific link to RCSB's Structure Explorer.

function makeRCSB(pdbid)
{
	var tmsg = pdbid.toUpperCase() + ' at the Protein Data Bank';

	// explore.cgi?pdbId= returns a blank page when the entry is on hold.
	// Feb08: rcsb.org/pdb/explore.do?structureId= no longer works for on hold.
	// Flammang @Nature inquired of RCSB and we were told to use the following
	// by Christine Zardecki, zardecki@rcsb.rutgers.edu
	var rcsb = "<a href='http:\/\/www.pdb.org\/pdb\/search\/structidSearch.do?structureId=" +
	pdbid + "' target='rcsbwin' \/>" +
	"<img src='pdb.gif' border=1 align='center' \
title='" + tmsg + "'><\/a>";

	return(rcsb);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function makeOCA(pdbid)
{
	var oca = "<a href='http:\/\/bip.weizmann.ac.il\/oca-bin\/ocashort?id=" +
	pdbid + "' target='ocawin' \/>" +
	"<img src='oca.gif' border=1 align='center' \
title='" + pdbid.toUpperCase() + " info at OCA'><\/a>";

	return oca;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function makeGaps(pdbid)
{
	var descrip = "<img src='gaps2.gif' border=1 align='center'>";
	var ttl = pdbid.toUpperCase() + " Sequences with Gaps from S2C";
	var gaps = "<a href='notes.htm?mol=" + pdbid + "#seq' " +
		"title='" + ttl + "' target=_blank>" +
		descrip + "</a>";

	return gaps;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function makePQS(pdbid)
{
	if (top.validPDBId.length == 0)
		return "";

//	var pqs = 
//		"<a href='http://pqs.ebi.ac.uk/pqs-bin/macmol.pl?filename=" +
//		top.validPDBId + "' target='pqswin'>" +
//		"<img src='pqs.gif' border=1 align='center' \
//title='" + validPDBId + " Specific Oligomers or Monomers'></a>";

	var descrip = "<img src='pqs.gif' border=1 align='center'>";

	var ttl = validPDBId + " Specific Oligomers or Monomers";

	var pqs = "<a href='notes.htm?mol=" + validPDBId + "#pqs' " +
		"title='" + ttl + "' target=_blank>" +
		descrip + "</a>";

	return (pqs);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// Write a special troubleshooting message, only if the Safari browser
// is being used. In 11/05, this bug in Apple's java had been fixed in
// OSX.4 (tiger) but not in OSX.3.9.

function makeSafari()
{
	if (!isMac)
		return "";
	var safariBug =
"Quit, restart the browser if the above controls don't work. \
<a href=\"notes.htm#safari\" target=_blank>Why?</a><br>";

	return (safariBug);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// Write a pdb code-specific link to Protein Explorer.

function writePE()
{
	var pdbid = getPDBId();

	if (pdbid.length == 0)
		return "";

	var pe = "<a href='http:\/\/www.umass.edu/microbio/chime/pe/protexpl/pe.htm?id=" +
	pdbid + "' target='_top'>Protein Explorer<\/a>";

	return(pe);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// Write a link that sends a command script to Jmol.
// Each link is numbered in the order in which they are written.
// The link numbers are used to perform the correct action in: doViewLink().
// Actions and link labels are stored in arrays.

var viewLinkSptName = new Array();
var viewLinkHelpName = new Array();

var secondaryStructureIndex = 1;
var cartoonIndex = 2;
var NCRainbowIndex = 3;
var compositionIndex = 4;
var hydrophobicPolarIndex = 5;
var chargeIndex = 6;
var contactsIndex = 7;
var vinesIndex = 8;
var allModelsIndex = 9;
var hideIndex = 10;
var findIndex = 11;
var moreViewsIndex = 12;
var centerIndex = 13;
var troubleshootingIndex = 14;
var resetIndex = 15;
var keyExternalResourcesIndex = 16;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function getLinkIndex(sptName)
{
	if (match(sptName, "rocket"))
		return secondaryStructureIndex;
	if(match(sptName, "cartoon"))
		return cartoonIndex = 2;
	if(match(sptName, "rainbow"))
		return NCRainbowIndex = 3;
	if(match(sptName, "composition"))
		return compositionIndex = 4;
	if(match(sptName, "polarity"))
		return hydrophobicPolarIndex = 5;
	if(match(sptName, "charge"))
		return chargeIndex = 6;
	if(match(sptName, "contacts"))
		return contactsIndex = 7;
	if(match(sptName, "vine"))
		return vinesIndex = 8;
	if(match(sptName, "allmodels"))
		return allModelsIndex = 9;
	if(match(sptName, "hide"))
		return hideIndex = 10;
	if(match(sptName, "find"))
		return findIndex = 11;
	if(match(sptName, "moreviews"))
		return moreViewsIndex = 12;
	if(match(sptName, "center"))
		return centerIndex = 13;
	if(match(sptName, "trouble"))
		return troubleshootingIndex = 14;
	if(match(sptName, "view1"))
		return resetIndex = 15;
	if(match(sptName, "keyexternal"))
		return resetIndex = 16;

	alert("Programmer's error: getLinkIndex() failure.");
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function writeViewLink(sptName, label, helpName, titleMsg)
{
	lk = makeViewLink(sptName, label, helpName, titleMsg);
	document.writeln(lk);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function makeViewLink(sptName, label, helpName, titleMsg)
{
// This is what jmol.js jmolLink() makes:
//<A name='jmolLink0' id='jmolLink0'
//href='javascript:_jmolClick(1);'
//onMouseover='_jmolMouseOver(1);return true;' onMouseout='_jmolMouseOut()'
//>Cartoon</A>

	linkIndex = getLinkIndex(sptName);

	viewLinkSptName[linkIndex] = sptName;
	viewLinkHelpName[linkIndex] = helpName;
//	linkLabel[linkIndex] = label;

	var lk = "<a href='javascript: doViewLink(" + linkIndex + ")'";
	if (typeof(titleMsg) != "undefined")
	{
		if (titleMsg != "")
			lk += " title='" + titleMsg + "' ";
	}
	lk += ">" + label + "<\/a>"

	return lk;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function doViewLink(lnum) // dvl
{
	// LOCAL CONVENIENCE FLAGS
	var hideNow = match(viewLinkSptName[lnum], "hide");
	var vinesNow = match(viewLinkSptName[lnum], "vine");
	var preContacts = match(viewLinkSptName[lnum], "precontacts");
	var preFind = match(viewLinkSptName[lnum], "find");
	var resetNow = match(viewLinkSptName[lnum], "view1");

	// if entering Hide.. or Find.. from the help prefix links in ConSurf,
	// also change the control panel to FG.
	if (controlPanel == "consurf" && (hideNow || preFind))
		writeFGControls();

	// CONFIRM NEW CONTACTS
	if (preContacts && contactsShowing)
	{
		if (!confirm("OK to select new targets for Contacts,\n" +
			"or Cancel to keep current Contacts."))
		{
			showHelp2("makeContactsShownHelp()");
			return;
		}
	}
			
	// contactsShowing goes off unless Find, Hide, Center, More Views, or
	// Troubleshooting.
	// This must happen before showing help!
	if (!hideNow && !preFind && !match(viewLinkSptName[lnum], "center") &&
		!match(viewLinkSptName[lnum], "moreviews") &&
		!match(viewLinkSptName[lnum], "troubleshooting"))
	{
		contactsShowing = false;
		markContactsTargets = false;
	}

	if (preContacts)
		resetContacts(); // must be done before showing help

	// RESET
	if (resetNow)
		resetPrep();

	if (vinesNow) // must be done before help
	{
		setButtonState("up", waterIndex);
		allWireframe = false;
		hydrogensVisible = true;
		sidechainsVisible = true;
	}

	if (preContacts)
		useConsurfColors = false;

	// SHOW HELP
	showHelp2(viewLinkHelpName[lnum]);
//	alert("jcontrol.js #6: help shown in doViewLink()");

	// FOCUS FIND SLOT
	if (match(viewLinkHelpName[lnum], "makefindhelp"))
		setTimeout("document.findForm.toFind.focus()", 100);

	// RETURN IF NO SCRIPT
	// More Views, Troubleshooting are special cases with NO SCRIPT
	// No Script: moreViews, troubleshooting, keyExternal
	if (match(viewLinkSptName[lnum], "moreviews") ||
		match(viewLinkSptName[lnum], "troubleshooting") ||
		match(viewLinkSptName[lnum], "keyexternal"))
	{
		cancelCenteringNoHelp(); // sends script set picking on
		selectMode = ""; // in doViewLink()
		return;
	}

	// SET VARIOUS FLAGS
	// For all remaining views, non-standard residues will be hidden.
//	alert("jcontrol.js #4: turning off showNonStandardResidues");
	top.showNonStandardResidues = false;

	// For all remaining views, hiding mode goes off.
	top.hideMode = "";

	// Unless this is Contacts, selectMode goes off.
	if (!preContacts)
		top.selectMode = ""; // in doViewLink()

	//..................................................
	// BUTTONS FORCED UP/DOWN
	//..................................................

	// LIGAND BUTTON GOES ON/DOWN if Composition, Vines, precontacts, reset
	if (match(viewLinkSptName[lnum], "composition") ||
		vinesNow ||	preContacts || resetNow)
			setButtonState("down", ligandIndex);

	// LIGAND BUTTON GOES OFF/UP if Polarity, Charge, All Models
	if (match(viewLinkSptName[lnum], "polarity") ||
		match(viewLinkSptName[lnum], "charge") ||
		match(viewLinkSptName[lnum], "allmodels"))
			setButtonState("up", ligandIndex);

	// WATER BUTTON GOES ON/DOWN if Composition, Contacts
	if (match(viewLinkSptName[lnum], "composition") || preContacts)
		setButtonState("down", waterIndex);

	// WATER BUTTON GOES OFF/UP if Polarity, Charge, All Models, reset,
	// Vines done above.
	// preContacts
	if (match(viewLinkSptName[lnum], "polarity") ||
		match(viewLinkSptName[lnum], "charge") ||
		match(viewLinkSptName[lnum], "allmodels") || resetNow || preContacts)
			setButtonState("up", waterIndex);

	// SLAB BUTTON GOES OFF/UP if precontacts, reset, or hide
//	if (preContacts || resetNow || hideNow)
	if (resetNow)
		setButtonState("up", slabIndex);

	// BACKGROUND BUTTON GOES BLACK/UP if precontacts, prefind
	if (preContacts || preFind)
		setButtonState("up", backgroundIndex); // Background Black

	// BACKGROUND BUTTON GOES DOWN/WHITE if reset
	if (resetNow)
		setButtonState("down", backgroundIndex);

	// SPIN BUTTON GOES DOWN/ON if reset
	if (resetNow)
		setButtonState("down", spinIndex);

	//....................................................
	// END BUTTONS
	//....................................................

	// SET centerMode IF CENTERING
	if (match(viewLinkSptName[lnum], "center"))
		top.centerMode = true;

	// SET default view for contacts
	if (preContacts)
		contactsView = "sf";

	// SET hideMode
	if (hideNow)
		hideMode = "c"; // hide has blank script, but needs sendToJmol postscripts!

	// RECORD CURRENT VIEW UNLESS ...
	if (!match(viewLinkSptName[lnum], "center") &&
		!match(viewLinkSptName[lnum], "find") &&
		!match(viewLinkSptName[lnum], "view1") &&
		!match(viewLinkSptName[lnum], "hide"))
			currentView = viewLinkSptName[lnum];

	// view1Spt has undesired consequences. It starts spinning, and
	// re-zeros ~hidden_jdef?
	if (match(viewLinkSptName[lnum], "view1"))
		currentView = "cartoonSpt";

//	alert("jcontrol.js #7: doViewLink() viewLinkSptName[]=" + viewLinkSptName[lnum] +
//		"\n currentView now = " + currentView);

	// MAIN VIEW SCRIPT
	var spt = eval(viewLinkSptName[lnum]);

	if (preContacts || resetNow || hideNow) // SLAB FORCED OFF
		spt += 	hoverSpt; // restore hover report

// This was removed in FGiJ 1.43.
//		spt += "slab off;\n"; // in doViewLink, for Hide

	if (!hideNow) // includes Reset
	{
		// hiddenRangeStart already blanked by resetPrep() if resetNow
		// but in all other cases,
		hiddenRangeStart = "";
	}

	if (preContacts && telAvivMode)
		spt += makeEchoSpt("Target Selection Colors (Temporary)");
	else if (!hideNow)
		// and in all cases except Hide, blank the echo message.
		spt += makeEchoSpt(""); // to blank "Range Started at "

	if (resetNow)
		spt += clearBoxes(); // axes, unitcell, boundbox

	spt += makeEchoPdbIdSpt(""); // blank parameter means get color from toggle

	// Clicking "Contacts.." always starts with nothing selected.
	if (preContacts)
	{
		clearSelectedArrays();		
		spt += "select none; define ~targ_current selected;\n";
	}

	// if centering was on, now the controls are gone, so turn it off.
	if (!match(viewLinkSptName[lnum], "center"))
		top.centerMode = false; // DO BEFORE SENDING SCRIPT!

	doMolViewSpt(spt); // in doViewLink()
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// showHelp2() is called by showHelp(), as well as directly in several
// places.

function showHelp2(helpname)
{
//	alert("jcontrol.js #8: showHelp2 receives " + helpname);

	if (helpname == "")
		return;

	helpPanel = helpname; // added in FGiJ 1.43
	
	// In some cases, the help HTML must be dynamically generated.
	// In other cases, the help HTML text is static.
	// Regardless of whether helpname is a static variable or a function,
	// the code below works.

	var prehtxt = makeHelpPrefix(helpname);

//	alert("jcontrol.js #8b: prehtxt:\n|" + prehtxt + "|");

	var htxt;
	htxt = eval("top." + helpname);

	if (typeof(htxt) == "undefined")
		htxt = top.nohelp;

//	alert("jcontrol.js #8d: htxt:\n" + htxt);

	htxt = prehtxt + htxt;

//	alert("jcontrol.js #5: " + top.helpTarget.document)

	// In most cases, add a footer with a link back to the introHelp.


	if (!match(helpname, "ntrohelp") &&
		!match(helpname, "epatienthelp") &&
		!match(helpname, "makeconsurfhelp") &&
		!match(helpname, "makebadpdbfilehelp"))
			htxt += top.helpFooter;

 // write to the division helpDiv

//		alert("jcontrol.js #13 to helpDiv:\n" + htxt);

		helpTarget.innerHTML = htxt;

// Probably I could simply use this now:
//		top.document.getElementById('helpDiv').innerHTML = htxt;

}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function closeFgij()
{
	if (confirm("Close window, ending this\n" +
		"FirstGlance session?"))
		top.window.close();
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function clearHidden()
{
	hiddenChains.length = 0;
	hiddenGroups.length = 0;
	hiddenAtoms.length = 0;
	hiddenRanges.length = 0;

	hiddenRangeStart = "";

	hideProtein = hideDNA = hideRNA = hideCarbohydrate = hideHydrogen = false;

	invertHidden = false;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function invertHiding(hiddenTot)
{
	if (hiddenTot == 0)
	{
		alert("Nothing is hidden yet.\n" +
			"Please hide something first.\n" +
			"Then hiding can be inverted.");
		document.hideForm.invert.checked = false;
		return;
	}

	invertHidden = true;
	hideMode = "";
	var msg = "Hiding Is Inverted";

	var ivt = document.hideForm.invert.checked;
	if (!ivt)
	{
		invertHidden = false;	
		msg = "Hiding Is Not Inverted";
	}
	reDisplay(makeEchoSpt(msg), "");
	showHelp2("makeHideHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function unHideAll()
{
	clearHidden();
	reDisplay(makeEchoSpt("Nothing Remains Hidden"), "");
	showHelp2("makeHideHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function unHideLast()
{
	var es;

	if (hideMode == "c")
	{
		es = "Chain " + hiddenChains[hiddenChains.length - 1] + " Re-Displayed";
		hiddenChains.length = hiddenChains.length - 1;
	}
	else if (hideMode == "g")
	{
		es = "Residue/Group " + hiddenGroups[hiddenGroups.length - 1] + " Re-Displayed";
		hiddenGroups.length = hiddenGroups.length - 1;
	}
	else if (hideMode == "a")
	{
		es = hiddenAtoms[hiddenAtoms.length - 1];
		es = es.substring(es.indexOf(" ")); // trim off leading serial number
		es += " Re-Displayed";
		hiddenAtoms.length = hiddenAtoms.length - 1;
	}
	else if (hideMode == "r")
	{
		es = "Range " + hiddenRanges[hiddenRanges.length - 1] + " Re-Displayed";
		hiddenRanges.length = hiddenRanges.length - 1;
	}
	else alert("Programmer's error: unhideLast() with hideMode blank");

	reDisplay("", makeEchoSpt(es)); // put echo last so not overwritten
	showHelp2("makeHideHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function reDisplay(echoSpt, trailingSpt)
{
	var rds = "# BEGIN reDisplay();\n" + echoSpt;

//	alert("jcontrol.js #12: reDisplay():\ncurrentView = " + currentView +
//		"\n useConSurfColors = " + useConsurfColors);

	rds += eval(currentView);

	if (telAvivMode) // pepsurf obeys useConsurfColors
	{
		// if using ConSurf colors, recolor ConSurf chain(s)
		if (useConsurfColors)
		{
			// don't recolor pepsurf (to retain transparency as needed)
			if (!(pepsurfMode && controlPanel == "consurf"))
			{
				var ccs = makeConsurfColorsSpt(); // works for pepsurf too
//			showSptInWindow(ccs);
				rds += ccs;
			}
		}
		else rds +=
"select not hetero;\n\
color chain;\n\
color cartoon chain;\n\
color backbone chain;\n\
";
	}

	// don't obey water/ligand buttons when contactsShowing
	if (!contactsShowing && !(controlPanel == "consurf" && pepsurfMode))
	{
		// OBEY LIGANDS BUTTON
		if (toggleIsDown[ligandIndex])
		{
			
			// toggleDownSpt[ligandIndex]; colors cpk unconditionally
			rds += ligandClearSpt + "spacefill;\n"; 
			if (match(currentView, "precontacts"))
				rds += "color [x" + colorLigand + "];\n";
		}
		else
			rds += ligandClearSpt; // clears		

		// OBEY WATER BUTTON
		if (toggleIsDown[waterIndex])
			rds += "select water; spacefill;\n"; // don't change color
		else
			rds += "restrict not water;\n";
	}

	rds += trailingSpt; // e.g. center, echo
	rds += "# END reDisplay();\n";

	doMolViewSpt(rds); // in reDisplay()
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function centerVisible()
{
	reDisplay(makeEchoSpt("Visible Chains Centered"),
		"select (" + proteinSpt + ", nucleic) and not ~hidden_jdef;\n" +
		"center selected;\n");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function centerContacting()
{
	var ccs = "center ~cont_current;\n";

	ccs += makeEchoSpt("Visible Contacting Atoms Centered");

	doMolViewSpt(ccs);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function makeSelectHiddenSpt()
{
	var hs = "# makeSelectHiddenSpt();\n" +
		"select none;\n";

	var ih;
	if (hiddenChains.length > 0)
	{
		// Changing from 'restrict not' to 'select selected or' to enable
		// centerVisible();

		if (hiddenChains[0].length > 1)
		{
			if (hiddenChains[0] == "Protein")
				hs += "select selected or ((" + proteinSpt + ") and not hetero);\n";
			else
				hs += "select selected or (nucleic and not hetero);\n";
		}
		else
		{
			hs += "select selected or ((";
			for (ih = 0; ih < hiddenChains.length; ih++)
			{
				if (ih > 0)
					hs += ",";
				hs += ":" + hiddenChains[ih];
			}
			hs += ") and not hetero);\n";
		}
	}
	if (hiddenGroups.length > 0)
	{
		// This is to workaround a bug in Jmol 10.00.48.
		// Should be fixed in a future Jmol release.
		hs += "set bondmode or;\n";

		hs += "select selected or (";
		for (ih = 0; ih < hiddenGroups.length; ih++)
		{
			if (ih > 0)
				hs += ",";
			hs += hiddenGroups[ih];
		}
		hs += ");\n";
	}
	if (hiddenAtoms.length > 0)
	{
		// This is to workaround a bug in Jmol 10.00.48.
		// Should be fixed in a future Jmol release.
		hs += "set bondmode or;\n";

		for (ih = 0; ih < hiddenAtoms.length; ih++)
		{
			hs += "select selected or (atomno=";
			hs += firstWord(hiddenAtoms[ih]);
			hs += ");\n";
		}
	}
	for (ih = 0; ih < hiddenRanges.length; ih++)
	{
		hs += "select selected or " + hiddenRanges[ih] + ";\n";
	}

	if (hideProtein)
		hs += "select selected or " + proteinSpt + ";\n";
	if (hideDNA)
		hs += "select selected or DNA;\n";
	if (hideRNA)
		hs += "select selected or RNA;\n";
	if (hideCarbohydrate)
		hs += "select selected or " + carbohydrateSpt + ";\n";
	if (hideHydrogen)
		hs += "select selected or hydrogen;\n";

//	hs += "define ~hidden_jdef selected;\n"; NOW DONE IN makeDefineHiddenSpt()

	return hs;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function makeHideSpt()
{
	var hs = makeDefineHiddenSpt();

	if (hiddenRangeStart != "") // mark with [
	{
		hs +=
			"select " + hiddenRangeStart + ";\n" +
			"set labeloffset 0 0;\n" +
			"label [;\n" +
			"set fontsize 20;\n";

		if (toggleIsDown[backgroundIndex])
			hs += "color labels black;\n";
		else
			hs += "color labels white;\n";
	}

	if (hs.length > 0)
	hs = "# makeHideSpt();\n" + hs;

	return hs;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function makeDefineHiddenSpt()
{
	var hs = makeSelectHiddenSpt();

	if (hs.length > 0)
	{
		if (!invertHidden)
		{
			hs += "define ~hidden_jdef selected;\n";
			hs += "restrict not selected;\n"; // makeHideSpt()
		}
		else // INVERTED
		{
			hs += "restrict selected;\n"; // makeHideSpt()
			hs += "select not selected;\n";
			hs += "define ~hidden_jdef selected;\n";
		}
	}

	return hs;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function showContacts()
{
	if ((selectedChains.length + selectedGroups.length + selectedAtoms.length
		+ selectedFound.length + selectedRanges.length == 0) &&
		!selectedWater)
		{
			alert("Before Contacts can be shown, you must first\n" +
				"select a target by clicking on the molecule,\n" +
				"or checking \"Atoms with Halos\".");
			return;
		}

	if (telAvivMode)
	{
		useConsurfColors = true;
		colorContactsTargetGray = true;
	}

	selectMode = "";

	// flags that affect other views are also set in doViewLink(), namely
	// contactsShowing and markContactsTargets (maybe redundant here)?
	contactsShowing = true;
	markContactsTargets = true;

	// flags that affect only contacts are set here

	targetSF = contactingSF = true;
	targetCPK = contactingCPK = false;

	backboneContacts = true;
	hydrogensContacts = false;
	labelContacts = false;

	var spt = makeGenerateContactsSpt();
	if (telAvivMode)
		spt += makeEchoSpt(serverName + " Colors Restored");

	doMolViewSpt(spt);
	currentView = "makeContactsViewSpt(false, false)";

	showHelp("makeContactsShownHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function toggleAxes()
{
	if (document.setForm.axes.checked)
	{
		scriptToJmol("set axes on;\n");
		axesOn = true;
	}
	else
	{
		scriptToJmol("set axes off;\n");
		axesOn = false;
	}
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function toggleBoundbox()
{
	if (document.setForm.boundbox.checked)
	{
		scriptToJmol("set boundbox on;\n");
		boundboxOn = true;
	}
	else
	{
		scriptToJmol("set boundbox off;\n");
		boundboxOn = false;
	}
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function toggleUnitcell()
{
	var ducs = "";
	if (document.setForm.unitcell.checked)
	{
		ducs += "set unitcell on;\n";
		ducs += "set echo top left; echo;\n";
		unitcellOn = true;
	}
	else
	{
		ducs += "set unitcell off;\n";
		unitcellOn = false; // must be before makeEchoPdbIdSpt()!
		ducs += makeEchoPdbIdSpt("");
	}

//	alert(ducs);
	scriptToJmol(ducs); // in toggleUnitcell()
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function getHiddenTot()
{
	var hiddenTot =
		hiddenChains.length +
		hiddenGroups.length +
		hiddenAtoms.length +
		hiddenRanges.length;

	if (hideProtein) hiddenTot++;
	if (hideDNA) hiddenTot++;
	if (hideRNA) hiddenTot++;
	if (hideCarbohydrate) hiddenTot++;
	if (hideHydrogen) hiddenTot++;

	return hiddenTot;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function changeContactsBackbones()
{
	var bb = top.document.contactsForm.contactsBackbones.checked;
	if (bb)
		doMolViewSpt(showContactsBackbonesSpt);
	else
		doMolViewSpt(hideContactsBackbonesSpt);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function changeContactsTargetsMarks()
{
	var conhal = top.document.contactsForm.markContactsTargets.checked;
	if (conhal)
		markContactsTargets = true;
	else
		markContactsTargets = false;
	doMolViewSpt("");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function hideMonitors()
{
	doMolViewSpt("monitors off;");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function changeSlabThickness()
{
	var thk = getRadioValue(top.document.slabForm.slabThickness);	
	slabThickness = thk;

	doMolViewSpt(makeSlabSpt(false));

}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function match(name, subname)
{
	if (name.toLowerCase().indexOf(subname.toLowerCase()) == -1)
		return false;
	return true;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function doFind()
{
	var find = document.findForm.toFind.value;
//	var quoted = false;
//	if (find.charAt(0) == "\"")
//		quoted = true;

	// STRIP OUT QUOTE MARKS & CHANGE CASE TO UPPER
	find = find.toUpperCase().replace(/\"/g, "");

	// SINGULARIZE SPACES
	while (find.indexOf("\ \ ") != -1)
		find = find.replace(/\ \ /g, " ");

//	if (!quoted)
//	{
//		// GUARANTEE COMMA BEFORE EVERY SPACE
//		var is;
//		for (is = 0; is < find.length; is++)
//			if (find.charAt(is) == " " && is > 0)
//				if (find.charAt(is - 1) != ",")
//					find = find.substring(0, is) + "," + find.substring(is);
//	}

	// BUG in Jmol 48: u works but U is not recog. and kills selection
	// EMBEDDED
	find = find.replace(/\ U,/g, "\ u,");
	find = find.replace(/,U,/g, ",u,");
	// BEGINNING
	find = find.replace(/^U,/g, "u,");
	// END
	find = find.replace(/\ U$/g, "\ u");
	find = find.replace(/,U$/g, ",u");

	// REWRITE QUERY WITHOUT QUOTES INTO SLOT
	document.findForm.toFind.value = find;

	// find it
	toFind = find;

	// makeFindSpt() sets background black if (forceBackgroundBlack):
	// Each doFind() forces the background to black.
	// But after the halos are rendered, subsequent refreshes don't force
	// the background, so user has control.
	setButtonState("up", backgroundIndex);
	forceBackgroundBlack = true;

	doMolViewSpt(""); // makeFindSpt() is called automatically when toFind
	// is not blank.


	// redisplay help
	showHelp2("makeFindHelp()");
	setTimeout("document.findForm.toFind.select()", 100);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function setButtonState(state, istate)
{
//	alert("jcontrol.js #9 setButtonState(" + state + ", " + istate + ")");
	var imgnum = eval("document.toggle" + istate);

	if (state == "up")
	{
		toggleIsDown[istate] = false;
		imgnum.src = "up.gif";		
	}
	else
	{
		toggleIsDown[istate] = true;
		imgnum.src = "down.gif";		
	}
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function changeContactsView()
{
	// this change is initiated from the form, so
	// true1 = read radio buttons
	// true 2 = read checkboxes
	doMolViewSpt(makeContactsViewSpt(true, true));
	showHelp2("makeContactsShownHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// setContactsView(vw) sets one of four preset views from snapshots
// in the contacts shown help.

function setContactsView(vw)
{
	var tailSpt = makeEchoPdbIdSpt("");
	if (vw == 1)
	{
		targetSF = true;
		contactingSF = true;
		targetCPK = false;
		contactingCPK = false;		
	}
	else if (vw == 2)
	{
		targetSF = true;
		contactingSF = false;
		targetCPK = false;
		contactingCPK = false;		
	}
	else if (vw == 3)
	{
		targetSF = true;
		contactingSF = false;
		targetCPK = true;
		contactingCPK = true;
	}
	else if (vw == 4)
	{
		targetSF = false;
		contactingSF = false;
		targetCPK = true;
		contactingCPK = true;
		tailSpt = makeEchoMsgSpt('Double click each atom to measure a distance.',
			'top', '20', '[xff4040]');
	}

	// preset views force radio buttons, so
	// false = don't read radio buttons
	// true = read checkboxes
	doMolViewSpt(makeContactsViewSpt(false, true) + tailSpt);
	showHelp2("makeContactsShownHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function toggleContactsRadioButtons()
{
	var showrad = top.document.contactsForm.contactsRadioButtons.checked;	
	if (showrad)
		contactsRadioViews = true;
	else
		contactsRadioViews = false;
	showHelp2("makeContactsShownHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function clearFindForm()
{
	document.findForm.toFind.value = "";
	doFind();
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function changePreContactsView()
{
	// SPACEFILL OR CARTOON
	preContactsView = getRadioValue(document.contactsForm.pCView);

	var fc = document.contactsForm.selectFound.checked;

	// SELECT FOUND?
	if (fc && toFind.length == 0)
	{
		alert("First, please use Find.. (above)\n" +
			"to apply halos to some atoms.");
		document.contactsForm.selectFound.checked = false;
		return;
	}

	if (fc)
		selectedFound = toFind;
	else
		selectedFound = "";

	// REGENERATE ~targ_current (selectedFound does not use pickCallback)
	// with makeSelectSpt()

	// REGENERATE VIEW
	doMolViewSpt(makeSelectSpt() + makePreContactsSpt());
	showHelp2("makePreContactsHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function cancelCenteringNoHelp()
{
	if (centerMode)
	{
		centerMode = false;
		doMolViewSpt(setPickingIdentSpt); // cancels set picking center
	}
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function changePreContactsWater(tailSpt)
{
	var pcw = top.document.contactsForm.preContactsWater.checked;
	preContactsWater = pcw;
	var pcws = "";

	if (pcw)
	{
		pcws = "select water and not hydrogen; color [x" + colorSolvent + "]; spacefill;\n";
		setButtonState("down", waterIndex);
	}
	else
	{
		pcws = "select water; spacefill off;\n";
		setButtonState("up", waterIndex);
	}

	doMolViewSpt(pcws + tailSpt);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function cancelSelectedRange()
{
	selectedRangeStart = "";
	doMolViewSpt(makeSelectSpt()); // to reset ~targ_current
	showHelp2("makePreContactsHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function cancelHiddenRange()
{
	if (hiddenRangeStart == "")
		return;
	cancelHiddenRangeNoHelp();
	showHelp2("makeHideHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function cancelHiddenRangeNoHelp()
{
	if (hiddenRangeStart == "")
		return;
	hiddenRangeStart = "";
	doMolViewSpt(makeEchoSpt("")); // to blank "Range Started at "
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function isStdAA(aaq)
{
	aaq = "" + aaq.toUpperCase();
//	alert("jcontrol.js #10: isStdAA receives " + aaq);

	switch (aaq)
	{
		case ("ALA"):
		case ("ARG"):
		case ("ASN"):
		case ("ASP"):
		case ("CYS"):
		case ("GLN"):
		case ("GLU"):
		case ("GLY"):
		case ("HIS"):
		case ("ILE"):
		case ("LYS"):
		case ("LEU"):
		case ("MET"):
		case ("PHE"):
		case ("PRO"):
		case ("SER"):
		case ("THR"):
		case ("TRP"):
		case ("TYR"):
		case ("VAL"):
			return true;
		default:
			return false;
	}	
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// PDB format 3.1: A,C,G,T,U,I, and Dx for all those!
// (See HET in http://www.wwpdb.org/documentation/format3.1-20070719.pdf)

function isStdNucleotide(nq)
{
	nq = "" + nq.toUpperCase();
//	alert("jcontrol.js #11: isStdNucleotide receives " + nq);

	switch (nq)
	{
		case ("A"):
		case ("C"):
		case ("G"):
		case ("I"):
		case ("T"):
		case ("U"):
		case ("DA"):
		case ("DC"):
		case ("DG"):
		case ("DI"):
		case ("DT"):
		case ("DU"):
			return true;
		default:
			return false;
	}	
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function changePreContactsWaterTarget()
{
	selectedWater = document.contactsForm.preContactsWaterTarget.checked;

	if (selectedWater)
		top.document.contactsForm.preContactsWater.checked = true;

	changePreContactsWater(makeSelectSpt());
	showHelp2("makePreContactsHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function doCatPiSB()
{
	clearSelectedArrays();
	selectedFound = "LYS, ARG";
	var css = makeDefineHiddenSpt() + // to define ~hidden_jdef in Jmol
		makeDefineContactsSpt();
	clearSelectedArrays();

	contactsShowing = false;

	currentView = "makeCatPiSBSpt(false)";

	showHelp2("makeCatPiSBHelp()");
	showCatPiSB(css);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function showCatPiSB(preSpt)
{
	setButtonState("down", backgroundIndex);
	setButtonState("up", ligandIndex);
	setButtonState("up", waterIndex);

	doMolViewSpt(preSpt + makeCatPiSBSpt(true));
	showHelp("makeCatPiSBHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function clearBoxes()
{
	var spt = "";
	if (axesOn)
	{
		axesOn = false;
		spt += "set axes off;\n";
	}
	if (unitcellOn)
	{
		unitcellOn = false;
		spt += "set unitcell off;\n";
	}
	if (boundboxOn)
	{
		boundboxOn = false;
		spt += "set boundbox off;\n";
	}
	return spt;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function resetPrep()
{
	toFind = ""; // must be before help!
	clearHidden();

	resetPrepConsurf();
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function resetPrepConsurf() // keeps hidden and found=halos
{
	showCatPi = false;
	colorCatPiSBChain = false;
	resetContacts();

	// avoid hiding default FG view on Reset
	processHeaderBeforeMolView = false; // needed only for initial load
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function doAnomalousAtoms()
{
	showAnomalous = document.anomalousForm.showAA.checked;
	var rendAA = getRadioValue(document.anomalousForm.renderAA);
	anomalousDots = (rendAA == "d");

//	doMolViewSpt("");
	reDisplay("", "");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function resetContacts()
{
	markContactsTargets = true;
	targetSF = true;
	preContactsView = "sf"; // must be done before showing help
	preContactsWater = false;
	selectedWater = false;
	labelContacts = false;

	showContactsHBonds = true;
	showContactsMeMi   = true;
	showContactsHphob  = true;
	showContactsSB     = true;
	showContactsCatPi  = true;
	showContactsSticks = true;
	showContactsWater  = true;
	showWaterBridges   = true;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function showFGControls(fromx) // for ConSurf
{
	clearControls();
	writeFGControls();

	if (fromx == "fromConsurf")
	{
		useConsurfColors = true;
		showHelp("makeFGFromConsurfHelp()");
	}
	else	
		showHelp("makeIntroHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function clearControls() // for showFGControls() <--> showConsurfControls()
{
	// don't clear toggle button arrays; they persist between control panels!

	// don't clear view link arrays because the indices persist!

	cancelCenteringNoHelp(); // centerMode false + set picking on

	hideMode = false;

	contactsShowing = false;

	// portions hidden or haloed remain in either transition.
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function returnToContacts()
{
	// can't use clearControls() b/c it clears contactsShowing!
	cancelCenteringNoHelp(); // centerMode false + set picking on
	hideMode = false;

	showHelp("makeContactsShownHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
var checkToShowLabelsMsg = "(Labels: Check 'Show' to show labels.)";

function toggleLabelsShow()
{
	labelsOn = !labelsOn;

	var msg = "Labels hidden.";

	if (labelsOn)
		msg = "Labels re-displayed.";

	reDisplay(makeEchoSpt(msg), "");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function toggleLabelsFront()
{
	labelsFront = !labelsFront;

	var msg = "Some labels may be hidden at the back.";
//	var tailspt = "set labelsFront off;\n";
	var tailspt = "select all;\n set labelGroup;\n"; // not labelsGroup!

	if (labelsFront)
	{
		msg = "All labels are now visible at the front.";
//		tailspt = "set labelsFront on;\n";
		tailspt = "select all;\n set labelFront;\n"; // not labelsFront!
	}

	if (!labelsOn)
		msg = checkToShowLabelsMsg;

	reDisplay(makeEchoSpt(msg), tailspt);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
function toggleLabelsID()
{
	labelsID = !labelsID;

	var msg = "ID's of labeled atoms are hidden.";

	if (labelsID)
		msg = "Labeled atoms are identified.";

	if (!labelsOn)
		msg = checkToShowLabelsMsg;

	reDisplay(makeEchoSpt(msg), "");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

