var hostName = document.location.host;
// make prefix for URL
var serverURL  = "http://" + hostName + "/servlet/com.esri.esrimap.Esrimap?ServiceName=";
var connectorURL = "http://" + hostName + "/servlet/com.esri.esrimap.Esrimap?ServiceName=redirect";
var imsURL = serverURL + "EBT_Locator";
var	imsQueryURL = imsURL + "&CustomService=Query";
var	imsGeocodeURL = imsURL + "&CustomService=Geocode";
// encoding for XML header
var localeEncoding = 'encoding="UTF-8" ';
// delimiter to be used between coordinates in strings in ArcXML request
var coordsDelimiter = " ";
// delimiter to be used between pairs of coordinates in strings in ArcXML request
var pairsDelimiter = ";";


var theStreet = ""
var theCity = ""
var theZip = ""

var theType = ""
var MoneyOrder = ""
var BillPay = ""
var Other = ""


var thePointX = "";
var thePointY = "";
var thePointLabel = "";
var theBestScoreIndex=0;
var GCscore = new Array();
var GCpointX = new Array();
var GCpointY = new Array();
var GCaddress = new Array();
var theSearchDistance = 0;


var sQuote = "'";
var dQuote = '"';

var debugOn = 0;



/**********************************************
*	XML functions
**********************************************/

// send in XML request and get XML response - uses PostFrame form
function sendToServer(URLString,XMLRequest,theType) {
	if (parent.PostFrame.document.forms[0]!=null) {
		okToSend = true;
		if (okToSend) {
			XMLMode = theType;
			if (debugOn>2) alert("ServiceName: " + URLString + "\nXMLRequest:\n " + XMLRequest);
			okToSend = false;
				var theForm = parent.PostFrame.document.forms[0];
				var requestURL = URLString;
				if (theForm.RedirectURL!=null) {
					if (isNotSameHostInURL(URLString, hostName)) {
						requestURL = connectorURL;
						theForm.RedirectURL.value = URLString;
					} else {
						theForm.RedirectURL.value = "";
					}
				}
				theForm.action=requestURL + "&Form=True&Encode=True";
				var xmlHeader = '<?xml version="1.0" ' + localeEncoding + '?>';
				theForm.ArcXMLRequest.value=xmlHeader + XMLRequest;
//				alert("Here");
//				alert("ServiceName: " + theForm.action + "\nXMLRequest:\n " + theForm.ArcXMLRequest.value);
				theForm.submit();
				
		} else {
			alert("Response from previous request(s) not received.");


		}
	} else {
		alert("Form for posting request not found. Unable to communicate with server.");
	}
		
}


// 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;
	}
}

// replace +  in string with space to allow parsing of unescaped xml response
function replacePlus(inText) {
     var re = /\+/g;
      inText = inText.replace(re," ");
     return inText;
}


// check if there is an error message in the response
function getXMLErrorMessage(theString) {
	var pos1 = 0;
	var pos2 = 0;
	var pos3 = 0;
	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;

}


// process the response xml
function processXML(theReplyIn) {

	theReplyIn = replacePlus(theReplyIn);
	var theReply = unescape(theReplyIn);
//	alert(theReply);
	
	okToSend = true;
	if (debugOn>2) alert("XMLResponse:\n " + theReply);
	var theError = getXMLErrorMessage(theReply);
	switch(XMLMode) {
		case 1:
			var theURL = "";
			theURL = getURL(theReply);
			
			if (theURL != "") {
				getXYs(theReply);
				document.theImage.src = theURL;
				
			}
			else {
				
				if (debugOn>0) {
					alert("Unable to display Map image\nDebug On\n" + theReply);
				} else {
					alert("Unable to display MapService\nServer returned:" + theError);
				}
			}
			hideRetrieveMap();
			break

		case 2:
			// nothing here yet
			break

		case 3:
			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 ((highlightedOne!="") && (queryZoom)) {
				setStartQuery();
			} else if (showGeocode) {
				//alert("Starting Geocode")
				setStartGeocode();
			} else if (showPoint) {
				//alert("Starting Geocode")
				zoomToPoint(thePointX,thePointY,true,thePointLabel)

			} else {
				eLeft=startLeft;
				eRight=startRight;
				eTop=startTop;
				eBottom=startBottom;
				sendMapXML();
			}
			
			
			break
		case 5:
			// startquery request
			parseStartQuery(theReply);
			
			break
		case 7:
			// identify
			processIdentify(theReply);
			
			break
		case 27:
			// get geocoding results

			customparseGeocodeResults(theReply,XMLMode);
			break
		case 28:
			// get geocoding results
			customparseGeocodeResults(theReply,XMLMode);
			break
		case 30:
			findNearestLocations(theReply);
			break

		default:
			alert(theReply + "\nUnable to execute response.");
			
	}
	
}




