// aimsXML.js
/*
*  JavaScript template file for ArcIMS HTML Viewer
*               dependent on ArcIMSparam.js, aimsCommon.js, aimsMap.js,
*/

aimsXMLPresent=true;
// client version
var cVersion = "&ClientVersion=3.1"; 
/*
***************************************************************************************

Functions for sending XML requests and XML reponses

***************************************************************************************
*/

// global variables
        // change these in aimsCustom.js to send XML response to custom function.
        // use numbers >= 1000
var selectXMLMode = 6;
var identifyXMLMode = 7;
var queryXMLMode = 8;
var findXMLMode = 14;
var hyperlinkXMLMode = 15;

// encoding for XML header
var charEncoding = "UTF-8";
var localeEncoding = 'encoding="' + charEncoding + '" ';

// charset for dynamic HTML pages - static pages must be changed manually
var charSet = "ISO-8859-1"

var formColor = "#000000";

// common dynamic variables
var XMLMode = 1;
var okToSend = true;

var xHalf = xDistance/2;
var yHalf = yDistance/2;

// ending position to start parse scan of XML string
var xmlEndPos = 0;

//var theImageType = "PNG";

var drawOVExtentBox=false;
// force a request for Overview map image with each map request?
var forceNewOVMap = false;
// the base servlet connector URL
var connectorURL = "http://" + hostName + "/servlet/com.esri.esrimap.Esrimap?ServiceName=redirect";

        // index of current active MapService - default is zero - multiples in MultiService sample
var activeMapServiceIndex = 0;
        // array for determining if extent coordinates should have comma instead of point for decimals
var forceCommaInRequest = new Array();
forceCommaInRequest[activeMapServiceIndex] = false;
var forceCommaInOV = false;

var pastStart=false;
if (hasOVMap != true) pastStart = true;

// send in XML request and get XML response - uses helper applet
function sendToServer(URLString,XMLRequest,theType) {
        if (parent.PostFrame.document.forms[0]!=null) {
                if (okToSend) {
                        XMLMode = theType;
                        if ((XMLMode==1) && (legendVisible)) {
                                showRetrieveMap();
                        }
                        if (debugOn>2) alert(msgList[8] + URLString + msgList[9] + XMLRequest);
                        okToSend = false;
                                var theForm = parent.PostFrame.document.forms[0];
                                URLString = URLString + cVersion;
                                var requestURL = URLString;
                                if (theForm.RedirectURL!=null) {
                                        if (isNotSameHostInURL(URLString, hostName)) {
                                                requestURL = connectorURL;
                                                theForm.RedirectURL.value = URLString;
                                                
                                        } else {
                                                theForm.RedirectURL.value = "";
                                        }

                                        
                                }
                                if (doURLencode) {
                                        theForm.action = requestURL + "&Form=True&Encode=True";
                                } else {
                                        theForm.action = requestURL + "&Form=True&Encode=False";
                                }
                                var xmlHeader = '<?xml version="1.0" ' + localeEncoding + '?>';
                                theForm.ArcXMLRequest.value = xmlHeader + XMLRequest;
                                if (theForm.FormCharset!=null) theForm.FormCharset.value = charSet;
                                if (theForm.BgColor!=null) theForm.BgColor.value = formColor;
                                
                                theForm.submit();
                                
                } else {
                        alert(msgList[10]);
                        hideRetrieveMap();
                        hideRetrieveData();
                }
        } else {
                alert(msgList[11]);
                        hideRetrieveMap();
                        hideRetrieveData();
        }
                
}

// send custom XML request. . . set up custom response handler
function sendCustomToServer(XMLRequest, theFunction, theType) {
        var theForm = parent.PostFrame.document.forms[0];
        theForm.JavaScriptFunction.value = theFunction;
        sendToServer(imsQueryURL,XMLRequest,theType)
}

// send the created xml request to map server
function sendMapXML() {
        beforeMapRefresh();
        showRetrieveMap();
        var theText = writeXML();
        if (debugOn==2) alert(msgList[12] + theText);
        //alert("theText ds sendMapXML   " + theText);
        sendToServer(imsURL,theText,1);
}

