// aimsMultiService.js
/*
*  JavaScript template file for ArcIMS HTML Viewer Multiple MapService Sample
*		dependent on aimsXML.js, ArcIMSparam.js, aimsCommon.js, aimsMap.js, aimsIdentify.js, aimsSelect.js, and aimsLayers.js
*		To be interactive, dependent also on aimsDHTML.js, aimsClick.js, and aimsNavigation.js
*
*		Assumes that the limit and start extents have been set.
*		Dependent on aimsMultiServiceParam.js
*/

aimsMultiService=true;
	// the main URL for accessing servlet connector extension - default is imsURL value
var baseMapServiceURL = imsURL;
	// maximum number of MapServices that can be loaded together - if more, define more style sheets in MapFrame.htm
var maxNumberMapServices = 10;
	// array for URLs of the MapSrvices. Define in aimsMultiServiceParam.js.
var mapServiceList = new Array();
	// array for descriptive names of the MapServices. Define in aimsMultiServiceParam.js.
var mapServiceName = new Array();
	// array for current visibility of the MapServices. Define in aimsMultiServiceParam.js.
var mapServiceVisible = new Array();
	// array for layer ids for each MapService 
		// string of id for each layer
		// delimited by bars ("|"). Automatically defined by viewer from mapservice info
var mapServiceLayers = new Array();
	// array for layer visibility for each MapService 
		// string of 1's (visible) or 0's (invisible) for each layer
		// delimited by bars ("|"). Automatically defined by viewer from mapservice info
var mapServiceLayersVisible = new Array();
	// definition for first element in the above arrays.  Change or define additional in aimsMultiServiceParam.js.
mapServiceList[0] = imsURL; //zero index starts with imsURL
mapServiceName[0] = "Assessor's Office";
mapServiceVisible[0] = 1; // visible

	// number of defined MapServices. Automatically defined by viewer.
var mapServiceCount = mapServiceList.length;
	// URL of current active MapService - Modify in aimsMultiServiceParam.js
var activeMapService = mapServiceList[0]; //assumes that there is a mapServiceList[0]
	// index of current active MapService - Modify in aimsMultiServiceParam.js
activeMapServiceIndex = 0;

	// list of hosts allowed to access. Delimited by commas (",").
		// The names listed should correspond with names defined in esrimap_prop for redirection
		// Set in aimsMultiServiceParam.js 
var availableHostsList = "";
	// array for available hosts. Automatically defined by viewer from availableHostsList string.
var availableHosts = new Array();

	// current overlay index to be plotted
var overlayIndex = 0;

	// able to add or delete mapservices - Modify in aimsMultiServiceParam.js
var canManageMapServices=true

imsURL = mapServiceList[0];
imsQueryURL= imsURL + "&CustomService=Query";
imsGeocodeURL = imsURL + "&CustomService=Geocode";

var serviceCount = 0;
var ServiceName = new Array();
var serviceImageType = new Array();
var newServiceName = "";
var serviceHost = hostName;

	// set field display to generic
selectFields= "#ALL#";
swapSelectFields=true;
useFieldAlias=true;
canLoad=true;
	// update maps when change of active mapservice?
var updateMaps=false;
var tempcVersion = "";


// send the created xml request to map server
	// this replaces the default sendMapXML() in aimsXML.js
function sendMapXML() {
	// ask for the Main map
	showRetrieveMap();
	updateMaps=false;
	overlayIndex=0;
	var theText = "";
	theText = writeXML();
	hideLayer("theMap");
	for (i=1;i<mapServiceCount;i++) {
		var lyrName = "theMap" + i;
		hideLayer(lyrName);
	}
	if (debugOn==2) alert(msgList[12] + theText);
	
	sendMultiToServer(mapServiceList[0],theText,"parent.MapFrame.processMulti",5001);

}

function sendMultiToServer(theURL, XMLRequest, theFunction, theType) {
	var theForm = parent.PostFrame.document.forms[0];
	theForm.JavaScriptFunction.value = theFunction;
	sendToServer(theURL,XMLRequest,theType)

}

function processMulti(theReplyIn) {
	theReplyIn = replacePlus(theReplyIn);
	var theReply = unescape(theReplyIn);
	//alert(theReply);
	okToSend = true;
	if (debugOn>2) alert(msgList[13] + theReply);
	var theError = getXMLErrorMessage(theReply);
	switch(XMLMode) {
		case 5001:
			//alert("XMLMode=5001\n" + theReply);
			// get the map image
			updateMultiOverlay(theReply, theError);
			break
		
		case 5002:
			//alert("XMLMode=5002");
			// get the layers in the MapServices
			processStartMapServiceLayers(theReply);
			break
			
		case 5003:
			processSwithchActiveMapService(theReply);
			break
		
		case 5004:
			processAddMapServiceLayers(theReply);
			break
		
		case 5005:
			processTopMap(theReply);
		
			break	
		default:
			alert(theReply + msgList[19]);
			
	}

}