// Added for CDC EZ Locator
function startSearchGeocode() {
	theStreet = document.Search.Street.value;
	theZip = document.Search.ZipCode.value;
	theCity = document.Search.City.value;
	theTypeList = document.Search.TYPE;
	theType = theTypeList[theTypeList.selectedIndex].value;
	MoneyOrder = document.Search.MoneyOrder.checked;
	BillPay = document.Search.BillPay.checked;
//   alert(theStreet+theCity+theZip);
	if ((MoneyOrder || BillPay) && (theType == "ATM")) theType = "POS";
	if ((MoneyOrder || BillPay) && (theType == "FS")) {
		MoneyOrder = false;
		BillPay = false;
		theType = "FS";
	}
	if (theStreet == "") {
		if ((theZip == "") && (theCity == "")) alert("Please enter a Zip Code or City")
		else if (theZip != "") findbyZip();
		else if (theCity != "") findbyCity();
		else alert("Unknown problem");
	} else if (theZip != "") SearchGeocode("Zip");
	else if (theCity != "") SearchGeocode("City");
	else alert("Please Enter a City or ZIP Code");
	return false;
}

function findbyZip() {
//alert("Finding By Zip");
posttoSearchPage("ZipList",theZip,theZip);

}


function findbyCity() {
//alert("Finding By City");
posttoSearchPage("CityList",theCity,theCity);
}

function SearchGeocode(theType) {
//	alert("Geocoding by "+theType);
	if (theType == "Zip") theString=writeGeocodeXML("Zip");
	else theString=writeGeocodeXML("City");
//	alert(theString);
	sendToServer(imsGeocodeURL,theString,27);
}

// write out the geocode XML request
function writeGeocodeXML(theSource) {
	//alert("Writing Geocode")
	var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_GEOCODE>\n';
	if (theSource == "Zip") {
		theString += '<LAYER id="ZipGeoCode" />';
		theString2 = '<GCTAG id="Zone" value="'+theZip+'"/>\n';
	} else if (theSource == "City") {
		theString += '<LAYER id="CityGeocode" />';
		theString2 = '<GCTAG id="Zone" value="'+theCity+'"/>\n';
	}
	theString += '<ADDRESS>\n';
	theString += '<GCTAG id="STREET" value="'+theStreet+'"/>\n';
	theString += theString2;
	theString += '</ADDRESS>\n</GET_GEOCODE>\n</REQUEST>\n</ARCXML>\n';
	return theString;	
}