// process the response xml
function processXML(theReplyIn) {
        if (doURLencode) {
                theReplyIn = replacePlus(theReplyIn);
                var theReply = unescape(theReplyIn);
        } else {
                var theReply = theReplyIn;
        }
        
        okToSend = true;
        if (debugOn>2) alert(msgList[13] + theReply);
        var theError = getXMLErrorMessage(theReply);
        
        
        //alert("LayerName[ActiveLayerIndex]:   " + LayerName[ActiveLayerIndex] + "\nXMLMode:   " + XMLMode);
        switch(XMLMode) {
                case 1:
                        //alert("1");
                        var theURL = "";
                        theURL = getURL(theReply);
                        if (theURL != "") {
                                getXYs(theReply);
                                document.theImage.src = theURL;
                                //alert("avant afterMapRefresh");
                                afterMapRefresh();
                                if (toolMode==3) {
                                        moveLayer("theMap",hspc,vspc);
                                        clipLayer2("theMap",0,0,iWidth,iHeight);
                                        window.setTimeout('showLayer("theMap");',1000);
                                        if (hasLayer("theMapClicks")) {
                                                moveLayer("theMapClicks",hspc,vspc);
                                                clipLayer2("theMapClicks",0,0,iWidth,iHeight);
                                
                                        }
                                }
                                
                        }
                        else {
                                
                                if (debugOn>0) {
                                        alert(msgList[14] + "\n" + theReply);
                                } else {
                                        alert(msgList[14] + theError);
                                }
                        }
                        if (toolMode==20) {
                                updateMeasureBox();
                        }
                        if (legendVisible) {
                        }
                        
                        //alert("hasOVMap:  " + ovIsVisible);
                        if (hasOVMap) {
                                if (ovIsVisible) {
                                // ask for the overview
                                        if ((!pastStart) || (forceNewOVMap)) {
                                                
                                                theText = writeOVXML();
                                                sendToServer(imsOVURL,theText,2);
                                        } else {
                                                putExtentOnOVMap();
                                                hideRetrieveMap();
                                        }
                                } else {
                                        if ((!pastStart) || (forceNewOVMap)) {
                                                theText = writeOVXML();
                                                sendToServer(imsOVURL,theText,2);
                                        } else {
                                        	//alert("hasOVMap:  " + ovIsVisible);
                                                hideRetrieveMap();
                                        }
                                
                                }
                        } else {
                                hideRetrieveMap();
                        }
                        if (aimsBufferPresent) {
                        	//alert("getBufferedData:   " + getBufferedData);
                                if (getBufferedData) {
                                        var buffString = writeGetBufferedData();
                                        if (buffString!="") {
                                                sendToServer(imsQueryURL,buffString,11);
                                        } else {
                                                alert(msgList[15]);
                                        }
                                        getBufferedData=false;
                                } 
                        }
                        //alert("A la fin de 1");
                        break

                case 2:
                        // just put up an overview map
                        var theURL = "";
                        theURL = getURL(theReply);
                        if (!pastStart) {
                                getOVXYs(theReply);
                                pastStart=true;
                                
                        }
                        if (theURL != "") {
                                ovImageVar.src = theURL; 
                        }
                        else {
                        
                                if (debugOn>0) {
                                        alert(msgList[16] + "\n" + theReply);
                                } else {
                                        alert(msgList[16] + theError);
                                }
                                
                        }
                        if (ovIsVisible) putExtentOnOVMap();
                        hideRetrieveMap();
                        
                        break

                case 3:
                        //  just get full extent - service info
                        if (getLimitExtent) {
                                getXYs(theReply);
                                fullLeft = eLeft;
                                fullRight = eRight;
                                fullTop = eTop;
                                fullBottom = eBottom;
                                fullOVLeft = eLeft;
                                fullOVRight = eRight;
                                fullOVTop = eTop;
                                fullOVBottom = eBottom;
                                limitLeft = eLeft;
                                limitRight = eRight;
                                limitTop = eTop;
                                limitBottom = eBottom;
                        } else {
                                fullLeft = limitLeft;
                                fullRight = limitRight;
                                fullTop = limitTop;
                                fullBottom = limitBottom;
                                fullOVLeft = limitLeft;
                                fullOVRight = limitRight;
                                fullOVTop = limitTop;
                                fullOVBottom = limitBottom;
                        }
                        
                        fullWidth = Math.abs(fullRight - fullLeft);
                        fullHeight = Math.abs(fullTop - fullBottom);
                        fullOVWidth = Math.abs(fullOVRight - fullOVLeft);
                        fullOVHeight = Math.abs(fullOVTop - fullOVBottom);
                        
                        if (ThemePresent==true){
                        	ChaineLayerID=theReply;		//theReply contient toutes les couches avec leur ID correspondant
                        	//alert("Avant l'envoi" + "\NomTheme:     " + NomTheme + "\nChaineLayerID:     " + ChaineLayerID);
                        	ThemeAffiche(ChaineLayerID);	//la fonction dans AIMSMap.js qui permet de rendre ou non visible les couches
                        	//alert("ChaineLayerID:     " + ChaineLayerID);
                        	
                        }
                        
                        theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_SERVICE_INFO />\n';
                        theString += '</REQUEST>\n</ARCXML>';
                        // get list of geocoding layers
                        if((aimsGeocodePresent) && ((useGeocode) || (useReverseGeocode))) {
                                theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_SERVICE_INFO  renderer="false" />\n';
                                theString += '</REQUEST>\n</ARCXML>';
                                sendToServer(imsGeocodeURL,theString,25);
                        } else {
                                theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_SERVICE_INFO  renderer="false" extensions="true" />\n';
                                theString += '</REQUEST>\n</ARCXML>';
                                sendToServer(imsURL,theString,4);
                                useGeocode=false;
                                useReverseGeocode=false;
                                
                        }
                        
                        break

                case 4:
                        // get service info - extent, layers
                        forceCommaInRequest[activeMapServiceIndex] = false;
                        processStartExtent(theReply);
                        
                        break

                case 5:
                        // get a list of ImageServices
                        processCatalog(theReply);
                        
                        break

                case 6:
                        // get select response
                        displayAttributeData(theReply);
                        break

                case 7:
                        // get identify response
                        if(LayerName[ActiveLayerIndex] == "Role_evaluation_2.5k") {
                                displayAttributeDataWindowRole(theReply);	//ds la page amisIdentify.js
                        } else {
                                displayAttributeDataNewWindow(theReply);	//ds la page amisIdentify.js
                        }
                        
                        break

                case 8:
                        // get query response
                        displayAttributeData(theReply);
                        break

                case 9:
                        // get geocode response
                        processGeocode(theReply);
                        
                        break
                case 10:
                        // get identifyall response
                        doIdentifyAll(theReply);
                        
                        break
                case 11:
                        // get buffer response
                        //alert("11")
                        getBufferAttributeData(theReply)
                        break
                case 14:
                        // get find response
                        displayAttributeData(theReply);
                        
                        break   

                case 15:
                        // get hyperlink response
                        parseHyperLink(theReply);
                        
                        break
                
                case 16:
                        // get hyperlinkAny response
                        parseHyperLinkAny(theReply);
                        
                        break
                
                case 20:
                        // process startup query
                        parseStartQuery(theReply);
                        
                        break
                case 21:
                        // get query response
                        displayAttributeDataNewWindow(theReply);
                        break
                case 25:
                        // get geocoding layers
                        parseGeocodeLayers(theReply);
                        // get layers for display
                        var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_SERVICE_INFO  renderer="false" extensions="true" />\n';
                        theString += '</REQUEST>\n</ARCXML>';
                        sendToServer(imsURL,theString,4);
                        
                        break

                case 26:
                        // get geocoding layers
                        if (parseGeocodeParams(theReply,GCLayers[GCActiveLayer])) {
                                var theAddressForm = appDir + "addmatch.htm";
                                //if ((useExternalWindow) || (!useTextFrame)) {
                                        //var Win1 = window.open(theAddressForm,"QueryWindow","width=650,height=350,scrollbars=yes,resizable=yes");
                                //} else {
                                        //Recherche.document.location= theAddressForm;
                                        //alert(parent.TOC2Frame.TOCText);
                                        parent.TOC2Frame.TOCText.document.location= theAddressForm;
                                        //parent.TextFrame.document.location= theAddressForm;
                                //}
                        } else {
                                if (debugOn>0) {
                                        alert(msgList[17] + "\n" + theReply);
                                        if (parent.TextFrame!=null) parent.TextFrame.document.location= appDir + "blank.htm";
                                } else {
                                        alert(msgList[17]);
                                        if (parent.TextFrame!=null) parent.TextFrame.document.location= appDir + "blank.htm";
                                }
                        }
                        
                        break

                case 27:
                        // get geocoding results
                        parseGeocodeResults(theReply);
                        
                        break
                case 40:
                        // get list of sample field values
                        parseFieldSamples(theReply);
                        writeQueryForm();
                        
                        break
                case 41:
                        // get list of sample field values
                        parseFieldSamples(theReply);
                        writeQueryForm2();
                        break
                case 55:
                        // get layer storedqueries
                        parseStoredQueries(theReply);
                        break

                case 70:
                        // get layer field for submission to external db
                        parseIDFieldData(theReply);     
                        
                        break

                case 98:
                        // just put up a map with legend
                        var theURL = "";
                        theURL = getURL(theReply);
                        if (theURL != "") {
                                document.theImage.src = theURL;
                        }
                        if (legendVisible) {
                                showLegend();
                                drawLegendOnly=false;
                        }
                        hideRetrieveMap();
                        
                        break

                case 99:
                        // just put up a map
                        var theURL = "";
                        legendVisible=legendTemp;
                        theURL = getURL(theReply);
                        if (theURL != "") {
                                document.theImage.src = theURL;
                        }
                        else {
                                alert(msgList[14] + theReply);
                        }
                        hideRetrieveMap();
                        
                        break

                case 101:
                        // print - get Map image
                        printMapURL = getURL(theReply);
                        printLegURL = getLegendURL(theReply);
                        if (hasOVMap) {
                                getPrintOV();
                        } else {
                                getPrintLegend();
                        }
                        
                        break

                case 102:
                        // print - get OV image
                        printOVURL = getURL(theReply);
                        legendImage = printLegURL
                        getPrintLegend();
                        
                        break

                case 103:
                        // print - get Legend image
                        hideRetrieveMap();
                        writePrintPage();
                        break

                case 900:
                        // just make a map
                        var theURL = "";
                        theURL = getURL(theReply);
                        if (theURL != "") {
                                getXYs(theReply);
                                document.theImage.src = theURL;
                        }
                        
                        break


                case 902:
                        // just put up an overview map
                        var theURL = "";
                        theURL = getURL(theReply);
                        if (theURL != "") {
                                document.ovImage2.src = theURL; 
                        }
                        var tempLeft = fullLeft;
                        var tempRight = fullRight;
                        var tempTop = fullTop;
                        var tempBottom = fullBottom;
                        getOVXYs(theReply);
                        fullLeft = tempLeft;
                        fullRight = tempRight;
                        fullTop = tempTop;
                        fullBottom = tempBottom;
                        break
                
                case 998:
                        // receive serviceinfo for overview map to check decimal delimiter
                        var tempLeft = limitLeft;
                        var tempRight = limitRight;
                        var tempTop = limitTop;
                        var tempBottom = limitBottom;
                        getOVXYs(theReply);
                        limitLeft = tempLeft;
                        limitRight = tempRight;
                        limitTop = tempTop;
                        limitBottom = tempBottom;
                        var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_SERVICE_INFO renderer="false" extensions="false" fields="false" />\n';
                        theString = theString + '</REQUEST>\n</ARCXML>';
                        sendToServer(imsURL,theString,3);
                        break
                case 999:
                        // get a blank map to get modified limit extents according image proportions
                        var tempLeft = eLeft;
                        var tempRight = eRight;
                        var tempTop = eTop;
                        var tempBottom = eBottom;
                        getXYs(theReply);
                        imageLimitLeft=eLeft;
                        imageLimitRight=eRight;
                        imageLimitTop=eTop
                        imageLimitBottom=eBottom;
                        eLeft = tempLeft;
                        eRight = tempRight;
                        eTop = tempTop;
                        eBottom = tempBottom;
                        if ((aimsQueryPresent) && (highlightedOne!="") && (queryZoom)) {
                                setStartQuery();
                        } else {
                                sendMapXML();
                        }
                        
                        break

                default:
                        // send any responses to custom requests off to the custom handler
                                // XMLMode >= 1000 are reserved for custom requests/responses
                        if (XMLMode >= 1000) {
                                useCustomFunction(theReply);    
                        } else {
                                alert(theReply + msgList[19]);
                        }
                        
                }
                
}