function updateMultiOverlay(theReply, theError) {
	//if (theReply!="") {
		//alert ("Received:\n\n" + theReply);
		var theURL = "";
		theURL = getURL(theReply);	
		//alert(theURL);
		var lyrName = "theMap";
		if (overlayIndex>0) lyrName = "theMap" + overlayIndex;
		hideLayer(lyrName);
		if (theURL != "") {
			getXYs(theReply);
			if (overlayIndex==0) {
				document.theImage.src = theURL;
			} else {
				eval("document.theImage" + overlayIndex + ".src = '" + theURL + "'");
			}
			if (mapServiceVisible[overlayIndex]==1) showLayer(lyrName);
		} else {
			if (debugOn>0) {
				alert(msgList[14] + "\n" + theReply);
			} else {
				alert(msgList[14] + theError);
			}
		}
		if (toolMode==3) {
			moveLayer(lyrName,hspc,vspc);
			clipLayer2(lyrName,0,0,iWidth,iHeight);
		}
		if ((legendVisible) && (overlayIndex==parseInt(activeMapServiceIndex))) {
			showLegend();
		}
	//}
	overlayIndex++;
	if (overlayIndex<mapServiceList.length) {
		//if (parseInt(mapServiceVisible[overlayIndex])==1)
			theText = writeXML();
			sendMultiToServer(mapServiceList[overlayIndex],theText,"parent.MapFrame.processMulti",5001);
		//} else {
		//	updateMultiOverlay("");
		//}
		
	} 
	else {
		if (toolMode==3) {
			if (hasLayer("theMapClicks")) {
				moveLayer("theMapClicks",hspc,vspc);
				clipLayer2("theMapClicks",0,0,iWidth,iHeight);
		
			}
		}
		
		
		if (hasOVMap) {
			if (ovIsVisible) {
			// ask for the overview
				if (!pastStart) {
					
					theText = writeOVXML();
					//pastStart=true;
					sendToServer(imsOVURL,theText,2);
				} else {
					putExtentOnOVMap();
					hideRetrieveMap();
				}
			} else {
				if (!pastStart) {
					theText = writeOVXML();
					sendToServer(imsOVURL,theText,2);
				} else {
					hideRetrieveMap();
				}
			
			}
		} else {
	
			hideRetrieveMap();
		}
		if (parent.ServiceFrame!=null) {
			parent.ServiceFrame.document.location = appDir + "MapServices.htm";
		}
	}


}

function processTopMap(theReply) {
	var theURL = "";
	theURL = getURL(theReply);	
	alert(theReply);
	var theError = getXMLErrorMessage(theReply);		
	//alert(theURL);
	var lyrName = "theTopMap";
	showLayer(lyrName);
	if (theURL != "") {
		document.theTopImage.src = theURL;
		showLayer(lyrName);
	} else {
		if (debugOn>0) {
			alert(msgList[14] + "\n" + theReply);
		} else {
			alert(msgList[14] + theError);
		}
	}
	if (hasOVMap) {
		if (ovIsVisible) {
		// ask for the overview
			if (!pastStart) {
				
				theText = writeOVXML();
				//pastStart=true;
				sendToServer(imsOVURL,theText,2);
			} else {
				putExtentOnOVMap();
				hideRetrieveMap();
			}
		} else {
			if (!pastStart) {
				theText = writeOVXML();
				sendToServer(imsOVURL,theText,2);
			} else {
				hideRetrieveMap();
			}
		
		}
	} else {

		hideRetrieveMap();
	}
	if (parent.ServiceFrame!=null) {
		parent.ServiceFrame.document.location = appDir + "MapServices.htm";
	}

}

// get the starting extent
	// this replaces the default getStartExtent() in aimsCommon.js
function getStartExtent() {
	if (parent.PostFrame.document.forms[0]!=null) {
		overlayIndex=0;
		var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_SERVICE_INFO renderer="false" extensions="false" fields="false" />\n</REQUEST>\n</ARCXML>\n';
		sendMultiToServer(imsURL,theString,"parent.MapFrame.processMulti",5002);
	}

}
// get the starting extent
	// the original getStartExtent() - run after the replacement function is done