function customparseGeocodeResults(theReply,theMode) {
//	alert("Parsing:\n"+theReply)
	GCscore.length=1;

	var pos = theReply.indexOf("<GCCOUNT count=");
	var lpos = 0;
	var startpos = pos + 16;
	var startpos2=0;
	var endpos = theReply.indexOf(dQuote,startpos);
	var fString = theReply.substring(startpos,endpos);
	GCpointCount=parseInt(fString);
	var gcCount=0;
	var theBestScore=0;
	var numBestScores=0;
	if ((pos>0) && (GCpointCount>0)) {
		pos = theReply.indexOf("<FEATURE");
		if (pos!=-1) {
			while (pos!=-1) {
				lpos = theReply.indexOf("<FIELD",pos);
				if (lpos!=-1) {
					startpos2 = theReply.indexOf('name="SCORE"',lpos);
					startpos = theReply.indexOf("FIELDVALUE valuestring=",startpos2);
					startpos = startpos + 24;
					endpos = theReply.indexOf(dQuote,startpos);
					theScore = parseFloat(theReply.substring(startpos,endpos));
					if (theScore>=theBestScore) {
					theBestScore=theScore;
					theBestScoreIndex=gcCount;
					numBestScores++;
					//alert("TheBestScore= "+theBestScore);
					}
					GCscore[gcCount] = theReply.substring(startpos,endpos);
					startpos2 = theReply.indexOf('name="ADDRESSFOUND"',lpos);
					startpos = theReply.indexOf("FIELDVALUE valuestring=",startpos2);
					startpos = startpos + 24;
					endpos = theReply.indexOf(dQuote,startpos);
					GCaddress[gcCount] = theReply.substring(startpos,endpos);
					startpos2 = theReply.indexOf('name="SHAPEFIELD"',lpos);
					startpos = theReply.indexOf("<POINT x=",startpos2);
					startpos += 10;
					endpos = theReply.indexOf(dQuote,startpos);
					GCpointX[gcCount] = theReply.substring(startpos,endpos);
					startpos = theReply.indexOf("y=",endpos);
					startpos = startpos + 3;
					endpos = theReply.indexOf(dQuote,startpos);
					GCpointY[gcCount] = theReply.substring(startpos,endpos);
					gcCount++;

				}
				
			pos = theReply.indexOf("<FEATURE",endpos);
			}
		}
		if (numBestScores>1) {
//			alert("Here");
//			alert(GCaddress[0]);
			parent.AddressFrame.writeLinks(numBestScores);
			
//			var i = 0;
//			while(i < 4) {
//				if (GCscore[i] == theBestScore) {
//					document.Response.ResponseList.options[i].text = GCaddress[i];
//					document.Response.ResponseList.options[i].value = GCpointX[i] + "," + GCpointY[i];
//				} else {
//					document.Response.ResponseList.options[i].text = "";
//				}
//			i++;
//			}
		} else {
//			alert("One Found");
			thePointX = GCpointX[theBestScoreIndex];
			thePointY = GCpointY[theBestScoreIndex];
			thePointLabel = GCaddress[theBestScoreIndex];
			theSearchDistance = 0.2;
			parent.LogFrame.document.location.reload();
			findNearestLocations("");
		}
	} else {
		alert("Address not found.");
	}
}

function findNearestLocations(theReply) {
//1 mile = 0.01756 degrees
//	alert("Find Locations\n"+theReply);
	var numFound = justGetFeatureCount(theReply);
//	alert(thePointX+':'+thePointY+':'+theSearchDistance);
//	alert(numFound);
	if (numFound < 10) {
		theSearchDistance = theSearchDistance * 2;
		circleCoords = createCircle(thePointX,thePointY,theSearchDistance);
		theIdentifyString = writeIdentifyXML(thePointX,thePointY,circleCoords);	
//		alert(theIdentifyString);
		sendToServer(imsQueryURL,theIdentifyString,30);
	} else {
		theSearchList = createSearchList(theReply,numFound);
	}
}

function createSearchList(theReply,recCount) {
//	alert("Creating SearchList\n"+theReply);
	var theIDFieldName = "PKEY";
	var theXFieldName = "X_COORD";
	var theYFieldName = "Y_COORD";
	var theIDList = getAllFieldValues2(theReply,theIDFieldName,recCount);
	var theXList = getAllFieldValues2(theReply,theXFieldName,recCount);
	var theYList = getAllFieldValues2(theReply,theYFieldName,recCount);
	var theResultString = ""
	for (var i=0;i<recCount;i++) {
		var theDistanceinMiles = getMileage(thePointX,thePointY,theXList[i],theYList[i]);
		theResultString = theResultString + theIDList[i] +","+theDistanceinMiles+";";
	}
//Post List to the Search.cfm page written at DPSS
//	alert(theResultString);
	var theRequestString = theStreet+","+theCity+","+theZip;
	theRequestString = theRequestString+";"+thePointX+","+thePointY;
//	alert(theRequestString);
	posttoSearchPage("MileList",theRequestString,theResultString);
	
}

function posttoSearchPage(theRequestType,theRequestString,theRequestResult) {
	var thePostForm = document.PostForm;
	theRequestString = theRequestString+";Type="+theType+",MoneyOrder="+MoneyOrder+",BillPay="+BillPay;

//	alert(theRequestString);
//	alert(theRequestResult);

	thePostForm.RequestType.value = theRequestType;
	thePostForm.RequestString.value = theRequestString;
	thePostForm.RequestResult.value = theRequestResult;

	thePostForm.submit();
}