// write out a blank map. . . to get image extents from limit extents
function writeBlankMapXML() {
        var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_IMAGE>\n<PROPERTIES>\n<ENVELOPE minx="' + forceComma(limitLeft) + '" miny="' + forceComma(limitBottom) + '" maxx="' + forceComma(limitRight) + '" maxy="' + forceComma(limitTop) + '" />\n';
        theString += '<IMAGESIZE height="' + iHeight + '" width="' + iWidth + '" />\n';
        var visString = "";
        // tell the server which layers are to be visible
        if (aimsLayersPresent) {
                theString += '<LAYERLIST >\n';
                for (var i=0;i<layerCount;i++) {
                        theString += '<LAYERDEF name="' + LayerName[i] + '" visible="false" />\n';
                        
                }
                theString += '</LAYERLIST>\n';
        }
        theString += '</PROPERTIES>\n';
        theString += '</GET_IMAGE>\n</REQUEST>\n</ARCXML>';
        sendToServer(imsURL,theString,999);

}


// prepare the request in xml format for Main Map
function writeXMLPrint() {
        var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_IMAGE>\n<PROPERTIES>\n<ENVELOPE minx="' + forceComma(eLeft) + '" miny="' + forceComma(eBottom) + '" maxx="' + forceComma(eRight) + '" maxy="' + forceComma(eTop) + '" />\n';
        theString += '<IMAGESIZE height="' + tempHeight + '" width="' + tempWidth + '" />\n';
        var visString = "";
        if (aimsLayersPresent) {
                // tell the server which layers are to be visible
                if (toggleVisible) {
                        theString += '<LAYERLIST >\n';
                        for (var i=0;i<layerCount;i++) {
                                if (LayerVisible[i]==1) {
                                        theString += '<LAYERDEF id="' + LayerID[i] + '" visible="true" ';
                                        if (aimsClassRenderPresent) {
                                                theString += addSpecialRenderToMap(i);
                                        } else {
                                                theString += '/>\n';
                                        }
                                        
                                }
                                else {
                                        theString += '<LAYERDEF id="' + LayerID[i] + '" visible="false" />\n';
                                }
                                
                        }
                        theString += '</LAYERLIST>\n';
                }
        }
        
        // map background color
        if (mapTransparent) {
                theString += '<BACKGROUND color="255,255,254" transcolor="255,255,254" />\n';
        } else {
                if (mapBackColor!="") {
                        theString += '<BACKGROUND color="' + mapBackColor + '" />\n\n';
                }
        }
        if (aimsLegendPresent) {
                // create a legend image
                if (legendVisible) theString += addLegendToMap();
        }
        
        theString += '</PROPERTIES>\n';
        
        // buffer
        if (aimsBufferPresent) {
                if (showBuffer) theString += addBufferToMap();
        }
        
        // select
        if (aimsSelectPresent) {
                theString += addSelectToMap();
        }       
        
        // any custom stuff to fit here
        if (aimsCustomPresent) theString += addCustomToMap1();
        
        
        if (aimsClickPresent){
                // clickpoints 
                if (clickCount>0) {
                        // draw click points and lines between them on map
                        var clickColor = selectColor;
                        if (clickType==1) clickColor = clickMarkerColor;
                        theString += '<LAYER type="acetate" name="allTheClicks">\n';
                        if (clickCount>1) {
                                theString += '<OBJECT units="database">\n<LINE coords="' + forceComma(clickPointX[0]) + coordsDelimiter + forceComma(clickPointY[0]);
                                for (var i=1;i<clickCount;i++) {
                                        theString += pairsDelimiter  + forceComma(clickPointX[i]) + coordsDelimiter + forceComma(clickPointY[i]); 
                                }
                                theString += '" >\n';
                                theString += '<SIMPLELINESYMBOL type="solid" color="' + clickMarkerColor;
                                theString += '" width="3" />\n</LINE>\n</OBJECT>\n'; 
                                theString += '<OBJECT units="database">\n<LINE coords="' + forceComma(clickPointX[0]) + coordsDelimiter + forceComma(clickPointY[0]);
                                for (var i=1;i<clickCount;i++) {
                                        theString += pairsDelimiter  + forceComma(clickPointX[i]) + coordsDelimiter + forceComma(clickPointY[i]); 
                                }
                                theString += '" >\n';
                                theString += '<SIMPLELINESYMBOL type="solid" color="255,255,255" width="1" />\n</LINE>\n</OBJECT>\n'; 
                        }
                        for (var i=0;i<clickCount;i++) {
                                theString += '<OBJECT units="acetate">\n<POINT coords="' + forceComma(clickPointX[i]) + coordsDelimiter + forceComma(clickPointY[i]) + '">\n';
                                theString += '<SIMPLEMARKERSYMBOL  type="' + clickMarkerType + '"';
                                theString += ' color="' + clickMarkerColor + '" width="' + clickMarkerSize + '" />\n</POINT>\n</OBJECT>\n';
                        }
                        theString += '</LAYER>\n';
                }
        }
        
        // geocoding or point with label
        if (showGeocode) {
                // draw the point . . . also used to display any point with a label on map
                theString += '<LAYER type="acetate" name="GeoCode1">\n';
                theString += '<OBJECT units="database">\n<POINT coords="' + forceComma(geocodeX) + coordsDelimiter + forceComma(geocodeY) + '">\n';
                theString += '<SIMPLEMARKERSYMBOL  type="circle"  color="' + geocodePointColor + '" width="' + geocodePointSize +'" overlap="false" />\n</POINT></OBJECT>\n';
                if (geocodeLabel!="") {
                        theString += '<OBJECT units="database">\n<TEXT coords="' + forceComma(geocodeX) + coordsDelimiter + forceComma(geocodeY) + '" label="' + geocodeLabel + '">\n';
                        theString += '<TEXTMARKERSYMBOL fontcolor="' + geocodePointColor + '" fontsize="12" shadow="64,64,64" glowing="255,255,0" halignment="right" valignment="top" overlap="false" /></TEXT></OBJECT>\n';
                }
                theString += '</LAYER>\n';
                
        }
        
        // any custom stuff to fit here
        if (aimsCustomPresent) theString += addCustomToMap2();

        if (drawCopyright) {
                // draw text on the map
                theString += '<LAYER type="acetate" name="theCopyright">\n';            
                theString += '<OBJECT units="pixel">\n<TEXT coords="' + CopyrightCoords + '" label="' + CopyrightText + '">\n';
                theString += '<TEXTMARKERSYMBOL fontstyle="' + CopyrightStyle + '" fontsize="' + CopyrightSize + '" ';
                theString += 'font="' + CopyrightFont + '" fontcolor="' + CopyrightColor + '" antialiasing="True" ';
                if (CopyrightBackground.toUpperCase()=="TRUE") theString += 'blockout="' + CopyrightBGColor + '" ';
                theString += 'shadow="32,32,32" overlap="false" ';
                if (CopyrightGlow.toUpperCase()=="TRUE") theString += ' glowing="' + CopyrightGlowColor + '" ';
                theString += '/>\n</TEXT>\n</OBJECT>\n';
                theString += '</LAYER>\n';
        }
        if (drawNorthArrow) {
                // draw a north arrow
                theString += '<LAYER type="acetate" name="theNorthArrow">\n';
                theString += '<OBJECT units="pixel">\n<NORTHARROW type="' + NorthArrowType + '" size="' + NorthArrowSize + '" coords="' + NorthArrowCoords + '" shadow="32,32,32" ';
                theString += 'angle="' + NorthArrowAngle + '" antialiasing="True" overlap="False" />\n</OBJECT>\n';
                theString += '</LAYER>\n';
        }
        if (drawScaleBar) {
                // draw a scale bar
                theString += '<LAYER type="acetate" name="theScaleBar">\n';
                xDistance = eRight - eLeft;
                theString += '<OBJECT units="pixel">\n';
                theString += '<SCALEBAR coords="' + parseInt(tempWidth * (6/10)) + coordsDelimiter + '2" ';
                if (MapUnits=="DEGREES") theString += 'mode="geodesic" ';
                ///*
                theString += 'outline="' + ScaleBarBackColor + '" ';
                theString += 'font="' + ScaleBarFont + '" fontcolor="' + ScaleBarFontColor + '" style="' + ScaleBarStyle + '" barcolor="' + ScaleBarColor + '" ';
                if (MapUnits!="DEGREES") {
                        theString += 'mapunits="' + MapUnits.toLowerCase() + '" ';
                }
                theString += 'scaleunits="' + ScaleBarUnits.toLowerCase() + '" antialiasing="True" ';
                var sDistance = getScaleBarDistance();
                if (MapUnits=="DEGREES") {
                        if (xDistance<1/10){
                                theString += 'precision="' + ScaleBarPrecision + '" ';
                        }
                } else if (sDistance<5) {
                        theString += 'precision="' + ScaleBarPrecision + '" ';
                }
                theString += 'screenlength="' + parseInt(tempWidth * (2/10)) + '" ';
                theString += 'fontsize="' + ScaleBarSize + '" barwidth="' + ScaleBarWidth + '" overlap="False"  ';
                theString += '/>\n</OBJECT>\n';
                theString += '</LAYER>\n';      
                
        }
        
        // any custom stuff to fit here
        if (aimsCustomPresent) theString += addCustomToMap3();

        if (drawModeOnMap) {
                // draw the current mode on the map
                theString += '<LAYER type="acetate" name="theMode">\n';
                theString += '<OBJECT units="pixel">\n<TEXT coords="5' + coordsDelimiter + (tempHeight-10) + '" label="' + modeBlurb + '">\n';
                theString += '<TEXTMARKERSYMBOL fontstyle="BOLD" fontsize="12" font="ARIAL" fontcolor="' + modeMapColor + '" ';
                theString += 'threed="TRUE" glowing="' + modeMapGlow + '" overlap="false" />\n</TEXT>\n</OBJECT>';
        
        }
        
        // any custom stuff to be drawn on top of everything
        if (aimsCustomPresent) theString += addCustomToMap4();

        theString += '</GET_IMAGE>\n</REQUEST>\n</ARCXML>';
        return theString;
}