function getStartExtent2() {
	if (parent.PostFrame.document.forms[0]!=null) {
		var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_SERVICE_INFO renderer="false" extensions="false" fields="false" />\n';
		theString = theString + '</REQUEST>\n</ARCXML>';
		var theReply="";
		if (hasOVMap) {
			theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_IMAGE><PROPERTIES>\n';
			theString += '<IMAGESIZE height="' + i2Height + '" width="' + i2Width + '" />\n';
			if (mapBackColor!="") {
				theString += '<BACKGROUND color="' + mapBackColor + '" />\n';
			}
			theString += '</PROPERTIES>\n';
			theString += '</GET_IMAGE>\n</REQUEST>\n</ARCXML>';
			sendToServer(imsOVURL,theString,902);
		} else {
				sendToServer(imsURL,theString,3);
		}
	} else {
		alert(msgList[2]);
	}
}



// get list of layers, id/shape fields, scalefactors, etc.
function getLayerIDs(theReply) {
	//alert("LayerInfo:\n" + theReply.length);
	var theReplyUC = theReply.toUpperCase();
	var startpos = 0;
	var endpos = 0;
	var pos = -1;
	var lpos = 1;
	var epos = 1;
	var zpos=1;
	var zpos2 = 1;
	var tempString="";
	var visString = "";
	var theString = "";
	var theCount = 0;
	var tempArray = new Array();
	//alert("Processing LayerInfo");
	lpos = theReplyUC.indexOf("<LAYERINFO",zpos);

	while (lpos > -1) {
		//alert("<LAYERINFO - pos " + lpos );
		
		if (lpos != -1) {
			
			zpos = theReplyUC.indexOf("</LAYERINFO",lpos);
			//alert("</LAYERINFO - pos " +  zpos);
			if (zpos!=-1) {
				pos = theReplyUC.indexOf("NAME=",lpos);
				if (pos != -1) {
					startpos = pos + 6;
					endpos = theReply.indexOf(dQuote, startpos);
					tempString = theReply.substring(startpos,endpos);
					startpos = theReplyUC.indexOf("ID=",lpos);
					if ((startpos != -1) && (startpos<zpos)) {
						startpos = startpos + 4;
						endpos = theReply.indexOf(dQuote, startpos);
						tempArray[theCount] = theReply.substring(startpos,endpos);
					} else {
						tempArray[theCount] = tempString;
					}
					theCount++;
					endpos = zpos;
					
				}
				lpos = theReplyUC.indexOf("<LAYERINFO",zpos);
			} else {
				lpos = -1;
			}
			
		}
	}
	//alert("LayerInfo processed");
	tempArray.reverse();
	theString = tempArray.join("|");
	
	theReplyUC="";
	tempArray = null;
	//alert(theString);
	return theString;
}


// get list of layers, id/shape fields, scalefactors, etc.
function getLayerVisibles(theReply) {
	//alert("LayerInfo:\n" + theReply.length);
	var theReplyUC = theReply.toUpperCase();
	var startpos = 0;
	var endpos = 0;
	var pos = -1;
	var lpos = 1;
	var epos = 1;
	var zpos=1;
	var zpos2 = 1;
	var tempString="";
	var visString = "";
	var theString = "";
	var theCount = 0;
	var tempArray = new Array();
	//alert("Processing LayerInfo");
	lpos = theReplyUC.indexOf("<LAYERINFO",zpos);

	while (lpos > -1) {
		//alert("<LAYERINFO - pos " + lpos );
		
		if (lpos != -1) {
			
			zpos = theReplyUC.indexOf("</LAYERINFO",lpos);
			//alert("</LAYERINFO - pos " +  zpos);
			if (zpos!=-1) {
				pos = theReplyUC.indexOf("NAME=",lpos);
				if (pos != -1) {
					startpos = theReplyUC.indexOf("VISIBLE=",lpos);
					if (startpos != -1) {
						startpos = startpos + 9;
						endpos = startpos + 4;
						visString = theReply.substring(startpos,endpos);
					}
					if (visString=="true") {tempArray[theCount] = 1} else {tempArray[theCount] = 0};
					
					theCount++;
					endpos = zpos;
					
				}
				lpos = theReplyUC.indexOf("<LAYERINFO",zpos);
			} else {
				lpos = -1;
			}
			
		}
	}
	//alert("LayerInfo processed");
	tempArray.reverse();
	theString = tempArray.join("|");
	
	theReplyUC="";
	tempArray = null;
	//alert(theString);
	return theString;
}

