// aimsGeocode.js
/*
*  JavaScript template file for ArcIMS HTML Viewer
*		dependent on aimsXML.js, ArcIMSparam.js, aimsCommon.js, aimsMap.js,
*		aimsLayers.js, aimsDHTML.js
*		aimsClick.js, aimsNavigation.js
*/

aimsGeocodePresent=true;
var gotParcels = false;
var usingSearchName = false;
var selSearchName;
var usingSearchPPN = true;
var selSearchPPN;
var GCLayers = new Array();
var GCLayerId = new Array();
var GCLayerStyle = new Array();
var GCActiveLayer=0;
var GCidCount=0;
var GCid = new Array();
var GClabel = new Array();
var GCdesc = new Array();
var GCvalue = new Array();
var GCpointX = new Array();
var GCpointY = new Array();
var GCpointCount = 0;
var GCscore = new Array();
var GCaddress = new Array();

var GCLayerCount=0;

var geocodeType = "";		//keep track of the layer being geocoded: used to alter symbol drawn on screen after match.
/* master variables for geocoding info - the main variables of GCid, GClabel, and GCdesc will be read in programmatically
	from there. Replaces previous system of asking IMS for geocode info EVERY time geocoding is requested.  */
var parcelGCid = new Array();
var parcelGClabel = new Array();
var parcelGCdesc = new Array();
var streetGCid = new Array();
var streetGClabel = new Array();
var streetGCdesc = new Array();


if (imsGeocodeURL=="") {
	imsGeocodeURL= imsURL + "&CustomService=Geocode";
}

/*
***************************************************************************************

Geocoding functions 

***************************************************************************************
*/

// set up geocode
function setupGeocode() {
		showRetrieveData();
		getGeocodeParams();	
}

// get a list of geocoding layers
function getGeocodeLayers() {
	var theString = '<?xml version="1.0" encoding="UTF-8"?><ARCXML VERSION="1.1">\n<REQUEST>\n<GET_SERVICE_INFO />\n';
	theString += '</REQUEST>\n</ARCXML>';
	sendToServer(imsGeocodeURL,theString,20);
	
}

// get the parameters for geocoding the layer
function getGeocodeParams() {
	var theString = '<?xml version="1.0" encoding="UTF-8"?><ARCXML VERSION="1.1">\n<REQUEST>\n<GET_SERVICE_INFO />\n';
	theString += '</REQUEST>\n</ARCXML>';
	var theReply="";
	sendToServer(imsGeocodeURL,theString,26);

}

// write out the geocode XML request
function writeGeocodeXML() {
	showRetrieveData();
	minGeocodeScore = 20;
	var theString = '<?xml version="1.0" encoding="UTF-8"?><ARCXML VERSION="1.1">\n<REQUEST>\n<GET_GEOCODE maxcandidates="' + maxGeocodeCandidates + '" minscore="' + minGeocodeScore + '">\n';
	theString += '<LAYER id="' + GCLayerId[GCActiveLayer] + '" />';
	geocodeType = GCLayerId[GCActiveLayer];
	theString += '<ADDRESS>\n';
	for (var i=0;i<GCidCount;i++) {
		theString += '<GCTAG id="' + GCid[i] + '" value="' + GCvalue[i] + '"/>\n';
	}
	theString += '</ADDRESS>\n</GET_GEOCODE>\n</REQUEST>\n</ARCXML>\n';
	//alert(theString);
	return theString;
	
}

// parse out geocoding layers
function parseGeocodeLayers(theReply) {
	//alert(theReply);
	var pos = 0;
	var startpos = 0;
	var endpos = 0;
	var lpos = 0;
	GCLayers.length=1;
	GCLayerCount=0;
	pos = theReply.indexOf("<LAYERINFO",endpos);
		
	while (pos!=-1) {
		lpos = theReply.indexOf('name=',pos);
		if (lpos!=-1) {
			//skip any layer not containing "extension"
			var nextpos = pos + 11;
			var nextLayer = theReply.indexOf("</LAYERINFO",nextpos);
			var extension = theReply.indexOf("<GCSTYLE",nextpos);
			//alert("extension:"+extension+" /// nextLayer:"+nextLayer);
			if ((extension <= nextLayer) && (extension != -1)) {	
				startpos = lpos + 6;
				endpos = theReply.indexOf(dQuote,startpos);
				GCLayers[GCLayerCount] = theReply.substring(startpos,endpos);
				if (GCLayers[GCLayerCount] == "Parcel Geocoding") gotParcels = true;
				startpos = theReply.indexOf('id=',endpos);
				if (startpos!=-1) {
					startpos += 4;
					endpos = theReply.indexOf(dQuote,startpos);
					GCLayerId[GCLayerCount] = theReply.substring(startpos,endpos);
				}
				startpos = theReply.indexOf("<GCSTYLE name=",endpos);
				if (startpos!=-1) {
					startpos += 15;
					endpos = theReply.indexOf(dQuote,startpos);
					GCLayerStyle[GCLayerCount] = theReply.substring(startpos,endpos);
					GCLayerCount=GCLayerCount+1;
				}
			} else {
				endpos = pos + 11;
			}
			pos = theReply.indexOf("<LAYERINFO",endpos);

		} else {
			// bypass this for now
			//alert(theReply);
			pos =-1;
		}
	}
	if (gotParcels) {


		//GCLayers[GCLayerCount] = "Searching by Name";
		//GCLayerCount = GCLayerCount + 1;
		GCLayers[GCLayerCount] = "Searching by PPN";
		GCLayerCount = GCLayerCount + 1;

	}
	hideRetrieveData();
}