// prepare the request in xml format for Main Map
function writeXML() {
        var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_IMAGE>\n<PROPERTIES>\n<ENVELOPE minx="' + forceComma(eLeft) + '" miny="' + forceComma(eBottom) + '" maxx="' + forceComma(eRight) + '" maxy="' + forceComma(eTop) + '" />\n';
        theString += '<IMAGESIZE height="' + iHeight + '" width="' + iWidth + '" />\n';
        var visString = "";
        if (aimsLayersPresent) {
                // tell the server which layers are to be visible
                if (toggleVisible) {
                        theString += '<LAYERLIST >\n';
                        for (var i=0;i<layerCount;i++) {
                                if (LayerVisible[i]==1) {
                                        theString += '<LAYERDEF id="' + LayerID[i] + '" visible="true" ';
                                        if (aimsClassRenderPresent) {
                                                theString += addSpecialRenderToMap(i);
                                        } else {
                                                theString += '/>\n';
                                        }
                                        
                                }
                                else {
                                        theString += '<LAYERDEF id="' + LayerID[i] + '" visible="false" />\n';
                                }
                                
                        }
                        theString += '</LAYERLIST>\n';
                }
        }
        
        // map background color
        if (mapTransparent) {
                theString += '<BACKGROUND color="255,255,254" transcolor="255,255,254" />\n';
        } else {
                if (mapBackColor!="") {
                        theString += '<BACKGROUND color="' + mapBackColor + '" />\n\n';
                }
        }
        if (aimsLegendPresent) {
                // create a legend image
                if (legendVisible) theString += addLegendToMap();
        }
        
        theString += '</PROPERTIES>\n';
        
        // buffer
        if (aimsBufferPresent) {
                if (showBuffer) theString += addBufferToMap();
        }
        
        // select
        if (aimsSelectPresent) {
                theString += addSelectToMap();
        }       
        
        // any custom stuff to fit here
        if (aimsCustomPresent) theString += addCustomToMap1();
        
        
        if (aimsClickPresent){
                // clickpoints 
                if (clickCount>0) {
                        // draw click points and lines between them on map
                        var clickColor = selectColor;
                        if (clickType==1) clickColor = clickMarkerColor;
                        theString += '<LAYER type="acetate" name="allTheClicks">\n';
                        if (clickCount>1) {
                                theString += '<OBJECT units="database">\n<LINE coords="' + forceComma(clickPointX[0]) + coordsDelimiter + forceComma(clickPointY[0]);
                                for (var i=1;i<clickCount;i++) {
                                        theString += pairsDelimiter  + forceComma(clickPointX[i]) + coordsDelimiter + forceComma(clickPointY[i]); 
                                }
                                theString += '" >\n';
                                theString += '<SIMPLELINESYMBOL type="solid" color="' + clickMarkerColor;
                                theString += '" width="3" />\n</LINE>\n</OBJECT>\n'; 
                                theString += '<OBJECT units="database">\n<LINE coords="' + forceComma(clickPointX[0]) + coordsDelimiter + forceComma(clickPointY[0]);
                                for (var i=1;i<clickCount;i++) {
                                        theString += pairsDelimiter  + forceComma(clickPointX[i]) + coordsDelimiter + forceComma(clickPointY[i]); 
                                }
                                theString += '" >\n';
                                theString += '<SIMPLELINESYMBOL type="solid" color="255,255,255" width="1" />\n</LINE>\n</OBJECT>\n'; 
                        }
                        for (var i=0;i<clickCount;i++) {
                                theString += '<OBJECT units="acetate">\n<POINT coords="' + forceComma(clickPointX[i]) + coordsDelimiter + forceComma(clickPointY[i]) + '">\n';
                                theString += '<SIMPLEMARKERSYMBOL  type="' + clickMarkerType + '"';
                                theString += ' color="' + clickMarkerColor + '" width="' + clickMarkerSize + '" />\n</POINT>\n</OBJECT>\n';
                        }
                        theString += '</LAYER>\n';
                }
        }
        
        // geocoding or point with label
        if (showGeocode) {
                // draw the point . . . also used to display any point with a label on map
                theString += '<LAYER type="acetate" name="GeoCode1">\n';
                theString += '<OBJECT units="database">\n<POINT coords="' + forceComma(geocodeX) + coordsDelimiter + forceComma(geocodeY) + '">\n';
                //theString += '<SIMPLEMARKERSYMBOL  type="circle"  color="' + geocodePointColor + '" width="' + geocodePointSize +'" overlap="false" />\n</POINT></OBJECT>\n';
                theString += '<SIMPLEMARKERSYMBOL  type="star"  color="' + geocodePointColor + '" width="' + geocodePointSize +'" overlap="false" />\n</POINT></OBJECT>\n';
                if (geocodeLabel!="") {
                        theString += '<OBJECT units="database">\n<TEXT coords="' + forceComma(geocodeX) + coordsDelimiter + forceComma(geocodeY) + '" label="' + geocodeLabel + '">\n';
                        theString += '<TEXTMARKERSYMBOL fontcolor="' + geocodePointColor + '" fontsize="12" shadow="64,64,64" glowing="255,255,0" halignment="right" valignment="top" overlap="false" /></TEXT></OBJECT>\n';
                }
                theString += '</LAYER>\n';
                
        }
        
        // any custom stuff to fit here
        if (aimsCustomPresent) theString += addCustomToMap2();

        if (drawCopyright) {
                // draw text on the map
                theString += '<LAYER type="acetate" name="theCopyright">\n';            
                theString += '<OBJECT units="pixel">\n<TEXT coords="' + CopyrightCoords + '" label="' + CopyrightText + '">\n';
                theString += '<TEXTMARKERSYMBOL fontstyle="' + CopyrightStyle + '" fontsize="' + CopyrightSize + '" ';
                theString += 'font="' + CopyrightFont + '" fontcolor="' + CopyrightColor + '" antialiasing="True" ';
                if (CopyrightBackground.toUpperCase()=="TRUE") theString += 'blockout="' + CopyrightBGColor + '" ';
                theString += 'shadow="32,32,32" overlap="false" ';
                if (CopyrightGlow.toUpperCase()=="TRUE") theString += ' glowing="' + CopyrightGlowColor + '" ';
                theString += '/>\n</TEXT>\n</OBJECT>\n';
                theString += '</LAYER>\n';
        }
        if (drawNorthArrow) {
                // draw a north arrow
                theString += '<LAYER type="acetate" name="theNorthArrow">\n';
                theString += '<OBJECT units="pixel">\n<NORTHARROW type="' + NorthArrowType + '" size="' + NorthArrowSize + '" coords="' + NorthArrowCoords + '" shadow="32,32,32" ';
                theString += 'angle="' + NorthArrowAngle + '" antialiasing="True" overlap="False" />\n</OBJECT>\n';
                theString += '</LAYER>\n';
        }
        if (drawScaleBar) {
                // draw a scale bar
                theString += '<LAYER type="acetate" name="theScaleBar">\n';
                xDistance = eRight - eLeft;
                theString += '<OBJECT units="pixel">\n';
                theString += '<SCALEBAR coords="' + parseInt(iWidth * (6/10)) + coordsDelimiter + '2" ';
                if (MapUnits=="DEGREES") theString += 'mode="geodesic" ';
                ///*
                theString += 'outline="' + ScaleBarBackColor + '" ';
                theString += 'font="' + ScaleBarFont + '" fontcolor="' + ScaleBarFontColor + '" style="' + ScaleBarStyle + '" barcolor="' + ScaleBarColor + '" ';
                if (MapUnits!="DEGREES") {
                        theString += 'mapunits="' + MapUnits.toLowerCase() + '" ';
                }
                theString += 'scaleunits="' + ScaleBarUnits.toLowerCase() + '" antialiasing="True" ';
                var sDistance = getScaleBarDistance();
                if (MapUnits=="DEGREES") {
                        if (xDistance<1/10){
                                theString += 'precision="' + ScaleBarPrecision + '" ';
                        }
                } else if (sDistance<5) {
                        theString += 'precision="' + ScaleBarPrecision + '" ';
                }
                theString += 'screenlength="' + parseInt(iWidth * (2/10)) + '" ';
                theString += 'fontsize="' + ScaleBarSize + '" barwidth="' + ScaleBarWidth + '" overlap="False"  ';
                theString += '/>\n</OBJECT>\n';
                theString += '</LAYER>\n';      
                
        }
        
        // any custom stuff to fit here
        if (aimsCustomPresent) theString += addCustomToMap3();

        if (drawModeOnMap) {
                // draw the current mode on the map
                theString += '<LAYER type="acetate" name="theMode">\n';
                theString += '<OBJECT units="pixel">\n<TEXT coords="5' + coordsDelimiter + (iHeight-10) + '" label="' + modeBlurb + '">\n';
                theString += '<TEXTMARKERSYMBOL fontstyle="BOLD" fontsize="12" font="ARIAL" fontcolor="' + modeMapColor + '" ';
                theString += 'threed="TRUE" glowing="' + modeMapGlow + '" overlap="false" />\n</TEXT>\n</OBJECT>';
        
        }
        
        // any custom stuff to be drawn on top of everything
        if (aimsCustomPresent) theString += addCustomToMap4();

        theString += '</GET_IMAGE>\n</REQUEST>\n</ARCXML>';
        return theString;
}