function processStartMapServiceLayers(theReply) {
	mapServiceLayers[overlayIndex] = getLayerIDs(theReply);
	mapServiceLayersVisible[overlayIndex] = getLayerVisibles(theReply);
	//alert(overlayIndex);
	overlayIndex++;
	if (overlayIndex<mapServiceCount) {
		var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_SERVICE_INFO renderer="false" extensions="false" fields="false" />\n</REQUEST>\n</ARCXML>\n';

		sendMultiToServer(mapServiceList[overlayIndex],theString,"parent.MapFrame.processMulti",5002);
		
	} else {
		if (parent.ServiceFrame!=null) parent.ServiceFrame.document.location = appDir + "MapServices.htm";
		overlayIndex=0;
		getStartExtent2();
		
	}

}

function processSwithchActiveMapService(theReply) {
		if (parent.ServiceFrame!=null) {
			parent.ServiceFrame.document.location = appDir + "MapServices.htm";
		}
		theIndex = parseInt(activeMapServiceIndex);
	if (aimsLayersPresent) {
		getLayers(theReply);
		//if (setLayerVisible.length>0) setupLayerVisible();
		LayerVisible.length=0;
		if (mapServiceLayersVisible[theIndex].indexOf("|")!=-1) {
			LayerVisible = mapServiceLayersVisible[theIndex].split("|");
		} else {
			LayerVisible[0] = mapServiceLayersVisible[theIndex]
		}
		mapServiceLayers[theIndex] = getLayerIDs(theReply);
	}
	if (aimsQueryPresent) {
		if (useStoredQuery) checkStoredQueries(theReply);
	} else {
		useStoredQuery=false;
	}
	if (aimsLayersPresent) {
	 	if ((hasTOC) && (showTOC)) {
		 	parent.TOCFrame.document.location=appDir+"toc.htm";
		}
	}
	if (aimsGeocodePresent) {
		if (GCLayerCount==0) {
			if ((useGeocode) || (useReverseGeocode)) {
				useGeocode=false;
				useReverseGeocode=false;
			}
		}
	} else {
			useGeocode=false;
			useReverseGeocode=false;	
	}
	if (parent.ToolFrame!=null) {
		//alert("Refreshing toolbar");
		parent.ToolFrame.document.location= appDir + "toolbar.htm";
	} else if (hasToolBarOnLayer) {
		// requires custom function getLayerListContent. . . 
		var content = getLayerListContent();
		if (isNav) {
			replaceLayerContent("theToolBar",content);
		} else {
			content = swapStuff(content,"\\'",sQuote);
			document.all.theToolBar.innerHTML = content;
		}
		
	}
	
	hideRetrieveData();
	if (updateMaps) sendMapXML();

}

function swithchActiveMapService(indexIn,redrawMaps) {
	var index = parseInt(indexIn);
	//alert("Stuff goes here");
	activeMapServiceIndex = index;
	activeMapService = mapServiceList[index];
	showRetrieveData();
	updateMaps=redrawMaps;
	LayerName.length=0;
	LayerType.length=0;
	LayerVisible.length=0;
	LayerExtent.length=0;
	LayerIsFeature.length=0;
	LayerID.length=0;
	LayerIDField.length=0;
	LayerShapeField.length=0;
	LayerMinScale.length=0;
	LayerMaxScale.length=0;
	LayerFieldTypeList.length=0;
	LayerFieldList.length=0;
	LayerRenderString.length=0;
	LayerFieldSizeList.length=0;
	LayerFieldPrecisionList.length=0;
	layerCount = 0;

	var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_SERVICE_INFO  renderer="false" extensions="true" fields="true" />\n</REQUEST>\n</ARCXML>';
	sendMultiToServer(mapServiceList[index],theString,"parent.MapFrame.processMulti",5003);
	imsURL = mapServiceList[index];
	imsQueryURL= imsURL + "&CustomService=Query";
	imsGeocodeURL = imsURL + "&CustomService=Geocode";
}

