var iSlideshowInterval = 7500; //ADJUSTABLE HERE... the number of milliseconds to wait between slideshow image changes. (originally 2500 but that was too hectic.)
var selectedCell1 = new Object();
var selectedCell2 = new Object();
var selectedCell3 = new Object();
var selectedCell4 = new Object();
var selectedCell5 = new Object();
var selectedCell6 = new Object();
var selectedCell7 = new Object();
var imagePositionFactor =  112;      // coronal range goes until 12450, so this is the max that will fit
var imageOffset = 13;                // offset within image (coronal is 8)
var sagittalFactor = 95;             // sagittal range goes until 6450
var sagittalOffset =  29;            // sagittal graphic starts 28 pixels in
var maxMove = 119;
var CurrentOrientation = "coronal";
var label1 = "Allen Reference Atlas";
var label2 = "";
var label3 = "";
var label4 = "";
var position1 = "";
var position2 = "";
var position3 = "";
var position4 = "";
var browserName = "";
var correspondingAtlasFile = "";
var bLCconfirmed = false; //this variable is changed when the referenceImage object sends in notice that it is working. This confirms that the LocalConnection for Flash is working. 
var UNDEFINED;
//*** KSB: testing the build system by putting this line in the code. I should see it in builds after 7/6/2005. ***
// called when body is loaded to set up the first selected image
function setInitialSelected()
{
    writeLog("setInitialSelected()");
    //NOTE: if you ever decide to make this page dynamic, and pass in a specific field to choose initially instead of the first one, remember that getElementsByTagName returns nested matches as well, so just putting in a different index will not work. 
    //  in that case, I would need to either filter the list of "td" elements to only include non-nested tds, OR I would need to identify a particular cell by its ID. 
    var i = "0";
    var oIframe;
    var oDoc;
    if (bIsAtlasOnly)
    {
        //if this is ATLAS ONLY, click on the first atlas cell. 
        if (atlasSagByDefault == true)
        {
            //if this is supposed to show Sagittal atlas-only on load...
            doNavCommand('annotation');
            doNavCommand('sagittal');
            setTimeout("doNavCommand('sagittal')", 4000);
            currentAtlasWindow = 5;
        }
        writeLog("setInitialSelected() detects bIsAtlasOnly: " + paramInitialIndex);
        var iInitialIndex = parseInt(paramInitialIndex); //choose which image (0-based) to start with
        iInitialIndex = (iInitialIndex*3); //0=first image, 3=second image, 6=third image...
        writeLog("selecting iframe" + currentAtlasWindow);
        oIframe = document.getElementById("iframe" + currentAtlasWindow);
        oDoc = (oIframe.contentWindow || oIframe.contentDocument);
        try
        {
            if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
        }
        catch(e){}
        if (oDoc.getElementById("OverallTableA"))
        {
        try
        {
            oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0].style.border='3px solid #cccccc';
        }
        catch(e){}
            try
            {
            eval('selectedCell' + currentAtlasWindow + ' = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[iInitialIndex].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0]');
            eval("selectedCell" + currentAtlasWindow + ".style.border='3px solid black'");
            }
            catch(e)
            {
                writeLog("ERROR setInitialSelected() constructing selectedCell for window "  + currentAtlasWindow + ": " + e.message);
                writeLog("This seems to be the result of an incomplete thumbnails page. View source of the thumbnails area and see.");
                writeLog("STOPPING code execution because it will error now anyway.");
                return;
            }
        }
        else
        {
            writeLog("There is a problem. Window "  + currentAtlasWindow + " has no OverallTableA: " + e.message);
        }
        //this logic is not sufficient. I need to set CurrentOrientation or currentAtlasWindow correctly. 
        if (currentAtlasWindow == "1" || currentAtlasWindow == "7")
        {
            CurrentOrientation = "coronal"; 
        }
        else
        {
            CurrentOrientation = "sagittal";
        }
        var oSC = eval("selectedCell" + currentAtlasWindow);
        // ********************************* 11/4/2005 KSB added this code to force SARA to sync with non-zero initialIndex
    stopSlideshow();
    onTableCellClick(oSC, true, false);
    var path = oSC.getAttribute("id"); //these get sent in to the WC in tellFlashWindows a few lines below here.
    var XMaskPath = oSC.getAttribute("XMaskPath");
    if (XMaskPath == "")
    {
        XMaskPath = "//notThere.pff"; //just a dummy path that leads nowhere to turn off the button.
    }
        // *********************************
        try
        {
            ip = getBarPositionNumber(oSC).toString();
        }
        catch(e)
        {
            writeLog("ERROR setInitialSelected() calling getBarPositionNumber() " + e.message);
        }
        tellFlashWindows("Orientation", CurrentOrientation, "InitialPosition", ip, "", "", "", "", "",  "", "", "", "", "", "exPath", XMaskPath, "zoomifyImagePath", path);
        //also, assign selectedCell5 and selectedCell6.
        if (currentAtlasWindow != "1")
        {
        oIframe = document.getElementById("iframe1");
        oDoc = (oIframe.contentWindow || oIframe.contentDocument);
        try
        {
            if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
        }
        catch(e){}
        if (oDoc.getElementById("OverallTableA") && oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td").length > 0)
        {
            selectedCell1 = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
            selectedCell1.style.border='3px solid black';
        }
        }
        if (currentAtlasWindow != "5")
        {
        oIframe = document.getElementById("iframe5");
        oDoc = (oIframe.contentWindow || oIframe.contentDocument);
        try
        {
            if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
        }
        catch(e){}
        if (oDoc.getElementById("OverallTableA") && oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td").length > 0)
        {
            selectedCell5 = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
            selectedCell5.style.border='3px solid black';
        }
    }
    if (currentAtlasWindow != "6")
    {
        oIframe = document.getElementById("iframe6");
        oDoc = (oIframe.contentWindow || oIframe.contentDocument);
        try
        {
            if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
        }
        catch(e){}
        if (oDoc.getElementById("OverallTableA") && oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td").length > 0)
        {
            selectedCell6 = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
            selectedCell6.style.border='3px solid black';
        }
        }
        if (currentAtlasWindow != "7")
    {
        oIframe = document.getElementById("iframe7");
        oDoc = (oIframe.contentWindow || oIframe.contentDocument);
        try
        {
            if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
        }
        catch(e){}
        if (oDoc.getElementById("OverallTableA") && oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td").length > 0)
        {
            selectedCell7 = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
            selectedCell7.style.border='3px solid black';
        }
        }
        //we are bAtlasOnly
        return;
    }
    try{
        if (!bIsAtlasOnly)
        {
            i = "1";
            //since I need values from the secomnd set to give to the first set, I do the second set first...
            var iInitialIndex = paramInitialIndex; //choose which image (0-based) to start with
            i = "1a";
            iInitialIndex = (iInitialIndex*3); //0=first image, 3=second image, 6=third image...
            //must drill into the iframe
            i = "1b";
            oIframe = document.getElementById("iframe2");
            i = "1c";
            oDoc = (oIframe.contentWindow || oIframe.contentDocument);
            i = "1d";
            try
            {
                if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
            }
                catch(e){}
            i = "1e";
            if (oDoc.getElementById("OverallTableA") && oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td").length > 0)
            {
            i = "1f";
            selectedCell2 = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[iInitialIndex].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
            i = "1g";
            selectedCell2.style.border='3px solid black';
            }
            i = "1h";
            var targetIndex = 0;
            i = "1i";

            //OK, but just setting this single number may not be enough. I may have other "td"s? 
            //first, I will test the value from the "raFile" attribute of the first thumbnail of the second window. 
            try
            {
            i = "1j";
            correspondingAtlasFile = selectedCell2.getAttribute("raFile");
            //OK, now that I have the file name, get the corresponding atlas index...
            writeLog("setInitialSelected calls getAtlasIndex('" + correspondingAtlasFile + "', '" + CurrentOrientation + "')");
            targetIndex = getAtlasIndex(correspondingAtlasFile, CurrentOrientation);
            }
            catch(e)
            {
            i = "1k";
            writeLog("ERROR setInitialSelected() setting targetIndex: " + e.message);
            //alert("ERROR finding raFile:\n" + e.message);
            }
            i = "1m";
            //then use that value to select the appropriate cell in the first set. 
        }
        oIframe = document.getElementById("iframe" + currentAtlasWindow);
        oDoc = (oIframe.contentWindow || oIframe.contentDocument);
        try
        {
            if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
        }
        catch(e){}
        if (oDoc.getElementById("OverallTableA"))
        {
            if (currentAtlasWindow == "1")
            {
                selectedCell1 = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
            }
            else
            {
                selectedCell5 = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
                oIframe = document.getElementById("iframe1");
                oDoc = (oIframe.contentWindow || oIframe.contentDocument);
                try
                {
                    if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
                }
                catch(e){}
                if (oDoc.getElementById("OverallTableA") && oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td").length > 0)
                {
                    selectedCell1 = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
                    selectedCell1.style.border='3px solid black';
                }
            }
        }
        i = "2";
        // Update position factor if set is sagittal
        if (!bIsAtlasOnly)
        {
            CurrentOrientation = Orientation2; //we are starting focus on the second set
        }
        else
        {
            CurrentOrientation = Orientation1;
        }
        i = "3";
        //**********************************
        //HERE is code to update the bar position...
        if (currentAtlasWindow == "1")
        {
            setBarPosition(selectedCell1);
        }
        else
        {
            setBarPosition(selectedCell5);
        }
        //**********************************

        if (!bIsAtlasOnly)
        {
            //I also need to color the first image for each of the other windows.
            i = "7";
            oIframe = document.getElementById("iframe3");
            oDoc = (oIframe.contentWindow || oIframe.contentDocument);
            try
            {
                if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
            }
                catch(e){}
            if (oDoc.getElementById("OverallTableA") && oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td").length > 0)
            {
            selectedCell3 = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
            selectedCell3.style.border='3px solid black';
            }
            i = "9";
            oIframe = document.getElementById("iframe4");
            i = "9a";
            oDoc = (oIframe.contentWindow || oIframe.contentDocument);
            i = "9b";
            try
            {
                if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
            }
                catch(e){}
            i = "9c";
            if (oDoc.getElementById("OverallTableA") && oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td").length > 0)
            {
            i = "9d";
            selectedCell4 = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
            i = "9e";
            selectedCell4.style.border='3px solid black';
            }
        }
        i = "9f";
        oIframe = document.getElementById("iframe5");
        oDoc = (oIframe.contentWindow || oIframe.contentDocument);
        try
        {
            if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
        }
        catch(e){}
        i = "9g";
        if (oDoc.getElementById("OverallTableA") && oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td").length > 0)
        {
        selectedCell5 = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
        selectedCell5.style.border='3px solid black';
        }
        i = "9h";
        oIframe = document.getElementById("iframe6");
        oDoc = (oIframe.contentWindow || oIframe.contentDocument);
        try
        {
            if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
        }
        catch(e){}
        i = "9i";
        if (oDoc.getElementById("OverallTableA") && oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td").length > 0)
        {
        selectedCell6 = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
        selectedCell6.style.border='3px solid black';
        }
        i = "9iA";
        oIframe = document.getElementById("iframe7");
    oDoc = (oIframe.contentWindow || oIframe.contentDocument);
    try
    {
        if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
    }
    catch(e){}
    i = "9iB";
    if (oDoc.getElementById("OverallTableA") && oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td").length > 0)
    {
    selectedCell7 = oDoc.getElementById("OverallTableA").getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
    selectedCell7.style.border='3px solid black';
        }
        
        i = "10";
        if (CurrentOrientation == "sagittal")
        {
        var ip = "0";
        var xpath = "";
        try
        {
            ip = getBarPositionNumber(selectedCell2).toString();
            xpath = selectedCell5.getAttribute("XMaskPath");
            if (xpath == "")
            {
                xpath = "//notThere.pff"; //just a dummy path that leads nowhere to turn off the button.
            }
        }
        catch(e)
        {
            writeLog("ERROR setInitialSelected() setting ip: " + e.message);
        }
        var initialSagittalPath = "";
        var zip = ""; //zoomifyImagePath
        if (correspondingAtlasFile.indexOf("ImageNotAvailable") > -1) //if the raFile contains "ImageNotAvailable"
        {
            initialSagittalPath = selectedCell5.id;
            zip = "zoomifyImagePath";
        }
        //tellFlashWindows about the exPath... that way it would be there on page load. 
        tellFlashWindows("exPath", xpath, zip, initialSagittalPath, "Orientation", "sagittal", "InitialPosition", ip, "",  "", "", "", "", "", "",  "", "", "");
        }
        else
        {
            if (!bIsAtlasOnly)
            {
            syncWith(selectedCell2);
        }
        }
        i = "11";
    }
    catch(e)
    {
        writeLog("ERROR setInitialSelected() at " + i + ": " + e.message);
        //alert("ERROR, setInitialSelected() at " + i + "\n" + e.message);
    }
}
// draws border around selected image and loads up image in frame with Flash zoom
function onTableCellClick(currentCell, bSyncAtlas, isSync)
{
    writeLog("onTableCellClick([object], " + bSyncAtlas + ", " + isSync + ")");
    writeLog(">>> currentFocusedWindow: " + currentFocusedWindow);
    writeLog(">>> currentAtlasWindow: " + currentAtlasWindow);
    if (document.getElementById("cbAllowSync").checked != true && innerButtonUsed == false) //this allows the users to uncheck a box and stop the sync.
    {
        writeLog("Sync not allowed, changing command.");
        bSyncAtlas = false; 
    }
    var where = "zero"; //this is just debug code, to let me know where the error occurs. 
    var p1 = "", p2 = "", c1 = "", c1v = "", c2, c2v = "", c3 = "", c3v = "", c4 = "", c4v = "", c5 = "", c5v = "", c6 = "", c6v = "", c7 = "", c7v = "", c8 = "", c8v = "";
    try{
        //OK, the problem with syncing is that I am using "currentFocusedWindow", which will not be the atlas when syncing. 
        var targetWindowNumber = currentFocusedWindow;
        if (isSync)
        { 
        where = "a";
        targetWindowNumber = currentAtlasWindow;
        }
        var displayWindow = targetWindowNumber;
        if (currentFocusedWindow == "1")
        {
            displayWindow = currentAtlasWindow;
        }
        where = "b";
        if (currentCell.id != eval("selectedCell" + displayWindow + ".id"))
        {
        where = "c";
        // Update border around image
        try
        {
            eval("selectedCell" + displayWindow + ".style.border='3px solid #cccccc'");
        }
        catch(e)
        {
            //alert("cannot change border color.\n" + e.message);
        }
        try
        {
            currentCell.style.border = "3px solid #000000";
        }
        catch(e)
        {
            writeLog("ERROR setting current cell border color: " + e.message);
            //alert("ERROR setting current cell border color.\n" + e.message);
            return;
        }
        where = "d";
        var path = currentCell.id; //the id is the path for the main zoomify image
            where = "d1";
        var setName = currentCell.getAttribute("imageSetName"); //I don't think I use this in WC, just sceneControl
            where = "d2";
        var fileName = currentCell.getAttribute("imageName"); //to display in the littlw indows.
            where = "d3";
        var setID = currentCell.getAttribute("imageSetId"); //the setID is used to get Metadata.

            where = "d4";
        try
        {
            var XMaskPath = currentCell.getAttribute("XMaskPath");
            if (XMaskPath == "")
                {
                XMaskPath = "//notThere.pff"; //just a dummy path that leads nowhere to turn off the button.
                }
        }
        catch(e)
        {
            var XMaskPath = "//notThere.pff";
            writeLog("ERROR getting XMaskPath: " + e.message);
        }
            where = "d5";
        var i = displayWindow; //targetWindowNumber;
            where = "e";
        if (i == "1" || i == "5" || i == "6" || i == "7") i = ""; //the first set is not appended. 

        c6 = "setID" + i;
        c6v = setID;
            where = "e4";
        c1 = "fileName" + i;
            where = "e5";
        c1v = fileName;
            where = "e6";
        c2 = "exPath" + i;
            where = "e7";
        c2v = XMaskPath;
            where = "e8";
        c3 = "zoomifyImagePath" + i;
            where = "e9";
        c3v = path;
            where = "f";
        //don't change the label for the Atlas, but do for the other three
        if (targetWindowNumber != "1" && targetWindowNumber != "5" && targetWindowNumber != "6" && targetWindowNumber != "7")
        {
            c4 = "label" + targetWindowNumber;
            c4v = setName;
            where = "g";
        }
        var framei = displayWindow;
        if (framei == "1")
        {
            //
            if (CurrentOrientation == "sagittal")
            {
                //
                if (currentSagittalView == "annotation")
                {
                    //annotation
                    framei = 5;
                }
                else
                {
                    //nssl
                    framei = 6;
                }
            }
            else
            {
                if (currentCoronalView == "annotation")
        {
            //annotation
            framei = 1;
        }
        else
        {
            //nssl
            framei = 7;
        }
            }
        }
        writeLog(">>SETTING selectedCell" + framei + " = " + currentCell.id);
        eval("selectedCell" + framei + " = currentCell");
        where = "h";
        }
        where = "h2";
        // Change position bar
        var p = eval("Orientation" + displayWindow);
        c5 = "Orientation";
        if (document.getElementById("cbAllowSync").checked == false) c5 = ""; //don't announce Orientation unless necessary.
        if (innerButtonUsed) 
        {
            writeLog("innerButtonUsed, so use 'Orientation'");
            c5 = "Orientation";
            innerButtonUsed = false;
        }
        c5v = p;
        where = "j";
        if (!isSync) //added 12/7 to stop focus-stealing.
        {
        CurrentOrientation = p;
        }
        //************************************************************************
        //note: we need to let the atlas know which image to pick.
        if (bSyncAtlas) //if this is not a request from the Atlas itself...
        {
        //***********************
        //I would like to use "syncWith()" instead if this repeated code, 
        //syncWith(currentCell);
        //***********************
        where = "k";
        //we need to sync the atlas with this choice. 
        var correspondingAtlasNumber = 0;
        try
        {
            where = "k1";
            correspondingAtlasFile = currentCell.getAttribute("raFile");
            if (currentAtlasWindow == "6" && (currentFocusedWindow == "1" || currentFocusedWindow == "6")) //but only do this when we are not syncing. 
            {
                //this gets the "annotated" file name in the "nssl" set, so the index gets found correctly.
                correspondingAtlasFile = currentCell.getAttribute("XMaskPath");
            }
            //TODO: July 2006 KSB: the "if" (above) should be expanded to include frame 7
            //OK, now that I have the file name, get the corresponding atlas index...
            //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
            //KSB 8/23/2005 added the if here to prevent currentAtlasWindow being set while sync box is unchecked. 
            if (document.getElementById("cbAllowSync").checked == true)// || innerButtonUsed == true
            {
            if (CurrentOrientation == "sagittal" && (currentAtlasWindow == "1" || currentAtlasWindow == "7"))
            {
                if (currentSagittalView == "annotation")
                {
                    currentAtlasWindow = "5";
                }
                else
                {
                    currentAtlasWindow = "6";
                }
            }
            if (CurrentOrientation == "coronal" && (currentAtlasWindow == "5" || currentAtlasWindow == "6"))
            {
                if (currentCoronalView == "annotation")
        {
            currentAtlasWindow = "1";
        }
        else
        {
            currentAtlasWindow = "7";
                }
            }
            }
            //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
            writeLog("onTableCellClick() calls getAtlasIndex('" + correspondingAtlasFile + "', '" + CurrentOrientation + "')");
            //**********************************************************
            var sErrMsg = "\n\n";
                if (CurrentOrientation == "sagittal" && (currentAtlasWindow == "1" || currentAtlasWindow == "7"))
                {
                    sErrMsg += "Sagittal sets should be syncing on window 5 or 6\n";
                }
                if (CurrentOrientation == "coronal" && (currentAtlasWindow == "5" || currentAtlasWindow == "6"))
                {
                    sErrMsg += "Coronal sets should be syncing on window 1 or 7\n";
                }
            //**********************************************************
            correspondingAtlasNumber = getAtlasIndex(correspondingAtlasFile, CurrentOrientation);
        }
        catch(e)
        {
            where = "k2";
            writeLog("ERROR onTableCellClick() getting raIndex: " + e.message);
            //alert("ERROR getting raIndex\n" + e.message);
        }
        where = "k3";
        correspondingAtlasNumber = parseInt(correspondingAtlasNumber);
        if (correspondingAtlasNumber < 0)
        {
            correspondingAtlasNumber = 0;
        }
        where = "k5\ncorrespondingAtlasNumber: " + correspondingAtlasNumber;
        
        var oIframe = document.getElementById("iframe" + currentAtlasWindow);
        var oDoc = (oIframe.contentWindow || oIframe.contentDocument);
        try
        {
            if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
        }
            catch(e){}
        var atlasTable = oDoc.getElementById("OverallTableA");
        try
        {
            where = "k5c";
            var aCells = atlasTable.getElementsByTagName("tr")[0].getElementsByTagName("td");
            var aCellArray = new Array();
            //OK, since getElementsByTagName return all matching descendants, I am getting TR tags from nested tables.
            //This should retain only direct children, and remove 
            //getElementsByTagName doesn't actually return an array. It returns an HTMLCollection. I need an array so I can filter out nested children. 
            for (k = 0; k < aCells.length; ++k)
            {
            where = "k5d";
            if (aCells[k].parentNode.parentNode.parentNode.id == "OverallTableA")
            {
                where = "k5e";
                try
                {
                aCellArray.push(aCells[k]);
                }
                catch(e)
                {
		    writeLog("ERROR during array manip.\nk = " + k + "\n" + e.message);
                //alert("ERROR during array manip.\nk = " + k + "\n" + e.message);
                }
            }
            }
            where = "k5f";
            if (correspondingAtlasNumber >= aCellArray.length)
            {
            where = "k5g";
            writeLog("HMMM, onTableCellClick() correspondingAtlasNumber >= aCellArray.length, set to 0");
            //SOMETIMES I ask for an index (a specific atlas image) that does not exist. this is bad. 
            correspondingAtlasNumber = 0;
            }
            if (aCellArray.length == 0)
            {
                writeLog("HMMM, onTableCellClick() no match found; stays 0.");
            }
            writeLog("=== onTableCellClick() aCellArray.length = " + aCellArray.length + " ===");
            writeLog("=== onTableCellClick() syncs with index " + correspondingAtlasNumber + " ===");
            where = "k5h";
            var atlasCell = aCellArray[correspondingAtlasNumber].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
        }
        catch(e)
        {
            writeLog("ERROR onTableCellClick() traversing table: " + e.message + " where=" + where + " correspondingAtlasNumber=" + correspondingAtlasNumber);
            //alert("ERROR traversing table:\n" + e.message + "\nwhere: " + where + "\ncorrespondingAtlasNumber: " + correspondingAtlasNumber);
            return;
        }

        where = "k6";
        //then I need to pass this cell object into this function(?) without causing a loop. 
        //only turn off the "focus" now as the atlas gets synced. It resets itself to true...
        where = "m";
        try 
        {
            //the SYNC will not happen if we did not get to a node that has an ID. 
            //So, if you are wondering why the sync does not work, look at how we drilled to the atlasCell.
            //******************************************
            //SYNC ATLAS 
            eval("selectedCell" + currentAtlasWindow + ".style.border='3px solid #cccccc'");
            where = "m1";
            atlasCell.style.border = "3px solid #000000";
            where = "m2";
            eval("selectedCell" + currentAtlasWindow + " = atlasCell");
            
            where = "m3";
            path = atlasCell.id;
                where = "m3a";
            var xpath = atlasCell.getAttribute("XMaskPath");
            if (xpath == "")
            {
                xpath = "//notThere.pff"; //just a dummy path that leads nowhere to turn off the button.
            }
            //=============================
            //path and xpath can both be set to "ImageNotAvailable" if the db says so.
            if (correspondingAtlasFile.indexOf("ImageNotAvailable") > -1)
            {
                path = correspondingAtlasFile;
                xpath = "//notThere.pff";
            }
            //=============================
            where = "m4";
            setName = atlasCell.getAttribute("imageSetName");
            where = "m6";
            fileName = "Allen+Reference+Atlas"; //atlasCell.getAttribute("imageName");
            where = "m7";
            tellFlashWindows("bAtlasSyncing", "true", "fileName", fileName, "setName", setName, "exPath", xpath, "zoomifyImagePath", path, c5,  p, "", "", "",  "", "", "");
            where = "m8";
            //******************************************
        }
        catch(e)
        {
            //alert("SYNC ERROR:\n" + e.message);
            writeLog("ERROR onTableCellClick() sync error: " + e.message);
        }
        }
        //************************************************************************
        c7 = "DoneSetup"; //doing this effectively means "show all changes".
        c7v = "false";
        where = "n";
        //*****************************
        //HERE is code to compute the bar position...
        setBarPosition(currentCell);
        //*****************************
        //update the position text
        writeLog("onTableCellClick() calls startSlideShow()");
        startSlideshow(false, "", "", false); //really, this just updates the "2 of 15" text.
    }
    catch(e)
    {
        //usually, the error is that the selectedCell1.id does not exist yet. 
        alert("ERROR onTableCellClick()\n" + e.message + "\nWHERE: " + where);
        writeLog("ERROR onTableCellClick(): " + e.message + " WHERE=" + where);
        return;
    }
    //now that I have collected all of the variables, announce them all at once. 
    if (targetWindowNumber != "1")
    {
        tellSceneControl("", "", "",  "", "",  "", "",  "", c4, c4v, "",  "", "",  "", "",  "", "", "");
    }

    if (c2 == UNDEFINED) 
    {
        //there is a small chance that this stops some needed communication... 
        return;
    }
    else
    {
        //c2 and c2v are used to send in exPath and XMaskPath!
        if (!bSyncAtlas)
        {
            writeLog("TFW 2");
        tellFlashWindows(c8, c8v, c1, c1v, c2, c2v, c3, c3v, "exPath",  xpath, c5, c5v, c6, c6v, "",  "", c8, c8v);
        }
        else
        {
        //also sending in the path/set/file for the atlas...
        tellFlashWindows("exPath", xpath, c1, c1v, c2, c2v, c3, c3v, "fileName",  fileName, c5, c5v, c6, c6v, "setName",  setName, "zoomifyImagePath", path);
        }
    }
}
function syncWith(oCell)
{
    writeLog("syncWith()");
    //we need to sync the atlas with this cell. This can be called from anywhere and the sync will happen.
    //if (document.getElementById("cbAllowSync").checked != true) return; //this allows the users to uncheck a box and stop the sync.
    var correspondingAtlasNumber = 0;
    var where = "0";
    if (!oCell)
    {
        where = "0a";
        writeLog("!! syncWith() finds no cell !!");
        return;
    }
    try
    {
        where = "1";
        correspondingAtlasFile = oCell.getAttribute("raFile");
        var p = eval("Orientation" + currentFocusedWindow);
        //OK, now that I have the file name, get the corresponding atlas index...
        writeLog("syncWith() calls getAtlasIndex()");
        correspondingAtlasNumber = getAtlasIndex(correspondingAtlasFile, p);
    }
    catch(e)
    {
        where = "2";
        writeLog("ERROR syncWith(): " + e.message);
        //alert("ERROR get raIndex\n" + e.message);
    }
    where = "3";
    correspondingAtlasNumber = parseInt(correspondingAtlasNumber);
    if (correspondingAtlasNumber < 0)
    {
        correspondingAtlasNumber = 0;
    }
    where = "4\ncorrespondingAtlasNumber: " + correspondingAtlasNumber;

    var oIframe = document.getElementById("iframe" + currentAtlasWindow);
    var oDoc = (oIframe.contentWindow || oIframe.contentDocument);
    try
    {
        if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
    }
    catch(e){}
    var atlasTable = oDoc.getElementById("OverallTableA");
    try
    {
        where = "5";
        var aCells = atlasTable.getElementsByTagName("tr")[0].getElementsByTagName("td");
        var aCellArray = new Array();
        //OK, since getElementsByTagName return all matching descendants, I am getting TR tags from nested tables.
        //This should retain only direct children, and remove "text" nodes and other weirdness from the DOM.
        //  (getElementsByTagName doesn't actually return an array. It returns an HTMLCollection. I need an array so I can filter out nested children.)
        for (k = 0; k < aCells.length; ++k)
        {
        where = "6";
        if (aCells[k].parentNode.parentNode.parentNode.id == "OverallTableA")
        {
            where = "7";
            try
            {
            aCellArray.push(aCells[k]);
            }
            catch(e)
            {
            writeLog("ERROR during array creation. k=" + k + " " + e.message);
            //alert("ERROR during array creation.\nk = " + k + "\n" + e.message);
            }
        }
        }
        where = "8";
        if (correspondingAtlasNumber >= aCellArray.length)
        {
        where = "9";
        //SOMETIMES I ask for an index (a specific atlas image) that does not exist. this is bad. Just set it to use the first image.
        correspondingAtlasNumber = 0;
        }
        where = "10";
        var atlasCell = aCellArray[correspondingAtlasNumber].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
    }
    catch(e)
    {
        writeLog("ERROR dancing table: " + e.message + " where=" + where + " correspondingAtlasNumber=" + correspondingAtlasNumber);
        //alert("ERROR dancing table:\n" + e.message + "\nwhere: " + where + "\ncorrespondingAtlasNumber: " + correspondingAtlasNumber);
        return;
    }
    where = "11";
    try 
    {
        //the SYNC will not happen if we did not get to a node that has an ID. 
        //So, if you are wondering why the sync does not work, look at how we drilled to the atlasCell.
        //******************************************
        //SYNC ATLAS 
        eval("selectedCell" + currentAtlasWindow + ".style.border='3px solid #cccccc'");
        where = "12";
        atlasCell.style.border = "3px solid #000000";
        where = "13";
        eval("selectedCell" + currentAtlasWindow + "=atlasCell");
        where = "14";
        path = atlasCell.id;
        where = "15";
        setName = atlasCell.getAttribute("imageSetName");
            where = "16";
        var xpath = atlasCell.getAttribute("XMaskPath");
        if (xpath == "")
        {
        xpath = "//notThere.pff"; //just a dummy path that leads nowhere to turn off the button.
        }
        where = "17";
        fileName = "Allen+Reference+Atlas"; //atlasCell.getAttribute("imageName");
        where = "18";
        tellFlashWindows("bAtlasSyncing", "true", "fileName", fileName, "setName", setName, "exPath",  xpath, "zoomifyImagePath", path, "", "", "", "", "",  "", "", "");
        where = "m8";
        //******************************************
    }
    catch(e)
    {
        writeLog("ERROR syncWith(): where=" + where + ": " + e.message);
        //alert("ERROR syncWith():\nwhere: " + where + "\n" + e.message);
    }
}
function setBarPosition(oCell)
{
    //given a particular cell, get the information from it to set the bar position:
    imagePositionInteger = getBarPositionNumber(oCell);
    writeLog("setBarPosition() imagePositionInteger: " + imagePositionInteger.toString());
    setValue(imagePositionInteger); //eventually does a tellImageControl()
}

function getBarPositionNumber(oCell)
{
    var imagePositionInteger = 0;
    if (CurrentOrientation == "sagittal")
    {
        //Sagittal range is 35 to 85 (so it is 50 wide, and I need to add 35 to it).
        var iMaxPos = 8400; //originally 10000 but the range is 0 - 4200, and it can only go halfway.
        imagePositionInteger = parseInt(oCell.getAttribute("imagePos"));
        if (imagePositionInteger > iMaxPos)
        {
        imagePositionInteger = iMaxPos;
        }
        //the range I receive is 0 to iMaxPos, and it needs to get to the range 0 to 50
        imagePositionInteger = imagePositionInteger/iMaxPos*100;
        imagePositionInteger = parseInt(imagePositionInteger*50/100);
        imagePositionInteger += 35;
        if (imagePositionInteger > 85)
        {
        imagePositionInteger = 85;
        }
        if (imagePositionInteger < 35)
        {
        imagePositionInteger = 35;
        }
    }
    else
    {
        //Coronal range is 19 to 109 (so it is 90 wide, and I need to add 19 to it).
        correspondingAtlasFile = oCell.getAttribute("raFile");
        var p = eval("Orientation" + currentFocusedWindow);
        //OK, now that I have the file name, get the corresponding atlas index...
        writeLog("getBarPositionNumber() calls getAtlasIndex()");
        imagePositionInteger = getAtlasIndex(correspondingAtlasFile, p);
        //********* NOTE ***********
        //This uses a dynamic set length (iCoronalSetLength) for the Atlas, and does not rely on it staying at 132.
        //**************************
        //the range I receive is 0 to [iCoronalSetLength], and it needs to get to the range 0 to 90 (the pixels in the image)
        imagePositionInteger = imagePositionInteger/iCoronalSetLength*100;
        imagePositionInteger = parseInt(imagePositionInteger*90/100);
        imagePositionInteger += 12;
        if (imagePositionInteger > 102)
        {
        imagePositionInteger = 102;
        }
        if (imagePositionInteger < 12)
        {
        imagePositionInteger = 12;
        }
    }
    if (isNaN(imagePositionInteger))
    {
        imagePositionInteger = 0;
    }
    return parseInt(imagePositionInteger);
}
//the "setValue" function sets a number from 0 through 130 that refers to the center of the vertical bar.
function setValue(newValue)
{
    //TODO: I should update the "2 of 15" text now, too. 
    //----------------------
        var framei = currentFocusedWindow;
        if (framei == "1")
        {
        //we need to make sure we show the right atlas window (only coronal should stay at 1)
        //check to see what the atlas state is, and change this accordingly.
        if (CurrentOrientation == "sagittal")
        {
            if (currentSagittalView == "annotation")
            {
                //annotation view
                framei = "5";
            }
            else
            {
                //nssl view
                framei = "6";
            }
        }
        else
        {
            if (currentCoronalView == "annotation")
            {
                //annotation view
                framei = "1";
            }
            else
            {
                //nssl view
                framei = "7";
            }
        }
        }
    //----------------------
    try
    {
        var p = eval("Orientation" + framei);
        CurrentOrientation = p;
        //My Flash object uses this number for the center of the bar. 
        tellImageControl("Orientation", p, "InitialPosition", newValue, "", "", "DoneSetup", "false", "", "", "", "", "", "", "", "", "", ""); //doing DoneSetup-false effectively means "show all changes".
    }
    catch(e)
    {
        writeLog("ERROR setValue('" + newValue + "'): " + e.message);
        //alert("ERROR setValue('" + newValue + "')\n" + e.message);
    }
}
function checkStarted()
{
    //I want to set a timeout that will see that we have already run the startPage() function.
    //I need to do this because very often, the ONLOAD event from the body does not fire! 
    setTimeout("startPage()", 2000);
}
var bStarted = false;
function startPage()
{
    var i = 0;
    try 
    {
        i = 1;
        if (bStarted) return;
        bStarted = true;
        
        browserName = navigator.appName;
        i = 2;
        //alert("You are using " + browserName); //The Safari browsers reports itself as "Netscape"
        InternetExplorer = browserName.indexOf("Microsoft") != -1;
        //get the Log ready
        try
        {
        if (!logInitialized) initLog(); //found in logger.js
        }
        catch(e)
        {
        writeLog("ERROR startPage() initLog(): " + e.message);
        }
        i = 3;
        writeLog("startPage() you are using " + browserName);
        //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        //I should make sure that the iframes have all resolved correctly.
        var passed = true;
        i = 301;
        vIframe = document.getElementById("iframe1");
        i = 3010;
        vDoc = (vIframe.contentWindow || vIframe.contentDocument);
        i = 302;
        try
        {
            if (vDoc.document) vDoc = vDoc.document; //some browsers are weird.
        }
        catch(e){}
        i = 3020; //if Safari errors here, it's because the thumbnail frames have not loaded yet. 
        if (!vDoc || !vDoc.documentElement)
        {i = 3021;
        writeLog("$$ startPage() missing iframe 1");
        passed = false;
        }
        else
        {i = 3022;
        writeLog("$$ startPage() found iframe 1");
        //I have the idea that I should also test for the element "divComplete", to be sure that the iframe has loaded. 
        if (!vDoc.getElementById("divComplete"))
        {
            //the count will be off if the page has not loaded yet.
            writeLog("$$ iframe 1 is not complete");
            passed = false;
        }
        }
        i = 305;
        vIframe = document.getElementById("iframe2");
        i = 3050;
        vDoc = (vIframe.contentWindow || vIframe.contentDocument);
        i = 306;
        try
        {
            if (vDoc.document) vDoc = vDoc.document; //some browsers are weird.
        }
        catch(e){}
        i = 3060;
        if (!vDoc || !vDoc.documentElement)
        {i = 3061;
        writeLog("$$ startPage() missing iframe 2");
        passed = false;
        }
        else
        {i = 3062;
        writeLog("$$ startPage() found iframe 2");
        if (!vDoc.getElementById("divComplete"))
        {
            //the count will be off if the page has not loaded yet.
            writeLog("$$ iframe 2 is not complete");
            passed = false;
        }
        }
        i = 309;
        vIframe = document.getElementById("iframe3");
        i = 3090;
        vDoc = (vIframe.contentWindow || vIframe.contentDocument);
        i = 310;
        try
        {
            if (vDoc.document) vDoc = vDoc.document; //some browsers are weird.
        }
        catch(e){}
        i = 3100;
        if (!vDoc || !vDoc.documentElement)
        {i = 3101;
        writeLog("$$ startPage() missing iframe 3");
        passed = false;
        }
        else
        {i = 3102;
        writeLog("$$ startPage() found iframe 3");
        if (!vDoc.getElementById("divComplete"))
        {
            //the count will be off if the page has not loaded yet.
            writeLog("$$ iframe 3 is not complete");
            passed = false;
        }
        }
        i = 313;
        vIframe = document.getElementById("iframe4");
        i = 3130;
        vDoc = (vIframe.contentWindow || vIframe.contentDocument);
        i = 314;
        try
        {
            if (vDoc.document) vDoc = vDoc.document; //some browsers are weird.
        }
        catch(e){}
        i = 3140;
        if (!vDoc || !vDoc.documentElement)
        {i = 3141;
        writeLog("$$ startPage() missing iframe 4");
        passed = false;
        }
        else
        {i = 3142;
        writeLog("$$ startPage() found iframe 4");
        if (!vDoc.getElementById("divComplete"))
        {
            //the count will be off if the page has not loaded yet.
            writeLog("$$ iframe 4 is not complete");
            passed = false;
        }
        }
        i = 317;
        vIframe = document.getElementById("iframe5");
        vDoc = (vIframe.contentWindow || vIframe.contentDocument);
        i = 318;
        try
        {
            if (vDoc.document) vDoc = vDoc.document; //some browsers are weird.
        }
        catch(e){}
        i = 3180;
        if (!vDoc || !vDoc.documentElement)
        {i = 3181;
        writeLog("$$ startPage() missing iframe 5");
        passed = false;
        }
        else
        {i = 3182;
        writeLog("$$ startPage() found iframe 5");
        if (!vDoc.getElementById("divComplete"))
        {
            //the count will be off if the page has not loaded yet.
            writeLog("$$ iframe 5 is not complete");
            passed = false;
        }
        }
        i = 321;
        vIframe = document.getElementById("iframe6");
        vDoc = (vIframe.contentWindow || vIframe.contentDocument);
        i = 322;
        try
        {
            if (vDoc.document) vDoc = vDoc.document; //some browsers are weird.
        }
        catch(e){}
        i = 3220;
        if (!vDoc || !vDoc.documentElement)
        {i = 3221;
        writeLog("$$ startPage() missing iframe 6");
        passed = false;
        }
        else
        {i = 3222;
        writeLog("$$ startPage() found iframe 6");
        if (!vDoc.getElementById("divComplete"))
        {
            //the count will be off if the page has not loaded yet.
            writeLog("$$ iframe 6 is not complete");
            passed = false;
        }
        }
        i = 325;
        vIframe = document.getElementById("iframe7");
        vDoc = (vIframe.contentWindow || vIframe.contentDocument);
        i = 700;
        try
        {
            if (vDoc.document) vDoc = vDoc.document; //some browsers are weird.
        }
        catch(e){}
        i = 701;
        if (!vDoc || !vDoc.documentElement)
        {i = 702;
        writeLog("$$ startPage() missing iframe 7");
        passed = false;
        }
        else
        {i = 703;
        writeLog("$$ startPage() found iframe 7");
        if (!vDoc.getElementById("divComplete"))
        {
            //the count will be off if the page has not loaded yet.
            writeLog("$$ iframe 7 is not complete");
            passed = false;
        }
        }
        if (!passed)
        {
        bStarted = false;
        writeLog("startPage() detects missing iframes; start over. ");
        setTimeout("startPage()", 2000);
        return;
        }
        //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        //we no longer resize the thumbnails here; it is done in the thumbnailSet.jsp. 
        i = 8;
        var bShow1 = document.getElementById("layer1").getAttribute("show");
        i = 9;
        //**********************************************************************************
        //DANG! I can't do "getAttribute" on an iframe? 
        //Well, I need to figure out another way to get info about whether to show each set. 
        //**********************************************************************************
        var bShow2 = document.getElementById("layer2").getAttribute("show");
        i = 10;
        var bShow3 = document.getElementById("layer3").getAttribute("show");
        i = 11;
        var bShow4 = document.getElementById("layer4").getAttribute("show");
        i = 12;
            writeLog("startPage() Orientation2: " + Orientation2);
            if (Orientation2 == "sagittal")
            {
                currentAtlasWindow = "5";
                CurrentOrientation = "sagittal";
            }
        setInitialSelected();
        //I have to select the first "non-atlas" set (the green window) as the default set, so I am adding the "focus", "2" command here as well. 
        //KSB 12/8/2004: removed ("focus","2") becuase I am trying to quiet the load, and start on 2. 
        tellSceneControl("label1", label1, "label2", label2, "label3", label3, "label4", label4, "show1", bShow1, "show2", bShow2, "show3", bShow3, "show4", bShow4, "", "");
        //then allow the WC to send focus commands
        i = 13;
        //get the "2 of 15" text to populate when the page loads
        startSlideshow(false, "", "", false); //really, this just updates the "2 of 15" text.
        //TODO: this next test may not work correctly if we are only passing one or two Gene sets to the viewer. 
        i = 14;
        if (label1 == "Gene 1" || label2 == "Gene 2" || label3 == "Gene 3")
        {
        bStarted = false;
        }
        fixImageSet("2"); //makes sure all the thumbnails appear in the newly chosen set.
        document.getElementById("divLoadingMsg").style.visibility = "hidden";
        //move the flash elements into place:
        document.getElementById("layerZoom").style.left = -4;
        document.getElementById("ReferenceImage").style.left = 244;
        document.getElementById("sceneControl").style.left = -1;
        document.getElementById("cbAllowSync").disabled = false;
        if (!bIsAtlasOnly) //if we are not "Atlas Only", show the second thumbnail set
        {
            document.getElementById("iframe2").style.left = 365;
        }
        else
        {
            //TODO: test here to see if this is sagittal (or default coronal) plane SARA
            if (atlasSagByDefault)
            {
                document.getElementById("iframe5").style.left = 365;
            }
            else
            {
                document.getElementById("iframe1").style.left = 365;
            }
        }
        if (InternetExplorer == true) 
        {
            return;
        }
        writeLog("navigator.userAgent: " + navigator.userAgent.toString());
        if (navigator.userAgent.indexOf("Safari") != -1)
        {
            if (!bIsAtlasOnly) //if we are not "Atlas Only", show the second thumbnail set
            {
                //move iframe1 so the tooltips don't show through.
                document.getElementById("iframe1").style.left = -1100; //only do this if we are not looking at the "Atlas Only" IVT (the second subwindow is visible).
            }
        //then, lastly, I want to make sure that Safari hasn't started up more than one IVT. 
        // To do this, I set a timer here to check to make sure the ImageControl object sends in confirmation that 
        // the LocalConnection is working correctly. If it is not, ImageControl will not have sent in confirmation
        // and we should notify the user that this IVT will not function correctly.
        writeLog("We will check the LC soon...");
        //send in a request for confirmation
        window.setTimeout('tellImageControl("LC", "check", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "")', 2000);
        window.setTimeout("verifyLC()", 7000);
        }
    }
    catch(e)
    {
        bStarted = false;
        writeLog("ERROR startPage() at " + i + ": " + e.message);
        //alert("ERROR in startPage() at " + i + ":\n" + e.message)
    }
}

function tellFlashWindows(variableName, message, c1, c1v, c2, c2v, c3, c3v, c4, c4v, c5, c5v, c6, c6v, c7, c7v, c8, c8v)
{
    writeLog("tellFlashWindows(" + variableName + ", " + message + ", " + c1 + ", " + c1v + ", " + c2 + ", " + c2v + ", " + c3 + ", " + c3v + ", " + c4 + ", " + c4v + ", " + c5 + ", " + c5v + ", " + c6 + ", " + c6v + ", " + c7 + ", " + c7v + ", " + c8 + ", " + c8v + ")");
    writeLog("tellFlashWindows() calls doSetVariable()");
    doSetVariable("3", variableName, message, c1, c1v, c2, c2v, c3, c3v, c4, c4v, c5, c5v, c6, c6v, c7, c7v, c8, c8v);
    //focusOnWindows();
}
function tellSceneControl(variableName, message, c1, c1v, c2, c2v, c3, c3v, c4, c4v, c5, c5v, c6, c6v, c7, c7v, c8, c8v)
{
    writeLog("tellSceneControl(" + variableName + ", " + message + ", " + c1 + ", " + c1v + ", " + c2 + ", " + c2v + ", " + c3 + ", " + c3v + ", " + c4 + ", " + c4v + ", " + c5 + ", " + c5v + ", " + c6 + ", " + c6v + ", " + c7 + ", " + c7v + ", " + c8 + ", " + c8v + ")");
    try
    {
        writeLog("tellSceneControl() calls doSetVariable()");
        doSetVariable("1", variableName, message, c1, c1v, c2, c2v, c3, c3v, c4, c4v, c5, c5v, c6, c6v, c7, c7v, c8, c8v);
    }
    catch(e)
    {
        writeLog("ERROR tellSceneControl(): " + e.message);
        //alert("ERROR in tellSceneControl:\n" + e.message);
    }
}
function tellImageControl(variableName, message, c1, c1v, c2, c2v, c3, c3v, c4, c4v, c5, c5v, c6, c6v, c7, c7v, c8, c8v)
{
    writeLog("tellImageControl(" + variableName + ", " + message + ", " + c1 + ", " + c1v + ", " + c2 + ", " + c2v + ", " + c3 + ", " + c3v + ", " + c4 + ", " + c4v + ", " + c5 + ", " + c5v + ", " + c6 + ", " + c6v + ", " + c7 + ", " + c7v + ", " + c8 + ", " + c8v + ")");
    writeLog("tellImageControl() calls doSetVariable()");
    doSetVariable("2", variableName, message, c1, c1v, c2, c2v, c3, c3v, c4, c4v, c5, c5v, c6, c6v, c7, c7v, c8, c8v);
}
function focusOnWindows() 
{
    //put the focus on the windows object so it gets keyboard commands. 
    try
    {
        //frames.flashFrame.document.WindowComponent.setActive(); //this is better than "focus()" method because it doesn't scroll to the bottom of the page.
    }
    catch(e)
    {
        //it's OK if the actual focus doesn't return to the windows object, really. 
    }
}
var hashCoronalIndex = new Array();
var bDoneCoronalHash = false;
var hashSagittalIndex = new Array();
var bDoneSagittalHash = false;
function getAtlasIndex(AtlasFileName, plane)
{

    writeLog("getAtlasIndex()");
    //I need to do this separately for coronal and sagittal! 
    switch(plane)
    {
        case "coronal":
            writeLog("getAtlasIndex() goes coronal");
            //should return an integer index that is its index number in the list of thumbnails.
            var iIndex = 0;
            //unfortunately, it is just the file name. 
            //I loop through the list once and make a hash table, then always check to see that the hash exists so i don't do it again. 
            writeLog("getAtlasIndex() bDoneCoronalHash: " + bDoneCoronalHash);
            if (!bDoneCoronalHash)
            {
                writeLog("getAtlasIndex() has not done coronal hash yet.");
                //loop through the ATLAS list and populate the array
                var oIframe = document.getElementById("iframe1");
                var oDoc = (oIframe.contentWindow || oIframe.contentDocument);
                try
                {
                    if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
                }
                    catch(e){}
                var atlasTable = oDoc.getElementById("OverallTableA");
                var indexCounter = 0;
                try
                {
                var aCells = atlasTable.getElementsByTagName("tr")[0].getElementsByTagName("td");
                writeLog("getAtlasIndex() 1 aCells.length: " + aCells.length);
                var aCellArray = new Array();
                //OK, since getElementsByTagName return all matching descendants, I am getting TR tags from nested tables.
                //This should retain only direct children, and remove excess nested elements.
                //getElementsByTagName doesn't actually return an array. It returns an HTMLCollection. I need an array so I can filter out nested children. 
                for (k = 0; k < aCells.length; ++k)
                {
                    if (aCells[k].getAttribute("raFile") != UNDEFINED)
                    {
                    try
                    {
                        writeLog(">>> " + aCells[k].getAttribute("raFile").toLowerCase());
                        hashCoronalIndex[aCells[k].getAttribute("raFile").toLowerCase()] = indexCounter;
                        ++indexCounter;
                    }
                    catch(e)
                    {
			writeLog("ERROR setting coronal hash.\n" + e.message);
                        //alert("ERROR setting coronal hash.\n" + e.message);
                    }
                    }
                }
                iCoronalSetLength = indexCounter;
                bDoneCoronalHash = true;
                }
                catch(e)
                {
                writeLog("ERROR getAtlasIndex(): " + e.message);
                //alert("ERROR getAtlasIndex():\n" + e.message);
                bDoneCoronalHash = false;
                return 0;
                }
            }
            else
            {
                writeLog("getAtlasIndex() bDoneCoronalHash, so skipped");
            }
            
            try
            {
                iIndex = hashCoronalIndex[AtlasFileName.toLowerCase()];
                writeLog("getAtlasIndex() iIndex: " + iIndex);
            }
            catch(e)
            {
                writeLog("ERROR getAtlasIndex() setting index: " + e.message);
                //alert("ERROR getAtlasIndex() setting index:\n" + e.message);
                return 0;
            }

        break;
        
        case "sagittal":
            //should return an integer index that is its index number in the list of thumbnails.
            writeLog("getAtlasIndex() goes sagittal");
            var iIndex = 0;
            //unfortunately, it is just the file name. 
            //I loop through the list once and make a hash table, then always check to see that the hash exists so i don't do it again. 
            writeLog("getAtlasIndex() bDoneSagittalHash: " + bDoneSagittalHash);
            if (!bDoneSagittalHash)
            {
                //loop through the ATLAS list and populate the array
                var oIframe = document.getElementById("iframe5");
                var oDoc = (oIframe.contentWindow || oIframe.contentDocument);
                try
                {
                    if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
                }
                    catch(e){}
                var atlasTable = oDoc.getElementById("OverallTableA");
                var indexCounter = 0;
                try
                {
                var aCells = atlasTable.getElementsByTagName("tr")[0].getElementsByTagName("td");
                writeLog("getAtlasIndex() 3 aCells.length: " + aCells.length);
                var aCellArray = new Array();
                //OK, since getElementsByTagName return all matching descendants, I am getting TR tags from nested tables.
                //This should retain only direct children, and remove excess nested elements.
                //getElementsByTagName doesn't actually return an array. It returns an HTMLCollection. I need an array so I can filter out nested children. 
                for (k = 0; k < aCells.length; ++k)
                {
                    //if (aCells[k].parentNode.parentNode.parentNode.id == "OverallTableA")
                    if (aCells[k].getAttribute("raFile") != UNDEFINED)
                    {
                    try
                    {
                        hashSagittalIndex[aCells[k].getAttribute("raFile").toLowerCase()] = indexCounter;
                        writeLog("...index " + indexCounter + ": " + aCells[k].getAttribute("raFile").toLowerCase());
                        ++indexCounter;
                    }
                    catch(e)
                    {
			writeLog("ERROR setting Sagittal hash.\n" + e.message);
                        //alert("ERROR setting Sagittal hash.\n" + e.message);
                    }
                    }
                }
                iSagittalSetLength = indexCounter;
                bDoneSagittalHash = true;
                }
                catch(e)
                {
                writeLog("ERROR getAtlasIndex() Sagittal: " + e.message);
                //alert("ERROR getAtlasIndex() Sagittal:\n" + e.message);
                bDoneSagittalHash = false;
                return 0;
                }
            }
            try
            {
                iIndex = hashSagittalIndex[AtlasFileName.toLowerCase()];
                writeLog("matching raFile: " + AtlasFileName.toLowerCase() + " at " + iIndex);
            }
            catch(e)
            {
                writeLog("ERROR getAtlasIndex() Sagittal setting index: " + e.message);
                //alert("ERROR getAtlasIndex() Sagittal setting index:\n" + e.message);
                return 0;
            }
        break;
    }
    if (iIndex == UNDEFINED)
    {
        writeLog("*** getAtlasIndex(): iIndex == UNDEFINED; set to 0");
        writeLog("*** WE TRIED to match this value: ");
        writeLog("*** " + AtlasFileName.toLowerCase());
        writeLog("*** TO ONE of these values: ");
        if (plane == "sagittal")
        {
            for (var x in hashSagittalIndex)
            {
                //
                writeLog("*** " + x);
            }
        }
        else
        {
            for (var x in hashCoronalIndex)
        {
            //
            writeLog("*** " + x);
            }
        }
        iIndex = 0;
    }
    return iIndex;
}

var lastAtlasSet = "1";
function changeColor(i)
{
    writeLog("changeColor(" + i + ")");
    /*if (i == currentFocusedWindow)
    {
        writeLog("changeColor() aborted; no need to change.");
        return;
    }*/
    currentFocusedWindow = i;
    switch(i)
    {
        case "1":
        case "5":
        case "6":
        case "7":
        document.getElementById("divImageSelectionStrip").style.backgroundColor = "#4F86A4";
        break;

        case "2":
        document.getElementById("divImageSelectionStrip").style.backgroundColor = "#047C6C";
        break;

        case "3":
        document.getElementById("divImageSelectionStrip").style.backgroundColor = "#A18963";
        break;

        case "4":
        document.getElementById("divImageSelectionStrip").style.backgroundColor = "#00507D";
        break;
    }
    var framei = i;
    
    //**************************************************
    //
    if (framei == "1" && document.getElementById("cbAllowSync").checked != true)
    {
        writeLog("changeColor() lastAtlasSet: " + lastAtlasSet);
        //we are switching to the atlas set and probably things are synced.
        switch(lastAtlasSet)
        {
            case "1":
                CurrentOrientation = "coronal"
                currentCoronalView = "annotation";
            break;
            
            case "5":
                CurrentOrientation = "sagittal";
                currentSagittalView = "annotation";
            break;
            
            case "6":
                CurrentOrientation = "sagittal";
                currentSagittalView = "nssl";
            break;
            
            case "7":
                CurrentOrientation = "coronal"
                currentCoronalView = "nssl";
            break;
        }
        currentAtlasWindow = lastAtlasSet;
    }
    //**************************************************
    
    if (framei == "1" || document.getElementById("cbAllowSync").checked == true)
    {
        lastAtlasSet = "1";
        //we need to make sure we show the right atlas window (only coronal should stay at 1)
        //check to see what the atlas state is, and change this accordingly.
        if (CurrentOrientation == "sagittal")
        {
            if (currentSagittalView == "annotation")
            {
                //annotation view
                if (framei == "1") framei = "5";
                lastAtlasSet = "5";
            }
            else
            {
                //nssl view
                if (framei == "1") framei = "6";
                lastAtlasSet = "6";
            }
        }
        else
        {
            if (currentCoronalView == "annotation")
            {
                //annotation view
                if (framei == "1") framei = "1";
                lastAtlasSet = "1";
            }
            else
            {
                //nssl view
                if (framei == "1") framei = "7";
                lastAtlasSet = "7";
            }
        }
    }
    var oLayer = eval("document.getElementById('iframe" + framei + "')");
    writeLog("changeColor() will show thumbnail set " + framei);
    //
    var oLayer2 = document.getElementById("iframe2");
    var oLayer3 = document.getElementById("iframe3");
    var oLayer4 = document.getElementById("iframe4");
    var oLayer5 = document.getElementById("iframe5");
    var oLayer6 = document.getElementById("iframe6");
    var oLayer7 = document.getElementById("iframe7");
    //
    if (oLayer2.id != oLayer.id)
    {
        oLayer2.style.left = -1100;
    }
    if (oLayer3.id != oLayer.id)
    {
        oLayer3.style.left = -1100;
    }
    if (oLayer4.id != oLayer.id)
    {
        oLayer4.style.left = -1100;
    }
    if (oLayer5.id != oLayer.id)
    {
        oLayer5.style.left = -1100;
    }
    if (oLayer6.id != oLayer.id)
    {
        oLayer6.style.left = -1100;
    }
    if (oLayer7.id != oLayer.id)
    {
        oLayer7.style.left = -1100;
    }
    if (document.getElementById("ReferenceImage").style.visibility == "hidden") //if the "Image selection" area has been minimized...
    {
        oLayer.style.left = -1100; //changes the position of the thumbnails
    }
    else
    {
        oLayer.style.left = 365; //changes the position of the thumbnails
    }
    fixImageSet(framei); //and make the thumbnails show (force it, even if they are already visible).
    //I also want to update the rotisserie, since it is not refecting the current orientation when the set changes. 
    //startSlideshow(false, "", "", false); //really, this just updates the "2 of 15" text.

    var bSync = true;
    if (i == "1" || i == "5" || i == "6" || i == "7") //means they just chose the atlas.
    {
        //do not sync the atlas if we are choosing the atlas.
        return;
    }
    //and do not sync if the checkbox is unchecked...
    if (document.getElementById("cbAllowSync").checked != true) //this allows the users to uncheck a box and stop the sync.
    {
        writeLog("changeColor() Sync not allowed.");
        return; 
    }
    //this should sync the atlas to the newly selected cell. 
    //OH, but i should only do this if it is a coronal image...
    var p = eval("Orientation" + i);
    //KSB 8/23/2005: added if here to prevent currentAtlasWindow from being set when box is unchecked.
    if (document.getElementById("cbAllowSync").checked == true)
    {
        if (p == "sagittal")
        {
            if (currentSagittalView == "annotation")
            {
                currentAtlasWindow = "5";
            }
            else
            {
                currentAtlasWindow = "6";
            }
        }
        if (p == "coronal")
        {
            if (currentCoronalView == "annotation")
            {
                currentAtlasWindow = "1";
            }
            else
            {
                currentAtlasWindow = "7";
            }
        }
    }
    var oCell = eval("selectedCell" + currentFocusedWindow);
    try
    {
        var where = "0";
        if (oCell.id != "")
        {
        var correspondingAtlasNumber = 0;
        try
        {
            where = "k1";
            //derive the index from the name of the slice. 
            correspondingAtlasFile = oCell.getAttribute("raFile");
            writeLog("changeColor() detects correspondingAtlasFile: " + correspondingAtlasFile);
            //OK, now that I have the file name, get the corresponding atlas index...
            writeLog("changeColor() calls getAtlasIndex('" + correspondingAtlasFile + "', '" + p + "')");
            correspondingAtlasNumber = getAtlasIndex(correspondingAtlasFile, p);
        }
        catch(e)
        {
            where = "k2";
            writeLog("ERROR changeColors() getting raIndex: " + e.message);
        }
        where = "k3";
        correspondingAtlasNumber = parseInt(correspondingAtlasNumber);
        if (correspondingAtlasNumber < 0)
        {
            correspondingAtlasNumber = 0;
        }
        
        writeLog("changeColor() looks at atlas number " + currentAtlasWindow);
        var oIframe = document.getElementById("iframe" + currentAtlasWindow);
        var oDoc = (oIframe.contentWindow || oIframe.contentDocument);
        try
        {
            if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
        }
            catch(e){}
        var atlasTable = oDoc.getElementById("OverallTableA");
        try
        {
            where = "k5c";
            var aCells = atlasTable.getElementsByTagName("tr")[0].getElementsByTagName("td");
            var aCellArray = new Array();
            //OK, since getElementsByTagName return all matching descendants, I am getting TR tags from nested tables.
            //This should retain only direct children, and remove 
            //getElementsByTagName doesn't actually return an array. It returns an HTMLCollection. I need an array so I can filter out nested children. 
            for (k = 0; k < aCells.length; ++k)
            {where = "k5d";
            if (aCells[k].parentNode.parentNode.parentNode.id == "OverallTableA")
            {where = "k5e";
                try
                {
                aCellArray.push(aCells[k]);
                }
                catch(e)
                {
	    	    writeLog("ERROR during array manip.\nk = " + k + "\n" + e.message);
                //alert("ERROR during array manip.\nk = " + k + "\n" + e.message);
                }
            }
            }
            where = "k5f";
            if (correspondingAtlasNumber >= aCellArray.length)
            {where = "k5g";
            correspondingAtlasNumber = 0;
            }
            where = "k5h";
            
            var atlasCell = aCellArray[correspondingAtlasNumber].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];
            writeLog("changeColor() picks atlas cell " + atlasCell.id);
        }
        catch(e)
        {
            writeLog("ERROR changeColors() walking table: " + e.message);
            //alert("ERROR walking table:\n" + e.message + "\nwhere: " + where + "\ncorrespondingAtlasNumber: " + correspondingAtlasNumber);
            return;
        }
        where = "m";
        writeLog("changeColor() tries getting path info");
        try 
        {
            //the SYNC will not happen if we did not get to a node that has an ID. 
            //So, if you are wondering why the sync does not work, look at how we drilled to the atlasCell.
            //******************************************
            //SYNC ATLAS 
            eval("selectedCell" + currentAtlasWindow + ".style.border='3px solid #cccccc'");
            where = "m1";
            atlasCell.style.border = "3px solid #000000";
            where = "m2";
            eval("selectedCell" + currentAtlasWindow + "=atlasCell"); //testing to see if we switch colors if the atlas will sync
            where = "m3";
            path = atlasCell.id;
            where = "m4";
            var xpath = atlasCell.getAttribute("XMaskPath");
            if (xpath == "")
            {
            xpath = "//notThere.pff"; //just a dummy path that leads nowhere to turn off the button.
            }
            where = "m5";
            setName = atlasCell.getAttribute("imageSetName");
            where = "m6";
            fileName = "Allen+Reference+Atlas";
            where = "m7";
            writeLog("changeColor() calls tellFlashWindows");
            var thisO = "Orientation";
            if (document.getElementById("cbAllowSync").checked == false) thisO = "";
            //IF, when you change sets, and the atlas doesn't sync, it's probably because this next line never actually gets executed.
            tellFlashWindows("bAtlasSyncing", "true", "fileName", fileName, "setName", setName, "exPath",  xpath, "zoomifyImagePath", unescape(path), thisO, p, "", "", "",  "", "", "");
            where = "m8";
            writeLog("changeColor() done tellFlashWindows");
            //******************************************
        }
        catch(e)
        {
            writeLog("ERROR changeColors(): " + e.message);
        }
        }
    }
    catch(e)
    {
        writeLog("ERROR changeColors(), sync: " + e.message);
        //alert("ERROR changeColors(), sync:\n" + e.message);
    }
    writeLog("changeColor() finished.");
}
function minimizeImageSelection()
{
    writeLog("minimizeImageSelection()");
    //this hides the middle row, and moves the "windows" flash object up. 
    var oReference = document.getElementById("ReferenceImage");
    if (oReference.style.visibility == "hidden") //this determines if we are already "minimized" or not.
    {
        maximizeImageSelection();
        return;
    }
    for (f = 1; f < 7; ++f)
    {
        document.getElementById("iframe" + f).style.left = -1100; //move all thumbnail panes, so they don't invisibly obscure the subwindows.
    }
    var oScene = document.getElementById("sceneControl");
    var oWindows = document.getElementById("layerZoom");
    var oImg = document.getElementById("imgMax");
    var oImg2 = document.getElementById("imgMin");
    oReference.style.visibility = "hidden";
    oScene.style.visibility = "hidden";
    oWindows.style.top = 69;
    oImg.style.visibility = "visible";
    oImg2.style.visibility = "hidden";
    //focusOnWindows(); //puts focus on the windows
}
function maximizeImageSelection()
{
    writeLog("maximizeImageSelection()");
    //this reveals the middle row, and moves the "windows" flash object down. 
    var oLayer = document.getElementById("iframe" + currentFocusedWindow);
        oLayer.style.left = 365; //changes the position of the thumbnails
    var oReference = document.getElementById("ReferenceImage");
    var oScene = document.getElementById("sceneControl");
    var oWindows = document.getElementById("layerZoom");
    var oImg = document.getElementById("imgMax");
    var oImg2 = document.getElementById("imgMin");
    oReference.style.visibility = "visible";
    oScene.style.visibility = "visible";
    oWindows.style.top = 200;
    oImg.style.visibility = "hidden";
    oImg2.style.visibility = "visible";
    //focusOnWindows(); //puts focus on the windows
}
function dockWindows(minOrMax)
{
    //This should send the message to the Flash Windows object to organize the windows. 
    writeLog("dockWindows(" + minOrMax + ")");
    switch(minOrMax)
    {
        case "min":
        tellFlashWindows("dock", "min", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "");
        break;

        case "max":
        tellFlashWindows("dock", "max", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "");
        break;
    }
}
var timerSlideshow;
function startSlideshow(bContinue, sDirection, sJumpTo, bReload)
{
    writeLog("startSlideshow(" + bContinue + ", " + sDirection + ", " + sJumpTo + ", " + bReload + ")");
    var i = 0;
    try 
    {
    var iIndex = 0;
    var thumbLength = 0;
    i = 1;
    //----------------------
        var framei = currentFocusedWindow;
        if (framei == "1")
        {
        //we need to make sure we show the right atlas window (only coronal should stay at 1)
        //check to see what the atlas state is, and change this accordingly.
        if (CurrentOrientation == "sagittal")
        {
            if (currentSagittalView == "annotation")
            {
            //annotation view
            framei = "5";
            }
            else
            {
            //nssl view
            framei = "6";
            }
        }
        else
        {
            if (currentCoronalView == "annotation")
            {
            //annotation view
            framei = "1";
            }
            else
            {
            //nssl view
            framei = "7";
            }
        }
        }
    //----------------------
    //***********************************************************************
    var oIframe = document.getElementById("iframe" + framei);
    var oDoc = (oIframe.contentWindow || oIframe.contentDocument);
    try
    {
        if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
    }
    catch(e){}
    oTable = oDoc.getElementById("OverallTableA");
    //***********************************************************************
    var cTD = oTable.getElementsByTagName("tr")[0].getElementsByTagName("td");
    //strip out the nested children. 
    var aCellArray = new Array();
    //OK, since getElementsByTagName return all matching descendants, I am getting TR tags from nested tables.
    //This should retain only direct children, and remove nested ones.
    //getElementsByTagName doesn't actually return an array. It returns an HTMLCollection. I need an array so I can filter out nested children. 
    for (k = 0; k < cTD.length; ++k)
    {
        if (cTD[k].parentNode.parentNode.parentNode.id.substring(0, 12) == "OverallTable")
        {
        try
        {
            aCellArray.push(cTD[k]);
        }
        catch(e)
        {
            writeLog("ERROR startSlideshow() filtering array: " + e.message);
            //alert("ERROR filtering array.\nk = " + k + "\n" + e.message);
        }
        }
    }

    i = 2;
    thumbLength = aCellArray.length;

    i = 5;
    //Now figure out which index we at currently at...
    for (x = 0; x < thumbLength; ++x)
    {
        i = 6;
        try
        {
            //I think the problem is here: using currentFocusedWindow will never do 5 or 6. 
            //instead of currentFocusedWindow, use framei?
        if (aCellArray[x].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0].id == eval("selectedCell" + framei + ".id"))
        {
            //this is the current cell
            iIndex = x;
            break;
        }
        }
        catch(e)
        {
        i = 9;
        writeLog("ERROR startSlideshow() in loop: " + e.message);
        //when this errors, it's usually because the page has not loaded yet. It can assume the index is 0. 
        }
    }
    i = 12;
    //if we made it this far, we can advance to the next one
    if (sDirection == "forward")
    {i = 13;
        if ((iIndex+1) >= thumbLength)
        {
        iIndex = -1;
        }
        ++iIndex;
    }
    i = 14;
    if (sDirection == "backward")
    {i = 15;
        if (iIndex == 0)
        {
        iIndex = thumbLength;
        }
        --iIndex;
    }
    i = 16;
    if (sJumpTo == "beginning")
    {i = 17;
        iIndex = 0;
    }
    i = 18;
    if (sJumpTo == "end")
    {i = 19;
        iIndex = (thumbLength-1);
    }
    var nextCell = aCellArray[iIndex].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];

    i = 22;
    if (bReload) 
    {i = 23;
        //only do the click if we are reloading. That way, I can use this function to just update the "2 of 15" text.
        try
        {
        if (nextCell.id != "")
        {
            var bSyncRA = true;
            
            if (currentFocusedWindow == "1") //shouldn't this be 1, 5 or 6? 
            {
            //
            bSyncRA = false;
            }
            writeLog("startSlideShow() calls onTableCellClick()");
            onTableCellClick(nextCell, bSyncRA, false);
        }
        }
        catch(e)
        {
        writeLog("ERROR startSlideshow() cannot click on next cell: " + e.message);
        //alert("cannot click on the next cell.");
        }
    }
    i = 24;

    //the rotisserei should adjust when set choice changes. 
    var p = eval("Orientation" + framei);
    CurrentOrientation = p;
    tellImageControl("Orientation", CurrentOrientation, "InitialPosition", getBarPositionNumber(nextCell).toString(), "positionNumber", (iIndex+1) + " of " + thumbLength, "DoneSetup", "false", "", "", "", "", "", "", "", "", "", "");
    i = 25;
    //I also have to scroll the correct cell into view... 
    try 
    {
        slidingCell = nextCell;
        slideCell(framei);
        /*
        var xx = 0;
        if (InternetExplorer)
        {
        //nextCell.focus(); //worked great in IE, not in Safari/Firefox
        xx = nextCell.offsetParent.offsetParent.offsetLeft;
        }
        else
        {
        xx = nextCell.parentNode.parentNode.parentNode.parentNode.offsetLeft
        }
        //To scroll right there...
        var oIframe = document.getElementById("iframe" + framei);
        var oDoc = (oIframe.contentWindow || oIframe.contentDocument);
        try
        {
            if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
        }
        catch(e){}
        oDoc.getElementById("layerA").scrollLeft = xx - 250;
        */
    }
    catch(e)
    {
        writeLog("ERROR startSlideshow() cannot focus on next cell: " + e.message);
        //alert("cannot focus on next cell\n" + e.message);
    }
    i = 26;
    if (bContinue)
    {
        i = 27;
        timerSlideshow = window.setTimeout("startSlideshow(true, '" + sDirection + "', '" + sJumpTo + "', " + bReload + ")", iSlideshowInterval);
    }

    }
    catch(e)
    {
        writeLog("ERROR startSlideshow() at " + i + ": " + e.message);
        if (i == 18)
        {
            alert("The thumbnails did not load correctly. Please try again later.");
        }
        //else
        //{
        //    alert("ERROR startSlideshow() at " + i + "\n" + e.name + "\n" + e.description + "\n" + e.message)
        //}
    }
}
function stopSlideshow()
{
    window.clearTimeout(timerSlideshow);
}
var timerSlideCell, slidingCell, slidingCount = 0;
function slideCell(iFrame)
{
    //************
    //DISABLED... but remove this "return" if you want the thumbnails to scroll when selected.
    return;
    //************
    window.clearTimeout(timerSlideCell);
    var xx = 0;
    if (InternetExplorer)
    {
        xx = slidingCell.offsetParent.offsetParent.offsetLeft;
    }
    else
    {
        xx = slidingCell.parentNode.parentNode.parentNode.parentNode.offsetLeft
    }
    //To scroll right there...
    var oIframe = document.getElementById("iframe" + iFrame);
    var oDoc = (oIframe.contentWindow || oIframe.contentDocument);
    try
    {
        if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
    }
    catch(e){}
    var u = 9;
    //alert("comparing " + oDoc.getElementById("layerA").scrollLeft + " to " + (xx-250));
    var closeEnough = false;
    if (oDoc.getElementById("layerA").scrollLeft < (xx - 250))
    {
        //we have to move right
        if ((xx - 250) - oDoc.getElementById("layerA").scrollLeft < 10) closeEnough = true;
    }
    if (oDoc.getElementById("layerA").scrollLeft > (xx - 250))
    {
        //we have to move left
        u = -u;
        if (oDoc.getElementById("layerA").scrollLeft - (xx - 250) < 10) closeEnough = true;
    }
    if (closeEnough || slidingCount > 50)
    {
        oDoc.getElementById("layerA").scrollLeft = xx - 250;
        slidingCount = 0;
    }
    else
    {
        slidingCount++;
        oDoc.getElementById("layerA").scrollLeft = oDoc.getElementById("layerA").scrollLeft + u;
        timerSlideCell = window.setTimeout("slideCell(" + iFrame + ")", 35);
    }
}

//here are some functions that allow me to simulate scripting directly to Flash objects (which avoids problems with Mac-Safari)
var ac_1 = new Array(), is1sending = false;
var ac_2 = new Array(), is2sending = false;
var ac_3 = new Array(), is3sending = false;
var timerDSV1, timerDSV2, timerDSV3;
function doSetVariable(Ftarget, varName, varValue, c1, c1v, c2, c2v, c3, c3v, c4, c4v, c5, c5v, c6, c6v, c7, c7v, c8, c8v)
{
    writeLog("doSetVariable(" + Ftarget + ", " + varName + ", " + varValue + ", " + c1 + ", " + c1v + ", " + c2 + ", " + c2v + ", " + c3 + ", " + c3v + ", " + c4 + ", " + c4v + ", " + c5 + ", " + c5v + ", " + c6 + ", " + c6v + ", " + c7 + ", " + c7v + ", " + c8 + ", " + c8v + ")");
    try
    {
        if (varName == "" && varValue == "" && c1 == "" && c1v == "" && c2 == "" && c2v == "" && c3 == "" && c3v == "" && c4 == "" && c4v == "" && c5 == "" && c5v == "" && c6 == "" && c6v == "" && c7 == "" && c7v == "" && c8 == "" && c8v == "")
        {
        //if there are no values to send, don't send all blanks. 
        return;
        }
    }
    catch(e)
    {
        writeLog("ERROR doSetVariable(): " + e.message);
        //alert("ERROR doSetVariable()\n" + e.message);
    }
    //NOTE: I need a way to get clever about buffering commands. When commands are sent in in rapid-fire succession, 
    //  some are getting lost, resulting in bad behavior. I think I can build up arrays full of command arrays, and 
    //  send them out when the previous commands have been sent.  
    try
    {
        //TODO: This needs to be reworked again. I am stuffing this command into the array and also sending it,
        //  which results in multiple sends for one command set. I know I need to remember it in case it doesn't get sent, 
        //  but maybe I can keep track of "just sent sets", and compare when sending, to reduce the number of sends. 
        var aTemp = new Array(Ftarget, varName, varValue, c1, c1v, c2, c2v, c3, c3v, c4, c4v, c5, c5v, c6, c6v, c7, c7v, c8, c8v);
        var oArray = eval("ac_" + Ftarget);
        oArray.push(aTemp);
        if (eval("is" + Ftarget + "sending")==true)
        {
        var oTimer = eval("timerDSV" + Ftarget);
        oTimer = setTimeout("is" + Ftarget + "sending=false;doSetVariable('" + Ftarget + "','" + varName + "','" + varValue + "','" + c1 + "','" + c1v + "','" + c2 + "','" + c2v + "','" + c3 + "','" + c3v + "','" + c4 + "','" + c4v + "','" + c5 + "','" + c5v + "','" + c6 + "','" + c6v + "','" + c7 + "','" + c7v + "','" + c8 + "','" + c8v + "')", 2000);
        }
        else
        {
        //just send the command array.

        //oooooooooooooooooooooooooooo
        //If we are going to send the 
        //command, remove it from the stored array. 
        var throwaway = oArray.pop();
        //I can only do this if I also reset the  lastCommandX
        eval("lastCommand" + Ftarget + " = ''"); //KSB 1/28/2005 TESTING this idea: uncommented the throwaway, as well as the sendNextCommand in sendVariables, below...
        //oooooooooooooooooooooooooooo
        writeLog("doSetVariable() calls sendVariables()");
        eval("is" + Ftarget + "sending=true");
        sendVariables(Ftarget, varName, varValue, c1, c1v, c2, c2v, c3, c3v, c4, c4v, c5, c5v, c6, c6v, c7, c7v, c8, c8v);
        }
    }
    catch(e)
    {
        writeLog("ERROR doSetVariable(): " + e.message);
        //alert("Cannot execute doSetVariable().\n" + e.message);
    }
}
var lastCommand1 = "", lastCommand2 = "", lastCommand3 = "";
function sendNextCommand(lcName)
{
    //there are three arrays that keep track of commands buffered and ready to be sent. 
    //when this function is called, I need to check the appropriate array and send the next command set,
    //if there are any in that array. 
    writeLog("sendNextCommand(" + lcName + ")");
    //ooooooooooooooooooooooooooooooooo
    //I need to strip all lcName values
    //down to 4 characters (sometimes it
    //gets a strange appendage).
    lcName = lcName.substring(0, 4);
    //ooooooooooooooooooooooooooooooooo

    var aTemp = new Array();
    switch(lcName)
    {
        case "lc_1":
        //sceneControl
        clearTimeout(timerDSV1);
        if (ac_1.length > 0)
        {
            //
            aTemp = ac_1.shift(); //gets the first value (an array) in the buffer array.
        }
        else
        {
            writeLog("sendNextCommand(" + lcName + ") empty; returning.");
            is1sending = false;
            return;
        }
        break;

        case "lc_2":
        //imageControl
        clearTimeout(timerDSV2);
        if (ac_2.length > 0)
        {
            //
            aTemp = ac_2.shift(); //gets the first value (an array) in the buffer array.
        }
        else
        {
            writeLog("sendNextCommand(" + lcName + ") empty; returning.");
            is2sending = false;
            return;
        }
        break;

        case "lc_3":
        //WindowsComponent
        clearTimeout(timerDSV3);
        if (ac_3.length > 0)
        {
            //
            //window.status = "array has stuff";
            aTemp = ac_3.shift(); //gets the first value (an array) in the buffer array.
        }
        else
        {
            writeLog("sendNextCommand(" + lcName + ") empty; returning.");
            is3sending = false;
            return;
        }
        break;

        default:
        return;
        break;
    }
    writeLog("sendNextCommand(" + lcName + ") calls sendVariables()");
    sendVariables(aTemp[0], aTemp[1], aTemp[2], aTemp[3], aTemp[4], aTemp[5], aTemp[6], aTemp[7], aTemp[8], aTemp[9], aTemp[10], aTemp[11], aTemp[12], aTemp[13], aTemp[14], aTemp[15], aTemp[16], aTemp[17], aTemp[18])
}
function receiveVariable(fromName, command, args)
{
    //this is called by any of the Flash objects when they would have 
    //  normally done an fscommand. Since fscommand is not supported on the Mac-Safari, 
    //  I need to simulate it. 
    writeLog("receiveVariable(" + fromName + ", " + command + ", " + args + ")");
    try
    {
        if (fromName == "" || command == "" || args == "")
        {
        return;
        }
    }
    catch(e)
    {
	writeLog("ERROR receiveVariable().\n" + e.message + "\nfromName: " + fromName + "\ncommand: " + command + "\nargs: " + args);
        //alert("ERROR receiveVariable().\n" + e.message + "\nfromName: " + fromName + "\ncommand: " + command + "\nargs: " + args);
    }
    try
    {
        //
        switch(fromName)
        {
        case "ReferenceImage":
            //
            ReferenceImage_DoFSCommand(command, args);
            break;

        case "sceneControl":
            //
            sceneControl_DoFSCommand(command, args);
            break;

        case "WindowComponent":
            //actually, the frame with the WindowComponent in it does this.
            break;
        }
    }
    catch(e)
    {
        writeLog("ERROR receiveVariable(): " + e.message);
        //alert("QV Cannot execute receiveVariable().\n" + e.message + "\nfromName: " + fromName + "\ncommand: " + command + "\nargs: " + args);
    }
}
function refreshPage()
{
    if (InternetExplorer) //safari will not do this, since it causes an error. 
    {
        window.location = window.location; 
    }
}
function stopScroll()
{
    try
    {
        writeLog("stopScroll()");
        window.scrollTo(0,0);
    }
    catch(e)
    {
        //
    }
}
function findNewPosition(newPositionNumber)
{
    writeLog("findNewPosition(" + newPositionNumber + ")")
    //if we are coronal or sagittal, the ranges are different.
    //this puts the same info back into imageControl, so the bar stays put.
    //tellImageControl("positionNumber", args, "InitialPosition", args, "DoneSetup", "false", "", "", "", "", "", "", "", "", "", "");
    var lowerBound;
    var totalRange;
    writeLog("-- CurrentOrientation: " + CurrentOrientation);
    writeLog("-- currentFocusedWindow: " + currentFocusedWindow);
    writeLog("-- currentAtlasWindow: " + currentAtlasWindow);
    switch(CurrentOrientation)
    {
        case "coronal":
        lowerBound = 19;
        totalRange = 90;
        break;

        default:
            if (currentFocusedWindow == "1")
            {
                currentFocusedWindow = currentAtlasWindow; //5 or 6
            }
        lowerBound = 35;
        totalRange = 25; //50;
        break;
    } 
    if (newPositionNumber < lowerBound)
    {
        newPositionNumber = lowerBound;
    }
    if (newPositionNumber >= lowerBound+totalRange)
    {
        newPositionNumber = lowerBound+totalRange-1;
    }
    var iIndex = 0;
    var thumbLength = 0;
    var oIframe = document.getElementById("iframe" + currentFocusedWindow);
    var oDoc = (oIframe.contentWindow || oIframe.contentDocument);
    try
    {
        if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
    }
    catch(e){}
    oTable = oDoc.getElementById("OverallTableA");
    var cTD = oTable.getElementsByTagName("tr")[0].getElementsByTagName("td");
    //strip out the nested children. 
    var aCellArray = new Array();
    //OK, since getElementsByTagName return all matching descendants, I am getting TR tags from nested tables.
    //This should retain only direct children, and remove nested ones.
    //getElementsByTagName doesn't actually return an array. It returns an HTMLCollection. I need an array so I can filter out nested children. 
    for (k = 0; k < cTD.length; ++k)
    {
        if (cTD[k].parentNode.parentNode.parentNode.id.substring(0, 12) == "OverallTable")
        {
        try
        {
            aCellArray.push(cTD[k]);
        }
        catch(e)
        {
            writeLog("ERROR findNewPosition()\nk = " + k + "\n" + e.message)
            //alert("ERROR filtering array.\nk = " + k + "\n" + e.message);
        }
        }
    }
    thumbLength = aCellArray.length;

    //Now compute the ratio of the args passed to the range for this orientation. 
    var pos = newPositionNumber - lowerBound;
    //so pos is what percent of totalRange?
     var xPercent = pos/totalRange*100;

    //Then I can take that same ration and apply it to my thumblength to get an appropriate index.
    iIndex = parseInt(xPercent*thumbLength/100);

    var nextCell = aCellArray[iIndex].getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0];

    try
    {
        writeLog("-- nextCell.id: " + nextCell.id);
        if (nextCell.id != "")
        {
        var bSyncRA = true;
        if (currentFocusedWindow == "1")
        {
            //
            bSyncRA = false;
        }
        onTableCellClick(nextCell, bSyncRA, false);
        }
    }
    catch(e)
    {
        writeLog("ERROR findNewPosition(): " + e.message)
        alert("cannot click on target cell.");
    }
}
var bLogUnlocked = false;
function unlockLogger()
{
    //this simulates a double-double-click on the logo to open up the logging tool
    if (bLogUnlocked)
    {
        showLog();
    }
    else
    {
        bLogUnlocked = true;
        setTimeout("bLogUnlocked=false", 2000);
    }
}
var InternetExplorer = navigator.appName.indexOf("Microsoft") != -1;
function sceneControl_DoFSCommand(command, args)
{
    writeLog("sceneControl_DoFSCommand(" + command + ", " + args + ")");
    checkStarted();
    var myFlashObj = InternetExplorer ? sceneControl : document.sceneControl;
    switch(command)
    {
    case "show":
        //
        changeColor(args);
        stopSlideshow(); //just in case it is going when they change sets, stop the slideshow.
        startSlideshow(false, "", "", false); //really, this just updates the "2 of 15" text.
        //removing ("focus", args) becuase I think it causes a loop. 
        //KSB 12/9/2004: putting the "focus" command back in. It helps when windows are hidden to bring the window to the front. 
        tellFlashWindows("ch" + args + "checked", "true", "focus", args, "", "", "", "", "", "", "", "", "", "", "", "", "", "");
        break;

    case "hide":
        //
        tellFlashWindows("ch" + args + "checked", "false", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "");
        break;

    case "focus":
        //
        //*************************
        var p = eval("Orientation" + args); //this way I can send in the correct orientation when the focus changes. 
        //I need to change the value of "p" if we have just chosen window 1. 
        if (args == "1")
        {
            //@@@@@@@@@@@@@@@@@@@@@@@@@
            //I need to keep track of currentAtlasWindow and not change it if the box is unchecked. 
            var pA = eval("Orientation" + currentAtlasWindow);
            writeLog("sc_dfsc sees that currentAtlasWindow is " + currentAtlasWindow);
            writeLog("and it knows that Orientation" + currentAtlasWindow + " is " + pA);
            //@@@@@@@@@@@@@@@@@@@@@@@@@
            writeLog("sceneControl_DoFSCommand() change plane from " + p + " to " + pA);
            if (pA == "coronal") lastAtlasSet = "1";
            p = pA; //atlas orientation
        }
        //*************************
        changeColor(args);
        tellImageControl("doStop","yes", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""); //so the "play" button goes "off" when changing windows.
        stopSlideshow(); //just in case it is going when they change sets, stop the slideshow.
        startSlideshow(false, "", "", false); //really, this just updates the "2 of 15" text.
        //12/3/2004 KSB: adding (focus/args) back because it is necessary and does not seem to be the cause of any loop. .
        var ZIP = ""; //zoomifyImagePath
        var ZIP_value = "";
        var XZIP = ""; //exPath
        var XZIP_value = "";
        var bigO = ""; //only tell WC about an orientation change when syncing
        if (document.getElementById("cbAllowSync").checked == true || innerButtonUsed == true) //this allows the users to uncheck a box and stop the sync.
            {
                innerButtonUsed = false; //reset it
            try
            {
                ZIP = "zoomifyImagePath";
                ZIP_value = eval("selectedCell" + currentAtlasWindow + ".id");
                XZIP = "exPath";
                XZIP_value = eval("selectedCell" + currentAtlasWindow + ".getAttribute('XMaskPath')");
                if (XZIP_value == "")
                {
                    XZIP_value = "//notThere.pff"; //just a dummy path that leads nowhere to turn off the button.
                }
                bigO = "Orientation";
            }
            catch(e)
            {
                writeLog("ERROR sceneControl_DoFSCommand(focus): " + e.message);
            }
        }
        //NOTE: adding "bAtlasSyncing", "true" does not seem to help make the atlas sync when set change occurs.
        writeLog("TFW 1");
        tellFlashWindows("ch" + args + "checked", "true", "focus", args, XZIP, XZIP_value, ZIP, ZIP_value, bigO, p, "", "", "", "", "", "", "", "");
        break;
    }
}
function ReferenceImage_DoFSCommand(command, args)
{
    writeLog("ReferenceImage_DoFSCommand(" + command + ", " + args + ")");
    checkStarted();
    var myFlashObj = InternetExplorer ? sceneControl : document.sceneControl;
    switch(command)
    {
        case "selectImage":
        //beginning, back, next, end, play, stop
        switch(args)
        {
            case "beginning":
            //go to the first image in the list
            stopSlideshow();
            startSlideshow(false, "forward", "beginning", true);
            break;

            case "back":
            //go to the previous image in the list
            stopSlideshow();
            startSlideshow(false, "backward", "", true);
            break;

            case "next":
            //go to the next image in the list
            stopSlideshow();
            startSlideshow(false, "forward", "", true);
            break;

            case "end":
            //go to the last image in the list
            stopSlideshow();
            startSlideshow(false, "forward", "end", true);
            break;

            case "play":
            //begin autoscrolling through the list  
            stopSlideshow();
            startSlideshow(true, "forward", "", true);
            break;

            case "stop":
            //stop autoscrolling through the list
            stopSlideshow();
            break;
        }

        break;

        case "NewPosition":
        //the bar was moved to a new place.
        //figure out which of the slices we are closest to.
        //I want to pick the closest thumbnail and choose that one as if I clicked on it.
        findNewPosition(args);
        break;
    
        case "LC":
            bLCconfirmed = true;
            break;
    }
}
if (navigator.appName && navigator.appName.indexOf("Microsoft") != -1 && navigator.userAgent.indexOf("Windows") != -1 && navigator.userAgent.indexOf("Windows 3.1") == -1) 
{
    document.write('<SCRIPT LANGUAGE=VBScript\> \n');
    document.write('on error resume next \n');
    document.write('Sub sceneControl_FSCommand(ByVal command, ByVal args)\n');
    document.write(' call sceneControl_DoFSCommand(command, args)\n');
    document.write('end sub\n');
    document.write('Sub ReferenceImage_FSCommand(ByVal command, ByVal args)\n');
    document.write(' call ReferenceImage_DoFSCommand(command, args)\n');
    document.write('end sub\n');
    document.write('</SCRIPT\> \n');
}
function sendVariables(Ftarget, varName, varValue, c1, c1v, c2, c2v, c3, c3v, c4, c4v, c5, c5v, c6, c6v, c7, c7v, c8, c8v)
{
    writeLog("sendVariables(" + Ftarget + ", " + varName + ", " + varValue + ", " + c1 + ", " + c1v + ", " + c2 + ", " + c2v + ", " + c3 + ", " + c3v + ", " + c4 + ", " + c4v + ", " + c5 + ", " + c5v + ", " + c6 + ", " + c6v + ", " + c7 + ", " + c7v + ", " + c8 + ", " + c8v + ")");
    if (Ftarget == UNDEFINED)
    {
        //for some reason, this sometimes comes through as undefined, and causes an error. I should find out why that happens, but for now, this prevents bad behavior. 
        return;
    }
    //I don't want to send in the same exact command set twice in a row, so I test it to make sure it changes by creating one long string out of the commands to compare to the preious command string sent to that window.
    var commandText = varName + varValue + c1 + c1v + c2 + c2v + c3 + c3v + c4 + c4v + c5 + c5v + c6 + c6v + c7 + c7v + c8 + c8v;
    if (eval("lastCommand" + Ftarget + " == '" + commandText + "'"))
    {
        //move on if we just sent the exact same set of commands.
        writeLog("sendVariables() detects repeated command; calls sendNextCommand()");
        sendNextCommand("lc_" + Ftarget);
        return;
    }
    eval("lastCommand" + Ftarget + " = '" + commandText + "'");
    //I need a way to get clever about buffering commands. When commands are sent in in rapid-fire succession, 
    //some are getting lost, resulting in bad behavior. I build up arrays full of command arrays, and 
    //send them out when the previous commands have been sent. 
    try
    {
        //************ SEND COMMANDS HERE *****************
        /*if (Ftarget == "3") //1, 2, or 3
        {
        alert("SENDING\nFtarget: " + Ftarget + "\nvarName: " + varName + "\nvarValue: " + varValue + "\nc1: " + c1 + "\nc1v: " + c1v + "\nc2: " + c2 + "\nc2v: " + c2v + "\nc3: " + c3 + "\nc3v: " + c3v + "\nc4: " + c4 + "\nc4v: " + c4v + "\nc5: " + c5 + "\nc5v: " + c5v + "\nc6: " + c6 + "\nc6v: " + c6v + "\nc7: " + c7 + "\nc7v: " + c7v + "\nc8: " + c8 + "\nc8v: " + c8v);
        }*/
        var myFrame = document.getElementById("senderFrame" + Ftarget);
        writeLog("sendVariables() sUnifierCode " + sUnifierCode);
        writeLog("sendVariables() sending commands to object " + Ftarget);
        myFrame.src = sContextPath + "/localConnectionInternalFrame.do?LCName=lc_" + Ftarget + sUnifierCode + "&methodToExecute=parseLC&param1=" + varName + "&param2=" + varValue + "&command1=" + c1 + "&command1v=" + c1v + "&command2=" + c2 + "&command2v=" + c2v + "&command3=" + c3 + "&command3v=" + c3v + "&command4=" + c4 + "&command4v=" + c4v + "&command5=" + c5 + "&command5v=" + c5v + "&command6=" + c6 + "&command6v=" + c6v + "&command7=" + c7 + "&command7v=" + c7v + "&command8=" + c8 + "&command8v=" + c8v + "";
    }
    catch(e)
    {
        writeLog("ERROR sendVariables(): " + e.message);
    }
}
var innerButtonUsed = false;
function doNavCommand(command)
{
    writeLog("doNavCommand(" + command + ")");
    //each of the buttons in the upper right corner of the page sends in the command here.
    switch(command)
    {
        case "instructions":
        //
        openTourWindow(fwdABATour,'Instructions','resizable=yes,scrollbars=no,width=800,height=533,dependent=yes');
        break;

        case "help":
        //
        openHelpWindow(sContextPath + '/help/wwhelp.htm','Help','resizable=yes,scrollbars=yes,width=1011,height=700,dependent=yes');
        break;

        case "faq":
        //
        openFaqWindow(fwdFAQ,'FAQ', 'scrollbars=yes,resizable=no,width=760,height=750,dependent=yes');
        break;

        case "support":
        //
        openSupportWindow(fwdSupport,'Support','resizable=no,scrollbars=no,width=492,height=630,dependent=yes');
        break;

        case "feedback":
        //
        openFeedbackWindow(fwdFeedback,'Feedback','resizable=no,width=492,height=530,dependent=yes');
        break;

        case "login":
        //
        break;

        case "legend":
        //TODO: The legend page path needs to be one of those forwards.
        openLegendWindow(fwdLegend,'Legend','resizable=yes,scrollbars=no,width=900,height=700,dependent=yes');
        break;

        case "refatlasdoc":
        //opens a window with "AllenReferenceAtlas.pdf" : doNavCommand('refatlasdoc');
        openRADocWindow(fwdRADoc,'RADoc','resizable=yes,scrollbars=yes,width=700,height=550,dependent=yes');
        break;
        
        case "coronal":
            innerButtonUsed = true;
            lastAtlasSet = "1";
            switchPlanes("coronal");
        break;
        
        case "sagittal":
            innerButtonUsed = true;
            //lastAtlasSet = "5"; or "6"???
            switchPlanes("sagittal");
        break;
        
        case "annotation":
            innerButtonUsed = true;
            if (CurrentOrientation == "sagittal")
            {
                lastAtlasSet = "5";
                switchSagittal("annotation");
            }
            else
            {
                lastAtlasSet = "1";
                switchCoronal("annotation");
            }
        break;
        
        case "nssl":
            innerButtonUsed = true;
            if (CurrentOrientation == "sagittal")
            {
                lastAtlasSet = "6";
                switchSagittal("nssl");
            }
            else
            {
                lastAtlasSet = "7";
                switchCoronal("nssl");
            }
        break;
    }
}
function openSingleViewer(imageID)
{
    //this opens the single_view.jsp page.
    writeLog("openSingleViewer(" + imageID + ")");
    openSingleViewWindow2(sContextPath + "/viewImage.do?imageId=" + imageID);
}
function openSingleViewWindow2(winURL) {
    //NOTE: Safari has a hard time finding this function in the "windows.js" include file, but when I put it in here, it works. 
    //opens the single_view.jsp page (feeding in the argument imageID)
    var t = new Date();
    var winName = "W" + t.getHours() + "" + t.getMinutes() + "" + t.getMilliseconds(); //"unique" names allow multiple instances
    var w=800;
    var h=600;
    var posLeft=(screen.width)?(screen.width-w)/2:100;
    var posTop=(screen.height)?(screen.height-h)/2:100;
    var settings='width='+w+',height='+h+',top='+posTop+',left='+posLeft+',scrollbars=no,location=no,directories=no,status=no,menubar=no,toolbar=no,resizable=yes';
    var newWindow = window.open(winURL,winName,settings);
    try
    {
        var wname = newWindow.name;
        newWindow.focus();
    }
    catch(e)
    {
        alert("Your POP-UP BLOCKER has prevented us from launching a new window.\nPlease disable the POP-UP BLOCKER and try again.");
    }
}
function switchPlanes(newPlane)
{
    //changes the var CurrentOrientation to "coronal" or "sagittal"
    writeLog("switchPlanes(" + newPlane + ")");
    CurrentOrientation = newPlane;
    var oldSagittalView = currentSagittalView;
    var oldCoronalView = currentCoronalView;
    var oldAtlasWindow = currentAtlasWindow;
    //so we have to keep track of which thumbnail set we will show. 
    try
    {
        switchAtlas();
    }
    catch(e)
    {
        writeLog("ERROR: cannot switch planes. Probably the page has not loaded completely yet.");
        var oLayer1 = document.getElementById("iframe1"); 
        var oLayer5 = document.getElementById("iframe5"); 
        var oLayer6 = document.getElementById("iframe6"); 
        var oLayer7 = document.getElementById("iframe7"); 
        oLayer1.style.left = -1100;
        oLayer5.style.left = -1100;
        oLayer6.style.left = -1100;
        oLayer7.style.left = -1100;
        currentSagittalView = oldSagittalView;
        currentCoronalView = oldCoronalView;
        currentAtlasWindow = oldAtlasWindow;
        var oLayer = document.getElementById("iframe" + currentAtlasWindow);
        oLayer.style.left = 365;
        return;
    }
}
var currentSagittalView = "annotation";
var currentCoronalView = "annotation";
var currentAtlasWindow = "1"; //BUT this has to change when we do a sagittal set, it should start on 5!
function switchSagittal(newView)
{
    writeLog("switchSagittal(" + newView + ")");
    //changes the var currentSagittalView to "annotation" or "nssl" (both sagittal views)
    var oldSagittalView = currentSagittalView;
    var oldAtlasWindow = currentAtlasWindow;
    currentSagittalView = newView;
    try
    {
        switchAtlas();
    }
    catch(e)
    {
        writeLog("ERROR: cannot switch sagittal view. Probably the page has not loaded completely yet.");
        currentSagittalView = oldSagittalView;
        currentAtlasWindow = oldAtlasWindow;
        var oLayer = document.getElementById("iframe" + currentAtlasWindow);
        oLayer.style.left = 365;
        return;
    }
}
function switchCoronal(newView)
{
    writeLog("switchCoronal(" + newView + ")");
    //changes the var currentCoronalView to "annotation" or "nssl" (both coronal views)
    var oldCoronalView = currentCoronalView;
    var oldAtlasWindow = currentAtlasWindow;
    currentCoronalView = newView;
    try
    {
        switchAtlas();
    }
    catch(e)
    {
        writeLog("ERROR: cannot switch Coronal view. Probably the page has not loaded completely yet.");
        currentCoronalView = oldCoronalView;
        currentAtlasWindow = oldAtlasWindow;
        var oLayer = document.getElementById("iframe" + currentAtlasWindow);
        oLayer.style.left = 365;
        return;
    }
}
function switchAtlas()
{
    currentFocusedWindow = "1"; //testing this... always pump the image into w1
    writeLog("switchAtlas()");
    writeLog("switchAtlas() CurrentOrientation: " + CurrentOrientation);
    //called when we change the atlas view between coronal and sagittal, and when sagittal, between nssl and annotated.
    //CurrentOrientation and currentSagittalView
    switch(CurrentOrientation)
    {
        case "coronal":
            //
            writeLog("switchAtlas() detects coronal: |" + currentCoronalView + "|");
            switch(currentCoronalView)
            {
                case "annotation":
                    //
                    writeLog("switchAtlas() detects coronal-anno");
                    currentAtlasWindow = "1";
                break;
                
                case "nssl":
                    //
                    writeLog("switchAtlas() detects coronal-nssl");
                    currentAtlasWindow = "7";
                break;
            }
        break;
        
        case "sagittal":
            writeLog("switchAtlas() detects sagittal: |" + currentSagittalView + "|");
            switch(currentSagittalView)
            {
                case "annotation":
                    //
                    writeLog("switchAtlas() detects sag-anno");
                    currentAtlasWindow = "5";
                break;
                
                case "nssl":
                    //
                    writeLog("switchAtlas() detects sag-nssl");
                    currentAtlasWindow = "6";
                break;
            }
        break;
    }
    writeLog("switchAtlas() currentAtlasWindow: " + currentAtlasWindow);
    //OK, now that all the variables are set, we can move things around.
    var oLayer = document.getElementById("iframe" + currentAtlasWindow); 
    var oLayer1 = document.getElementById("iframe1"); 
    var oLayer5 = document.getElementById("iframe5"); 
    var oLayer6 = document.getElementById("iframe6"); 
    var oLayer7 = document.getElementById("iframe7"); 
    oLayer1.style.left = -1100;
    oLayer5.style.left = -1100;
    oLayer6.style.left = -1100;
    oLayer7.style.left = -1100;
    oLayer.style.left = 365;
    //I don't think we have to change color, since all atlases are the same color. 
    //BUT I do want to pump the correct image into the viewer now.
    writeLog("switchAtlas() calls onTableCellClick() for selectedCell" + currentAtlasWindow);
    writeLog("BTW, selectedCell" + currentAtlasWindow + ".id = " + eval("selectedCell" + currentAtlasWindow).id);
    //************************************
    //IF the user touches the "show sagittal" button too soon (like before all the atlas iframes load) caused errors.
    //stop the error! If the cell doesn't have any attributes we can read, ignore the command! 
    var c = eval("selectedCell" + currentAtlasWindow);
    var cid = c.getAttribute("id"); //this will force an error if the iframe has not been built yet; caught by the calling functions (switchPlanes and switchSagittal).
    //************************************
    onTableCellClick(eval("selectedCell" + currentAtlasWindow), true, false); //maybe that should be false, true? 
    //startSlideshow(false, "", "", false); //really, this just updates the "2 of 15" text.
    changeColor(currentAtlasWindow); //hopefully this will keep the colors correct when changing from another set.
    //it seems I still have to make the sceneControl correct
    tellSceneControl("focus", "1", "", "", "",  "", "",  "", "",  "", "",  "", "",  "", "",  "", "", "");
}
function fixImageSet(frameNum)
{
    //This does battle with the bug that makes some thumbnails never appear.
    //This is called when the page loads, then when the set choice changes. 
    var oIframe, oDoc;
    oIframe = document.getElementById("iframe" + frameNum);
    oDoc = (oIframe.contentWindow || oIframe.contentDocument);
    try
    {
        if (oDoc.document) oDoc = oDoc.document; //some browsers are weird.
    }
    catch(e){}
    if (!oDoc.images) return;
    var aImg = oDoc.images;
    for (x=0; x < aImg.length; ++x)
    {
        aImg[x].src = aImg[x].src;
    }
}
function syncMemory()
{
    //called when the user chdecks or unchecks a checkbox that allows atlas sync. 
    var isChecked = document.getElementById("cbAllowSync").checked;
    writeLog("The checkbox is now " + isChecked + ", currentAtlasWindow=" + currentAtlasWindow);
    if (isChecked)
    {
        //when the box gets checked, sync the atlas with the current set.
        if (currentFocusedWindow != "1")
        {
            onTableCellClick(eval("selectedCell" + currentFocusedWindow), true, false);
        }
    }
    lastAtlasSet = currentAtlasWindow;
}
function verifyLC()
{
    //only Safari will do this. 
    writeLog("verifyLC()");
    if (bLCconfirmed == false)
    {
        alert("You should be aware that Safari users are limited to using one Image Viewing Tool (IVT).\n\nYou will need to close all IVTs before attempting to open another.");
    }
}
function openOpener()
{
    //close this tool and return to search
    if (window.opener.opener)
    {
        //if the IVT was opened from the thumbnails page
        window.opener.opener.focus();
    }
    else
    {
        //the IVT was opened directly from results (search) page
        window.opener.focus();
    }
    window.close();
}