// prepare the request in xml format for overview map
function writeOVXML() {
        var extentRatio = xDistance/fullWidth;
        var midX = eLeft + xHalf;
        var midY = eBottom + yHalf;
        var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_IMAGE><PROPERTIES>\n';
        theString += '<ENVELOPE minx="' + forceOVComma(fullOVLeft) + '" miny="' + forceOVComma(fullOVBottom) + '" maxx="' + forceOVComma(fullOVRight) + '" maxy="' + forceOVComma(fullOVTop) + '" />\n';
        theString += '<IMAGESIZE height="' + i2Height + '" width="' + i2Width + '" />\n';
        if ((toggleOVVisible) && (imsURL==imsOVURL)) {
                theString += '<LAYERLIST >\n';
                for (var i=0;i<layerCount;i++) {
                        if (LayerVisible[i]==1) {
                                visString = "true";
                        }
                        else {
                                visString = "false";
                        }
                        theString += '<LAYERDEF name="' + LayerName[i] + '" visible="' + visString + '" />\n';
                        
                }
                theString += '</LAYERLIST>\n';
        }
        if (mapBackColor!="") {
                theString += '<BACKGROUND color="' + mapBackColor + '" />\n';
        }
        
        theString += '</PROPERTIES>\n';
        if (drawOVExtentBox) {
                theString += '<LAYER type="acetate" name="ACETATE">\n';
                if (extentRatio<(1/100)) {
                        theString += '<OBJECT units="database">\n<POINT coords="' + forceOVComma(midX) + coordsDelimiter + forceOVComma(midY) + '">\n';
                        theString += '<SIMPLEMARKERSYMBOL  type="Square" color="' + ovBoxColor + '" width="4" />\n</POINT></OBJECT>\n';
                } else {
                        theString += '<OBJECT units="database">\n<LINE coords="' + forceOVComma(eLeft) + coordsDelimiter + forceOVComma(eBottom) + pairsDelimiter + forceOVComma(eLeft) + coordsDelimiter + forceOVComma(eTop) + pairsDelimiter;
                        theString += forceOVComma(eRight) + coordsDelimiter + forceOVComma(eTop) + pairsDelimiter + forceOVComma(eRight) + coordsDelimiter + forceOVComma(eBottom) + pairsDelimiter + forceOVComma(eLeft) + coordsDelimiter + forceOVComma(eBottom) + '">\n';
                        theString += '<SIMPLELINESYMBOL type="solid" color="' + ovBoxColor + '" width="3" />\n</LINE></OBJECT>\n';
                }
                theString += '</LAYER>\n';
        }
        theString += '</GET_IMAGE>\n</REQUEST>\n</ARCXML>';
        return theString;
}