/*
// prepare the request in xml format for Main Map
function writeXML() {
	//alert(overlayIndex);
	if (mapServiceLayers[overlayIndex].indexOf("|")!=-1) {
		var idArray = mapServiceLayers[overlayIndex].split("|");
		var visArray = mapServiceLayersVisible[overlayIndex].split("|");
	} else {
		var idArray = new Array();
		var visArray = new Array();
		idArray[0] = mapServiceLayers[overlayIndex];
		visArray[0] = mapServiceLayersVisible[overlayIndex];
		
	}
	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<idArray.length;i++) {
				if (visArray[i]==1) {
					theString += '<LAYERDEF id="' + idArray[i] + '" visible="true" />\n';
					
				}
				else {
					theString += '<LAYERDEF id="' + idArray[i] + '" visible="false" />\n';
				}
				
			}
			theString += '</LAYERLIST>\n';
		}
	}
	
	// map background color
	if ((mapTransparent) && (overlayIndex!=0)) {
		theString += '<BACKGROUND color="' + transColor + '" transcolor="' + transColor + '" />\n';
	} else {
		if (mapBackColor!="") {
			theString += '<BACKGROUND color="' + mapBackColor + '" />\n\n';
		}
	}
	if (overlayIndex==parseInt(activeMapServiceIndex)) {
		if (aimsLegendPresent) {
			// create a legend image
			if (legendVisible) theString += addLegendToMap();
		}
	}
	theString += '</PROPERTIES>\n';
	if (overlayIndex==parseInt(activeMapServiceIndex)) {
		// buffer
		if (aimsBufferPresent) {
			if (showBuffer) theString += addBufferToMap();
		}
		
		// select
		if (aimsSelectPresent) {
			theString += addSelectToMap();
		}	
	}
	
	// any custom stuff to fit here
	if ((aimsCustomPresent) && (overlayIndex==mapServiceCount-1)) theString += addCustomToMap1();
	if (overlayIndex==parseInt(activeMapServiceIndex)) {
		// 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 coord="' + forceComma(geocodeX) + coordsDelimiter + forceComma(geocodeY) + '">\n';
			theString += '<SIMPLEMARKERSYMBOL  type="circle"  color="' + geocodePointColor + '" width="' + geocodePointSize +'" />\n</POINT></OBJECT>\n';
			if (geocodeLabel!="") {
				theString += '<OBJECT units="database">\n<TEXT coord="' + 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" /></TEXT></OBJECT>\n';
			}
			theString += '</LAYER>\n';
			
		}
		
		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 coord="' + 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';
			}
		}
		if (overlayIndex==mapServiceList.length - 1) theString += addMapElements();
	}

	theString += '</GET_IMAGE>\n</REQUEST>\n</ARCXML>';
	idArray = null;
	visArray = null;
	//alert(theString);
	return theString;
}
*/
// write out a blank map. . . to get image extents from limit extents
function writeTopXML() {
	var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_IMAGE>\n<PROPERTIES>\n<ENVELOPE minx="' + forceCommaInOverlay(eLeft) + '" miny="' + forceCommaInOverlay(eBottom) + '" maxx="' + forceCommaInOverlay(eRight) + '" maxy="' + forceCommaInOverlay(eTop) + '" />\n';
	theString += '<IMAGESIZE height="' + iHeight + '" width="' + iWidth + '" />\n';
	theString += addMapElements();	
	theString += '</GET_IMAGE>\n</REQUEST>\n</ARCXML>';
	//alert(theString);
	return theString;

}