// parse out the basic geocode parameters for the layer
function parseGeocodeParams(theReply) {
	//alert(theReply);
	/* 11-2003 - we will now be storing all geocoding info at once,to avoid having to send this request over & over
		this will facilitate increased speed in switching between geocoding types. When an active geocoding layer 		needs to be set, the setActiveGeocode function will be called */ 
	var layerBegin = 0;
	var startpos = 0;
	var endpos = 0;
	var layerEnd = 0;
	layerBegin = theReply.indexOf("<LAYERINFO");
	
	if (layerBegin != -1) {
		while (layerBegin != -1) {
			var idCount = 0;
			var geoType = "nil";
			startpos = layerBegin + 11;
			layerEnd = theReply.indexOf("</LAYERINFO>",startpos);
			startpos = theReply.indexOf("<GCINPUT id=",startpos);
			var nameStart = theReply.indexOf("<LAYERINFO name=",layerBegin) + 17;
			var nameEnd = theReply.indexOf(dQuote,nameStart);
			var layerNm = theReply.slice(nameStart,nameEnd);
			if (layerNm == "Parcel Geocoding") geoType = "parcel";
			if (layerNm == "Street Geocoding") geoType = "street"; 
			while ((startpos<layerEnd) && (startpos!=-1)) {
				startpos += 13;
				endpos = theReply.indexOf(dQuote,startpos);
				if (geoType == "parcel") parcelGCid[idCount] = theReply.substring(startpos,endpos);
				if (geoType == "street") streetGCid[idCount] = theReply.substring(startpos,endpos);
				startpos = theReply.indexOf("label=",endpos);
				startpos = startpos + 7;
				endpos = theReply.indexOf(dQuote,startpos);
				if (geoType == "parcel") parcelGClabel[idCount] = theReply.substring(startpos,endpos);
				if (geoType == "street") streetGClabel[idCount] = theReply.substring(startpos,endpos);
				startpos = theReply.indexOf("description=",endpos);
				startpos += 13;
				endpos = theReply.indexOf(dQuote,startpos);
				if (geoType == "parcel") parcelGCdesc[idCount] = theReply.substring(startpos,endpos);
				if (geoType == "street") streetGCdesc[idCount] = theReply.substring(startpos,endpos);
				idCount=idCount+1;
				startpos = theReply.indexOf("<GCINPUT id=",endpos);
			}
			layerBegin = theReply.indexOf("<LAYERINFO",layerEnd);
		}
		hideRetrieveData();
		return true;
	} else {
		hideRetrieveData();
		return false;
	}
}

function setActiveGeocode(theLayer) {
/* this function fills the active geocode variables (GCid, GClabel, GCdesc) used in XML request generation with the info stored in either the parcelGC variable set or the streetGC variable set, depending on the value of theLayer. This function will need to be called every time the active geocode layer is changed, prior to generating an XML request  */
	GCid.length=0;
	GClabel.length=0;
	GCdesc.length=0;
	GCidCount=0;
	for (var e=0;e<GCLayers.length;e++) {
		if (GCLayers[e] == theLayer) GCActiveLayer = e;
	}	
	if (theLayer == "Parcel Geocoding") {
		GCidCount = parcelGCid.length;
		for (var d=0;d<GCidCount;d++) {
			GCid[d] = parcelGCid[d];
			GClabel[d] = parcelGClabel[d];
			GCdesc[d] = parcelGCdesc[d];
		}	
	} else if (theLayer == "Street Geocoding") {
		GCidCount = streetGCid.length;
		for (var d=0;d<GCidCount;d++) {
			GCid[d] = streetGCid[d];
			GClabel[d] = streetGClabel[d];
			GCdesc[d] = streetGCdesc[d];
		}
	}
}