// get the map extents from xml reply
function getXYs(theString) {
        var tempStr = "";
        var smallStr = "";
        var startpos = 0;
        var endpos = 0;
        var theReply = theString
        var theXYs =  getEnvelopeXYs(theString, 0)
        eLeft = theXYs[0];
        eBottom = theXYs[1];
        eRight = theXYs[2];
        eTop = theXYs[3];
        xDistance = Math.abs(eRight-eLeft);
        yDistance = Math.abs(eTop-eBottom);
        xHalf = xDistance / 2;
        yHalf = yDistance / 2;
        panX = xDistance * panFactor;
        panY = yDistance * panFactor;
        var sFactor = xDistance / iWidth
        if (aimsLayersPresent) {
                if (sFactor!=mapScaleFactor) {
                        mapScaleFactor = sFactor;
                        //alert("getXYs ds aimsXML.js" + "\nhasTOC:  " + hasTOC + "\nlegendVisible:  " + legendVisible + "\ntpTOC:  " + tpTOC);
                        if ((hasTOC) && (!legendVisible)) parent.TOC2Frame.TOCFrame.document.location = appDir + "toc.htm";
                        if ((hasTOC) && (!legendVisible) && (tpTOC)) parent.TOC2Frame.TOCTemp.document.location = appDir + "toc.htm";
                        if (aimsLayersPresent) {
                                if (LayerListOpen) writeLayerListForm();
                        }
                        
                } 
        }
}