function addMapElements() {
	var theString = "";
	
	// any custom stuff to fit here
	if (aimsCustomPresent) theString += addCustomToMap2();
	
	if (drawBottomBar) {
		theString += '<LAYER type="acetate" name="theBottomBar">\n';		
		theString += '<OBJECT units="pixel">\n<POLYGON ';
		theString += 'coords="0' + coordsDelimiter + '1' + pairsDelimiter;
		theString += '1' + coordsDelimiter + bottomBarHeight + pairsDelimiter;
		theString += (iWidth-1) + coordsDelimiter + bottomBarHeight + pairsDelimiter;
		theString += (iWidth-1) + coordsDelimiter + '1' + pairsDelimiter;
		theString += '0' + coordsDelimiter + '1">\n';
		theString += '<SIMPLEPOLYGONSYMBOL fillcolor="' + bottomBarColor + '" boundary="true" boundarycolor="' + bottomBarOutline + '" overlap="false" />\n';
		theString += '</POLYGON>\n</OBJECT>\n';
		theString += '</LAYER>\n';
	}

	if (drawCopyright) {
		// draw text on the map
		theString += '<LAYER type="acetate" name="theCopyright" id="theCopyright">\n';		
		theString += '<OBJECT units="pixel">\n<TEXT coords="' + CopyrightCoords + '" label="' + CopyrightText + '">\n';
		theString += '<TEXTMARKERSYMBOL fontstyle="' + CopyrightStyle + '" fontsize="' + CopyrightSize + '" ';
		if (CopyrightFont!="") theString += 'font="' + CopyrightFont + '" ';
		theString += 'fontcolor="' + CopyrightColor + '" antialiasing="True" ';
		//if (CopyrightBackground.toUpperCase()=="TRUE") theString += 'background="' + CopyrightBackground + '" backcolor="' + CopyrightBGColor + '" ';
		if (CopyrightBackground.toUpperCase()=="TRUE") theString += 'blockout="' + CopyrightBGColor + '" ';
		if (CopyrightShadow.toUpperCase()=="TRUE") theString += 'shadow="' + CopyrightShadowColor + '" ';
		theString += '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" id="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
		//ScaleBarPrecision = numDecimals;
		theString += '<LAYER type="acetate" name="theScaleBar">\n';
		xDistance = eRight - eLeft;
		theString += '<OBJECT units="pixel">\n';
		theString += '<SCALEBAR ';
		
		if (drawScaleBar2) {
			theString += 'screenlength="' + parseInt(iWidth * (1/10)) + '" coords="' + (iWidth-((parseInt(iWidth * (4/10)))+20)) + coordsDelimiter + '3" ';
		} else {
			theString += 'screenlength="' + parseInt(iWidth * (2/10)) + '" coords="' + parseInt(iWidth * (6/10)) + coordsDelimiter + '3" ';
		}
		if (MapUnits=="DEGREES") theString += 'mode="geodesic" ';
		if (ScaleBarFont!="") theString += 'font="' + ScaleBarFont + '" ';
		theString += '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';	
		
	}
	if (drawScaleBar2) {
		// draw a scale bar
		//ScaleBarPrecision = numDecimals;
		theString += '<LAYER type="acetate" name="theScaleBar2">\n';
		xDistance = eRight - eLeft;
		theString += '<OBJECT units="pixel">\n';
		theString += '<SCALEBAR ';
		
		if (drawScaleBar) {
			theString += 'screenlength="' + parseInt(iWidth * (1/10)) + '" coords="' + (iWidth-((parseInt(iWidth * (2/10)))+10)) + coordsDelimiter + '3" ';
		} else {
			theString += 'screenlength="' + parseInt(iWidth * (2/10)) + '" coords="' + parseInt(iWidth * (6/10)) + coordsDelimiter + '3" ';
		}
		if (MapUnits=="DEGREES") theString += 'mode="geodesic" ';
		if (ScaleBar2Font!="") theString += 'font="' + ScaleBar2Font + '" ';
		theString += 'fontcolor="' + ScaleBar2FontColor + '" style="' + ScaleBar2Style + '" barcolor="' + ScaleBar2Color + '" ';
		if (MapUnits!="DEGREES") {
			theString += 'mapunits="' + MapUnits.toLowerCase() + '" ';
		}
		theString += 'scaleunits="' + ScaleBar2Units.toLowerCase() + '" antialiasing="True" ';
		var sDistance = getScaleBarDistance();
		if (MapUnits=="DEGREES") {
			if (xDistance<1/10){
				theString += 'precision="' + ScaleBar2Precision + '" ';
			}
		} else if (sDistance<5) {
			theString += 'precision="' + ScaleBar2Precision + '" ';
		}
		//theString += 'screenlength="' + parseInt(iWidth * (2/10)) + '" ';
		theString += 'fontsize="' + ScaleBar2Size + '" barwidth="' + ScaleBar2Width + '" 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 coord="5' + coordsDelimiter + (iHeight-10) + '" label="' + modeBlurb + '">\n';
		theString += '<TEXTMARKERSYMBOL fontstyle="BOLD" fontsize="12" font="ARIAL" fontcolor="' + modeMapColor + '" ';
		theString += 'threed="TRUE" glowing="' + modeMapGlow + '" />\n</TEXT>\n</OBJECT></LAYER>';
	
	}
	
	// any custom stuff to be drawn on top of everything
	if (aimsCustomPresent) theString += addCustomToMap4();
	
	return theString;
}
// send request to create graphic legend
	// replaces original getLegend() in aimsLegend.js
function getLegend() {
	legendVisible=true;
	drawLegendOnly=true;
	overlayIndex = parseInt(activeMapServiceIndex);
	legTitle = mapServiceName[overlayIndex];
	var theString=writeXML();
	showRetrieveMap();
	sendToServer(imsURL,theString,98);
}

function serviceVisibility(index, isVisible) {
	//alert(index + " - " + isVisible);
	var lyrName = "theMap" ;
	if (index>0) lyrName = "theMap" + index;
	parent.MapFrame.focus();
	if (isVisible) {
		showLayer(lyrName);
		mapServiceVisible[index]=1;
	} else {
		hideLayer(lyrName);
		mapServiceVisible[index]=0;
	}
}