// parse out geocode response and display results in table
function parseGeocodeResults(theReply) {
	//alert(theReply);
	hideRetrieveData();
	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;
	//alert(GCpointCount);
	if (GCpointCount == 0) {
		/*if the voter search is running, and no match returns from a parcel geocode request, run the search
		again using street geocoding */
		//alert(GCLayers[GCActiveLayer]); 
		if (GCLayers[GCActiveLayer] == "Parcel Geocoding") {
			setActiveGeocode("Street Geocoding");
			GCvalue[0] = storedSearchAddress;
			GCvalue[1] = "";
			GCvalue[2] = "";
			var theText = writeGeocodeXML();
			sendToServer(imsGeocodeURL,theText,27);
			return;
		} 
	}
	if (GCpointCount>0) {
		pos = theReply.indexOf("<FEATURE");
		if (pos!=-1) {
			while (pos!=-1) {
				lpos = theReply.indexOf("<FIELD",pos);
				if (lpos!=-1) {
					//while (lpos!=-1) {
						startpos2 = theReply.indexOf('name="SCORE"',lpos);
						startpos = theReply.indexOf("FIELDVALUE valuestring=",startpos2);
						startpos = startpos + 24;
						endpos = theReply.indexOf(dQuote,startpos);
						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++;
					//	lpos = theReply.indexOf("<FIELD",endpos);
					//}
				}
				pos = theReply.indexOf("<FEATURE",endpos);
			}
		}
		showGeocode=true;
		geocodeX=GCpointX[0];
		geocodeY=GCpointY[0];
		geocodeLabel=GCaddress[0];
			
		if (GCpointCount == 1 && runningVoterSearch) {
			autoVotingFrontEnd(GCaddress[0],GCpointX[0],GCpointY[0]);
			return;	
		}

		//} else {
		var Win1;
		if (((toolMode == 7) && (GCpointCount > 1)) || ((toolMode != 7) && (GCpointCount > 0))) {
			var theFrame = "parent.MapFrame";
			if ((useExternalWindow) || (!useTextFrame)) {
				Win1 = window.open("","QueryWindow","width=200,height=200,scrollbars=yes,resizable=yes");
				Win1.resizeTo(400,200);
				theFrame = "opener";
				if (parent.MapFrame!=null) theFrame = "opener.parent.MapFrame";
			} else {
				Win1 = parent.TextFrame;
				Win1.document.open();

			}



			Win1.document.open();
			Win1.document.writeln('<html><head><title>Address Match Candidates</title>');
			Win1.document.writeln('<script language="javascript">');
			Win1.document.writeln('var t;');
			Win1.document.writeln('var par;');
			Win1.document.writeln(' if (opener) {  ');
			Win1.document.writeln(' 	if (opener.name=="MapFrame") {  ');
			Win1.document.writeln(' 		t = opener.parent.MapFrame;  ');
			Win1.document.writeln('			par = opener.parent;  ');
			Win1.document.writeln(' 	} else {  ');
			Win1.document.writeln('	        	t = opener; ');
			Win1.document.writeln('			par = opener;  ');
			Win1.document.writeln('		}  ');
			Win1.document.writeln(' } else {  ');
			Win1.document.writeln('		if (parent.MapFrame) {  ');
			Win1.document.writeln('			t = parent.MapFrame;  ');
			Win1.document.writeln('			par = parent;  ');
			Win1.document.writeln('		} else {  ');
			Win1.document.writeln('			t=document;  ');
			Win1.document.writeln('		}  ');
			Win1.document.writeln('	}  ');
			Win1.document.writeln('	function loadHelp(){  ');
			Win1.document.writeln('     var Win2;  ');
			Win1.document.writeln('	    Win2 = window.open("http://" + hostName + "/website/public/helpGeocodeResults.htm","Help","width=800,height=550,scrollbars=yes,resizable=yes");  ');
			Win1.document.writeln('	    Win2 = null;  ');
			Win1.document.writeln('	}   ');	
			Win1.document.writeln('function parcelCleanup(GCX,GCY) {   ');
			Win1.document.writeln('		t.getPPN(GCX,GCY); ');			
			Win1.document.writeln('		//window.close();		');
			Win1.document.writeln('	} ');
			Win1.document.writeln('function votingCleanup(GCadd,GCX,GCY) {   ');
			Win1.document.writeln('		t.geocodeX = GCX;		');
			Win1.document.writeln('		t.geocodeY = GCY;		');
			Win1.document.writeln('		t.geocodeLabel = GCadd;		');
			Win1.document.writeln('		t.GCpointCount = 1;		'); 
			Win1.document.writeln('		t.autoVotingFrontEnd(GCadd,GCX,GCY); ');			
			Win1.document.writeln('		//window.close();		');
			Win1.document.writeln('	} ');	
			Win1.document.writeln('</script></head>');
			Win1.document.writeln('<body bgcolor=#006600 text=#006600 link="Blue" vlink="Blue" LEFTMARGIN=0 onload="window.focus();" onunload="t.clearSelection"><center>');
			Win1.document.writeln('<FONT COLOR="White" FACE="Arial" SIZE="0"><b>');
			if (toolMode == 7) Win1.document.writeln('Possible Matches');
			else Win1.document.writeln('Locate Results');
			Win1.document.writeln('</b>');
			if (toolMode == 7) {
				Win1.document.writeln('<br><FONT COLOR="White" FACE="Arial" SIZE="-1"><b>');
				Win1.document.writeln('Click the number of the address you are looking for');
				Win1.document.writeln('</b>');
			}
			if (isPublic) Win1.document.write('&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://" + hostName + "/website/KCRC/KCRC_Images/buttonnarr_help.gif" width=20 height=20 hspace=1 vspace=1 border=0 alt="Help" name="help" onmousedown="loadHelp()">');
			Win1.document.writeln('<table border="1" cellspacing="0" cellpadding="2" nowrap bgcolor=#ffff99>');
			Win1.document.writeln('<tr><th><FONT FACE="Arial" SIZE="-1" color="#006600">#</font></th><th><FONT FACE="Arial" SIZE="-1" color="#006600">Address</font></th><th><FONT FACE="Arial" SIZE="-1" color="#006600">Score</th></tr>');
			for (var i=0;i<GCpointCount;i++) {
				Win1.document.writeln('<tr>');
				Win1.document.writeln('<td><FONT FACE="Arial" SIZE="-1"><a href="javascript:' + theFrame + '.zoomToPoint(' + GCpointX[i] + ',' + GCpointY[i] + ',true,\'' + GCaddress[i] + '\')">' + (i+1) + '</a></font></td>');
				Win1.document.writeln('<td><FONT FACE="Arial" SIZE="-1" color="#006600">' + GCaddress[i] + '</font></td>');
				Win1.document.writeln('<td><FONT FACE="Arial" SIZE="-1" color="#006600">' + GCscore[i] + '</font></td>');
				if (loadThisService == "Public_Parcel_Find" && GCLayers[GCActiveLayer] == "Parcel Geocoding") {
					Win1.document.writeln('<td><input type="button" value="More Details!" onClick="parcelCleanup(' + GCpointX[i] + ',' + GCpointY[i] + ')" style="font-size: xx-small; font-weight: bold; color: #000000; background: #ffff99;"></td>');
				}
				if (loadThisService == "Public_Voting" && runningVoterSearch) {
					GCaddress[i] = GCaddress[i].toString();
					//alert(GCaddress[i]);
					Win1.document.writeln('<td><input type="button" value="This One!" onClick="votingCleanup(\'' + GCaddress[i] + '\',' + GCpointX[i] + ',' + GCpointY[i] + ')" style="font-size: xx-small; font-weight: bold; color: #000000; background: #ffff99;"></td>');
				}
				Win1.document.writeln('</tr>');
			}
			Win1.document.writeln('</table></form>');
			if ((GCpointCount > 1) && (toolMode != 7)) {
				Win1.document.writeln('<font color="#FFFFFF">Click on any number to view that feature on the map</font>');
			}
			if (toolMode == 35) {
				Win1.document.writeln('<br><br><input type="button" onclick="t.clickFunction(\'geocode\');" value="Locate Another Address" style="font-size: xx-small; font-weight: bold; color: #000000; background: #ffff99;"></form>');
			}
			if (toolMode == 14) {
				Win1.document.writeln('<br><br><input type="button" onclick="t.clickFunction(\'busfind\');" value="Locate Another Bus Stop/Route" style="font-size: xx-small; font-weight: bold; color: #000000; background: #ffff99;"></form>');
			}
			if (isPublic) {
				Win1.document.writeln('<input type="button" onclick="t.clearSelection()" value="Remove Address Label" style="font-size: xx-small; font-weight: bold; color: #000000; background: #ffff99;">');
			}
			Win1.document.writeln('</center>')
			Win1.document.close();
		}
		//if (GCpointCount==1) sendMapXML();
        	var gcptx = parseFloat(GCpointX[0]);
	 	var gcpty = parseFloat(GCpointY[0]);
		if (GCpointCount==1) {
			//Win1.close();
			zoomToPoint(gcptx, gcpty, true, geocodeLabel);
		} else {
			customLeft = 12653337.8922337;
			customBottom = 457815.573216434;
			customRight = 12904653.6029823;
			customTop = 662912.30267793;
			useCustomCoords = true;
			sendMapXML();
		}
		Win1=null;
	} else {
		//no match
		alert("The address you requested does not currently exist in our street or parcel address databases.\nThis may occur frequently with apartment complexes and mobile home parks.\nTry the address again, or if you believe an error has occurred, contact the REGIS Help Desk at the address shown on the 'IMS Home' page.");
		if (useTextFrame) parent.TextFrame.location=appDir + "addmatch.htm";
		if (runningVoterSearch) clickFunction("votingfind");
	}
}