// get the map extents from xml reply
function getOVXYs(theString) {
        var tempStr = "";
        var smallStr = "";
        var startpos = 0;
        var endpos = 0;
        var tempComma = forceCommaInRequest[activeMapServiceIndex];
        var theXYs =  getEnvelopeXYs(theString, 0)
        forceCommaInOV = forceCommaInRequest[activeMapServiceIndex];
        forceCommaInRequest[activeMapServiceIndex] = tempComma;
        fullOVLeft = theXYs[0];
        fullOVBottom = theXYs[1];
        fullOVRight = theXYs[2];
        fullOVTop = theXYs[3];
        fullOVWidth = Math.abs(fullOVRight - fullOVLeft);
        fullOVHeight = Math.abs(fullOVTop - fullOVBottom);
}

// get URL
function getURL(theReply) {
        var theURL = "";
        var startpos = 0;
        var endpos = 0;

        var pos = theReply.indexOf("OUTPUT");
        if (pos != -1) {
                theURL = getInsideString(theReply,'url="',dQuote,pos,0,false);
        }
        legendImage = getLegendURL(theReply);
        return theURL;

}


// getLegendURL
function getLegendURL(theReply) {
        var theURL = "";
        var startpos = 0;
        var endpos = 0;
        var pos = theReply.indexOf("LEGEND");
        if (pos != -1) {
                theURL = getInsideString(theReply,'url="',dQuote,pos,0,false);
        }
        return theURL;

}