function getMileage(fromX,fromY,toX,toY) {
	var x1 = parseFloat(fromX);
	var y1 = parseFloat(fromY);	
	var x2 = parseFloat(toX);
	var y2 = parseFloat(toY);
//	alert(x1+":"+y1+";"+x2+":"+y2);

	var dx = (x2 - x1)/5280;
	var dy = (y2 - y1)/5280;
	var theDistance = Math.sqrt((dx * dx) + (dy * dy));///0.0159914058;
	theMiles = Math.round(theDistance*100)/100;
	return(theMiles);
}

// get all the field values and return a list
function getAllFieldValues2(theReply,theField,recCount) {
	var vList = new Array();
	startpos = 0;
	for (var i=0;i<recCount;i++) {
		var preString = theField + '="';
		var pos = theReply.indexOf(preString,startpos);
		var startpos = pos + preString.length;
		var endpos = theReply.indexOf(dQuote,startpos);
		var theValue = theReply.substring(startpos,endpos);
		vList[i] = theValue;
	}
	return vList;
}

function writeIdentifyXML(theXString,theYString,circleCoords) {
//	alert("Writing Identify");
	var theString = "";
	var theWhereString = "";
	if ((theType != "Both") || (MoneyOrder) || (BillPay)) {
		theString += ' where="'
		if (theType != "Both") theString += 'LACOUNTY.GIS.EBT_LOCATIONS2.TYPE = \''+theType+'\' and ';
		if (MoneyOrder)	theString += 'LACOUNTY.GIS.EBT_LOCATIONS2.MO = \'MO\' and ';
		if (BillPay)	theString += 'LACOUNTY.GIS.EBT_LOCATIONS2.BP = \'BP\' and ';
		theWhereString = theString.substr(0,theString.length-5)
		theWhereString += '"';
	}	
	var theString = '<ARCXML version="1.1">\n<REQUEST>\n';
	theString += '<GET_FEATURES outputmode="xml" geometry="true">\n';
	theString += '<LAYER id="EBT Locations" />\n';
	theString += '<SPATIALQUERY'+theWhereString+'>\n';
	theString += '<SPATIALFILTER relation="area_intersection">\n';
	theString += '<POLYGON>\n<RING>\n';
	theString += '<COORDS>' + circleCoords + '</COORDS>\n';
	theString += '</RING>\n</POLYGON>\n';
	theString += '</SPATIALFILTER>\n</SPATIALQUERY>\n</GET_FEATURES>\n</REQUEST>\n</ARCXML>\n';
	return theString;	
}


function createCircle(xVal, yVal, aDist){
	var intXval = parseFloat(xVal);
	var intYval = parseFloat(yVal);
	var coordString = "";
	var circX = 0;
	var circY = 0;
	var delX = 0;
	var delY = 0;
	var nSine = 0;
	var nCosine = 0;
	var radAngle = 0;
	var feetDist = parseFloat(aDist) * 5280;
	var ddDist = parseFloat(aDist) * 0.0159914058;
	for (i = 0; i <= 36; i++) {
		radAngle = ( ( i * 10 * Math.PI) / 180);
		nSine = Math.sin(radAngle);
		nCosine = Math.cos(radAngle);
		delX = nCosine * feetDist;
		delY = nSine * feetDist;
		circX = intXval + parseFloat(delX); 
		circY = intYval + parseFloat(delY);
		if (i == 0) {
			coordString = circX + coordsDelimiter + circY;
		}else {
			coordString += ";" + circX + coordsDelimiter + circY;
		} // if i == 0		
	} // for loop
	return coordString;
}

function selectCandidate(theBestScoreIndex) {
//	alert(theBestScoreIndex);
//	alert(parent.MapFrame.GCpointX[theBestScoreIndex]);
	parent.MapFrame.thePointX = parent.MapFrame.GCpointX[theBestScoreIndex];
	parent.MapFrame.thePointY = parent.MapFrame.GCpointY[theBestScoreIndex];
	parent.MapFrame.thePointLabel = parent.MapFrame.GCaddress[theBestScoreIndex];
	parent.MapFrame.theSearchDistance = 0.2;
	parent.MapFrame.findNearestLocations("");
			
}