// move map image with mouse
	// replaces panMouse() in aimsNavigation.js
function panMouse() {
	var xMove = x2-x1;
	var yMove = y2-y1;
	var cLeft = -xMove;
	var cTop = -yMove;
	var cRight = iWidth;
	var cBottom = iHeight;
	if (xMove>0) {
		cLeft = 0;
		cRight = iWidth - xMove;
	}
	if (yMove>0) {
		cTop = 0;
		cBottom = iHeight - yMove;
	}
	clipLayer2("theMap",cLeft,cTop,cRight,cBottom);
	moveLayer("theMap",xMove+hspc,yMove+vspc);
	for (var i=1;i<mapServiceCount;i++) {
		var lyrName = "theMap" + i;
			clipLayer2(lyrName,cLeft,cTop,cRight,cBottom);
			moveLayer(lyrName,xMove+hspc,yMove+vspc);
	
	}
	if (hasLayer("theMapClicks")) {
		clipLayer2("theMapClicks",cLeft,cTop,cRight,cBottom);
		moveLayer("theMapClicks",xMove+hspc,yMove+vspc);

	}
	//return false;
}

// move active service up
function moveServiceUp() {
	var k = parseInt(activeMapServiceIndex);
	if (k<mapServiceList.length-1) {
		var m = k + 1;
		activeMapServiceIndex = m;
		moveMapService(k, m)
	}
}

// move active service down
function moveServiceDown() {
	var k = parseInt(activeMapServiceIndex);
	if (k>0) {
		var m = k - 1;
		//var msg = "Before:" + k + "\n" + mapServiceList[k] + "\n" + mapServiceName[k] + "\n" + mapServiceLayers[k] + "\n" + mapServiceLayersVisible[k] + "\n" +  mapServiceVisible[k] + "\n\n";
		activeMapServiceIndex = m;
		moveMapService(k, m)
		//var msg = msg + "After:" + k + "\n" + mapServiceList[k] + "\n" + mapServiceName[k] + "\n" + mapServiceLayers[k] + "\n" + mapServiceLayersVisible[k] + "\n" +  mapServiceVisible[k] + "\n\n";
		//alert(msg);
		
	}

}

function moveMapService(fromPosition, toPosition) {
	var fp=parseInt(fromPosition);
	var tp=parseInt(toPosition);
	var temp1 = mapServiceList[fp];
	var temp2 = mapServiceList[tp];
	mapServiceList[fp] = temp2;
	mapServiceList[tp] = temp1;
	temp1 = mapServiceName[fp];
	temp2 = mapServiceName[tp];
	mapServiceName[fp] = temp2;
	mapServiceName[tp] = temp1;
	temp1 = mapServiceLayers[fp];
	temp2 = mapServiceLayers[tp];
	mapServiceLayers[fp] = temp2;
	mapServiceLayers[tp] = temp1;
	temp1 = mapServiceLayersVisible[fp];
	temp2 = mapServiceLayersVisible[tp];
	mapServiceLayersVisible[fp] = new String(temp2);
	mapServiceLayersVisible[tp] = new String(temp1);
	var temp3 = mapServiceVisible[fp];
	var temp4 = mapServiceVisible[tp];
	mapServiceVisible[fp] = temp4;
	mapServiceVisible[tp] = temp3;
	temp3 = forceCommaInRequest[fp];
	temp4 = forceCommaInRequest[tp];
	forceCommaInRequest[fp] = temp4;
	forceCommaInRequest[tp] = temp3;
	//window.setTimeout("sendMapXML();",1500);
	if (parent.TOCFrame!=null) {
		parent.TOCFrame.updateLayers2();
	} else {
		sendMapXML();
	}
	
}
		
function deleteMapService() {
	var k = parseInt(activeMapServiceIndex);
	var m = mapServiceList.length-1;
	if (k==m) {
		activeMapServiceIndex = k-1;
	} else {
		for (var i=k;i<m;i++) {
			mapServiceList[i]=mapServiceList[i+1];
			mapServiceName[i]=mapServiceName[i+1];
			mapServiceLayers[i]=mapServiceLayers[i+1];
			mapServiceLayersVisible[i]=mapServiceLayersVisible[i+1];
			mapServiceVisible[i]=mapServiceVisible[i+1];
			forceCommaInRequest[i]=forceCommaInRequest[i+1];
		}
	}
	mapServiceList.length=m;
	mapServiceName.length=m;
	mapServiceLayers.length=m;
	mapServiceLayersVisible.length=m;
	mapServiceVisible.length=m;
	forceCommaInRequest.length=m;
	mapServiceCount = mapServiceList.length;
	lyrName = "theMap" + m;
	hideLayer(lyrName);
	swithchActiveMapService(activeMapServiceIndex,true);
}