// just make a map with URL and  extent
function justGetMap(theURL, extentLeft, extentTop, extentRight, extentBottom, getOVMap) {
        var mode = 900;
        if (getOVMap) mode = 1;
        if (extentLeft!="") eLeft = extentLeft;
        if (extentTop!="") eTop = extentTop
        if (extentRight!="") eRight = extentRight;
        if (extentBottom!="") eBottom = extentBottom;
        var theText = writeXML();
        if (debugOn==2) alert(msgList[12] + theText);   
        sendToServer(theURL,theText,mode);
        
}

// get min and max x,y's from xml stream . . . return an array with values
function getEnvelopeXYs(theString, startpos) {
        var theEnvelope = new Array();
        theString = theString.toUpperCase();
        var tempString = "";
        var pos = theString.indexOf("ENVELOPE",startpos);
        if (pos!=-1) {
                pos = pos + 8;
                startpos = theString.indexOf("MINX=",pos);
                startpos += 6;
                var endpos = theString.indexOf(dQuote,startpos);
                tempString = theString.substring(startpos,endpos);
                theEnvelope[0] = parseFloat(setDecimalString(tempString)); 
                startpos = theString.indexOf("MINY=",pos);
                startpos += 6;
                endpos = theString.indexOf(dQuote,startpos);
                tempString = theString.substring(startpos,endpos);
                theEnvelope[1] = parseFloat(setDecimalString(tempString)); 
                startpos = theString.indexOf("MAXX=",pos);
                startpos += 6;
                endpos = theString.indexOf(dQuote,startpos);
                tempString = theString.substring(startpos,endpos);
                theEnvelope[2] = parseFloat(setDecimalString(tempString)); 
                startpos = theString.indexOf("MAXY=",pos);
                startpos += 6;
                endpos = theString.indexOf(dQuote,startpos);
                tempString = theString.substring(startpos,endpos);
                theEnvelope[3] = parseFloat(setDecimalString(tempString)); 
                xmlEndPos = endpos;
        }
        return theEnvelope;

}

// set number string to have decimal character to match browser language type - point or comma
function setDecimalString(numberString) {
        if (numberString.indexOf(",")!=-1) forceCommaInRequest[activeMapServiceIndex] = true;
        if (decimalChar==".") {
                numberString = numberString.replace(/,/g, ".");
        } else {
                numberString = numberString.replace(/./g, ",");
        }
        return numberString;
}

function forceComma(theNumber) {
        var comma = ",";
        var dot = ".";
        var charOut = comma;
        var charIn = dot;
        var numberString = new String(theNumber);
        if (forceCommaInRequest[activeMapServiceIndex]) {
                charOut = dot;
                charIn = comma;
        }
        var pos = numberString.indexOf(charOut);
        if (pos!=-1) {
                var begin = numberString.substring(0,pos);
                var ending = numberString.substring(pos+1, numberString.length);
                numberString = begin + charIn + ending;
        }
        return numberString;
}
function forceOVComma(theNumber) {
        var comma = ",";
        var dot = ".";
        var charOut = comma;
        var charIn = dot;
        var numberString = new String(theNumber);
        if (forceCommaInOV) {
                charOut = dot;
                charIn = comma;
        }
        var pos = numberString.indexOf(charOut);
        if (pos!=-1) {
                var begin = numberString.substring(0,pos);
                var ending = numberString.substring(pos+1, numberString.length);
                numberString = begin + charIn + ending;
        }
        return numberString;
}

// check if there is an error message in the response
function getXMLErrorMessage(theString) {
        var pos1 = 0;
        var pos2 = 0;
        var pos3 = 0;
        var theError = "";
        pos3 = theString.indexOf("<ERROR");
        if (pos3!=-1) {
                pos1 = theString.indexOf(">",pos3);
                pos1 += 1;
                pos2 = theString.indexOf("</ERROR");
                theError = theString.substring(pos1,pos2)
        }
        return theError;

}

// check if theURL has different host from theHost
function isNotSameHostInURL(theURL, theHost) {
        var startpos = theURL.indexOf("//");
        if (startpos==-1) {
                startpos = 0;
        } else {
                startpos = startpos + 2;
        }
        var endpos = theURL.indexOf("/",startpos);
        if (endpos==-1) endpos = theURL.length;
        var thisHost = theURL.substring(startpos,endpos);
        if (thisHost==theHost) {
                return false;
        } else {
                return true;
        }
}