// process the catalog and list the ImageServices
function processCatalog(theReply) {
		//alert ("function startMap\nResponse:\n" + theReply);
		var theReplyUC = theReply.toUpperCase();
		var startpos = 0;
		var endpos = 0;
		ServiceName.length=0;
		serviceCount = 0;
		var pos = -1;
		var spos = 9;
		var lpos = 9;
		var i=0;
		var tempString=""
		var visString = ""
		var testString = "";
		pos = theReply.indexOf("ERROR",endpos);
		if (pos==-1) {
			while (lpos > -1) {
				// find the mapper service group
				lpos = theReplyUC.indexOf("<SERVICE ",endpos);
				if (lpos != -1) {
					startpos = theReplyUC.indexOf("NAME=",lpos + 8);
					startpos = startpos + 6
					endpos = theReply.indexOf(dQuote, startpos);
					tempString = theReply.substring(startpos,endpos);
					startpos = theReplyUC.indexOf("TYPE=",lpos);
					startpos = startpos + 6;
					endpos = startpos + 5;
					if (theReply.substring(startpos,endpos)=="Image") {
						startpos = theReplyUC.indexOf("STATUS=",lpos);
						startpos = startpos + 8;
						endpos = startpos + 7;
						if (theReplyUC.substring(startpos,endpos)=="ENABLED") {
							ServiceName[i]=tempString;
							startpos = theReplyUC.indexOf("<IMAGE",lpos);
							if (startpos!=-1) {
								endpos = startpos + 7;
								startpos = theReplyUC.indexOf("TYPE=",endpos);
								startpos = startpos + 6;
								endpos = theReply.indexOf(dQuote, startpos);
								serviceImageType[i] = theReplyUC.substring(startpos,endpos);
							} else {
								serviceImageType[i] ="Unknown";
							}
							i=i+1;
							serviceCount=serviceCount+1;
						}
						//serviceImageType
					}
					
				}
			}
			//ServiceName.sort();
			loadServiceForm();
		} else {
			alert("Error compiling MapService List");
		}
		hideRetrieveData();
	
}

function startAddService() {
	var tempcVersion = cVersion;
	cVersion = "";
	var catologURL = "http://" + serviceHost + "/servlet/com.esri.esrimap.Esrimap?ServiceName=catalog";
	var theText = "<GETCLIENTSERVICES/>";
	sendToServer(catologURL,theText,5);
	cVersion = tempcVersion;

}

function loadServiceForm() {
		if (useTextFrame) {
			parent.TextFrame.document.location= appDir + "addService.htm";
		} else {
			var Win1 = open(appDir + "addService.htm","AddServiceWindow","width=575,height=150,scrollbars=yes,resizable=yes");
		}
	
}

function addMapService(theServiceURL,addServiceName,serviceIndex) {
	// make URL for getting mapservice catalog
	//overlayIndex=mapServiceCount;
	var theType = serviceImageType[serviceIndex];
	var okayToLoad = true;
	if ((theType=="JPG") || (theType=="PNG24") || (theType=="Unknown")) {
		if (!confirm(noTransMessage,true)) okayToLoad=false;
	}
	if (okayToLoad) {
		mapServiceName[mapServiceCount]=addServiceName;
		mapServiceList[mapServiceCount]=theServiceURL;
		mapServiceVisible[mapServiceCount]=1;

		var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_SERVICE_INFO renderer="false" extensions="false" fields="false" />\n</REQUEST>\n</ARCXML>\n';
		sendMultiToServer(theServiceURL,theString,"parent.MapFrame.processMulti",5004);
	}
}

function processAddMapServiceLayers(theReply) {
	mapServiceLayers[mapServiceCount] = getLayerIDs(theReply);
	mapServiceLayersVisible[mapServiceCount] = getLayerVisibles(theReply);
	if (parent.ServiceFrame!=null) parent.ServiceFrame.document.location = appDir + "MapServices.htm";
	mapServiceCount++;
	overlayIndex=0;
	sendMapXML();
		

}

function forceCommaInOverlay(theNumber) {
	var comma = ",";
	var dot = ".";
	var charOut = comma;
	var charIn = dot;
	var numberString = new String(theNumber);
	if (commaUsedInTopLayer) {
		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;
}

