/********************************
	Geocode style parameters
	
	Supported styles:
	
	GeocodeDdcUSA
	
	Layers: streets
			Zip5

********************************/

aimsRoutePresent = true;

var imsRouteURL = serverURL + "newstore&CustomService=SDCGeocode";
var imsGeocodeURL = serverURL + "newstore&CustomService=SDCGeocode";

var useSdcGeocode = true;

var minScaleLimit = 0.00000025; // world units per pixel
var zoomToStopScale = 0.00004;

// input
var RTStopNames = new Array();
var RTStopDesc = new Array();
var RTStopsCount = 0;
var RTStopX = new Array();
var RTStopY = new Array();
var RTType = "quickest"; // or "shortest"
var RTHwyPref = 50;
var RTPrecision = 0.0;
var RTStopsChanged = false;

// result
var RTEnvelope = null; // Envelope object
var RTSegments = null; // array of RouteSegment objects
var RTSegmentsCount = 0;
var RTTotals = null; // RouteTotals object
var RouteResult = false;

var locationBlurb = "";
var addressStyle = "address"; // address or range

var printDirections = false;

var zoomToGCPoint = false;

var showRouting = false;

var currZip = "";



// parse out routing response
function parseRoutingResults( theReply ) {
    var startpos = 0;
    var endpos = 0;
    
    RouteResult = false;
    showRouting = false;

    var str = '<ROUTE';
    var pos = theReply.indexOf(str, 0);
    
    if ( pos != -1 ) {
        // parse full route envelope
        var routestart = pos + str.length;
        str = '<ENVELOPE';
        pos = theReply.indexOf(str, routestart);
        if ( pos == -1 ) return; // error
        RTEnvelope = parseEnvelope(theReply, pos);
        if ( RTEnvelope == null ) return; // error
        RTEnvelope = inflateEnvelope( RTEnvelope, 0.1 );
        // parse route parts
        str = '<PARTS>';
        pos = theReply.indexOf(str, routestart);
        if ( pos != -1 ) {
            var partsstartpos = pos + str.length;
            var partsendpos = theReply.indexOf('</PARTS>', partsstartpos);
            if ( partsendpos == -1 ) return; // error

            RTSegments = new Array();
            RTSegmentsCount = 0;
            
            // parse part data
            str = '<PART';
            pos = theReply.indexOf(str, partsstartpos);
            while ( pos != -1 && pos < partsendpos ) {
                var partstart = pos + str.length;
                var partend = theReply.indexOf('</PART>', partstart);
                if ( partend == -1 ) return; // error
                
                // parse segments
                str = '<SEGMENT';
                pos = theReply.indexOf(str, partstart);
                while ( pos != -1 && pos < partend ) {
                    var segstart = pos + str.length;
                    var segend = theReply.indexOf('</SEGMENT>', segstart);
                    if ( partend == -1 ) return; // error
                    
                    var nSeg = RTSegmentsCount;
                    RTSegments[nSeg] = new RouteSegment();
                    RTSegmentsCount++;
                    
                    // get segment distance and time
                    str = '>';
                    pos = theReply.indexOf(str, segstart);
                    var strTag = theReply.substring(segstart, pos + str.length);
                    var d = parseAttrib( strTag, 'distance' );
                    var t = parseAttrib( strTag, 'time' );
                    if ( d == null || t == null ) return; // error
                    RTSegments[nSeg].distance = parseFloat(d);
                    RTSegments[nSeg].time = parseFloat(t);
                        
                    // parse segment envelope               
                    str = '<ENVELOPE';
                    pos = theReply.indexOf(str, segstart);
                    if ( pos == -1 || pos >= segend ) return; // error
                    RTSegments[nSeg].envelope = parseEnvelope(theReply, pos);
                    if ( RTSegments[nSeg].envelope == null ) return; // error
                    RTSegments[nSeg].envelope = inflateEnvelope( RTSegments[nSeg].envelope, 0.1 );
                        
                    // parse segment descriptions
                    RTSegments[nSeg].desc = new Array();
                    var nDesc = 0;
                    
                    str = '<DESCRIPTION>';
                    pos = theReply.indexOf(str, segstart);
                    while ( pos != -1 && pos < segend ) {
                        startpos = pos + str.length;
                        str = '</DESCRIPTION>';
                        pos = theReply.indexOf(str, startpos);

                        if ( (pos == -1) || (pos >= segend) )  return; // error
                        RTSegments[nSeg].desc[nDesc] = theReply.substring(startpos, pos);
                        nDesc++;

                        str = '<DESCRIPTION>';
                        pos = theReply.indexOf(str, pos);
                    }
                    
                    // get segment shape coords
                    str = '<POLYLINE>';
                    pos = theReply.indexOf(str, segstart);
                    if ( pos != -1 && pos < segend ) {
                        var startpoly = pos + str.length;
                        str = '</POLYLINE>';
                        var endpoly = theReply.indexOf(str, startpoly);
                        if ( endpoly == -1 || endpoly >= segend ) return; // error
                            
                        RTSegments[nSeg].shape = new Array();
                        var nPath = 0;
                        
                        // parse each <PATH> of polyline
                        str = '<PATH>';
                        var startpath = theReply.indexOf(str, startpoly);
                        if ( startpath == -1 || startpath >= endpoly ) return; // error
                        while ( startpath != -1 && startpath < endpoly ){
                            str = '</PATH>';
                            var endpath = theReply.indexOf(str, startpath);
                            if ( endpath == -1 || endpath >= endpoly ) return; // error
                                
                            str = '<COORDS>';
                            var startcoord = theReply.indexOf(str, startpath);
                            if ( startcoord == -1 || startcoord >= endpath ) return; // error
                            var startdata = startcoord + str.length;
                                
                            str = '</COORDS>';
                            var endcoord = theReply.indexOf(str, startcoord);
                            if ( endcoord == -1 || endcoord >= endpath ) return; // error
                            
                            RTSegments[nSeg].shape[nPath] = theReply.substring(startdata, endcoord);
                            nPath++;
                            
                            // parse next <PATH> of polyline
                            str = '<PATH>';
                            var startpath = theReply.indexOf(str, endpath);
                        }
                    } else {
						// no shape for that segment due to generalization
                        RTSegments[nSeg].shape = null;
                    }

                    // next segment                 
                    str = '<SEGMENT';
                    pos = theReply.indexOf(str, segend);
                }

                // next part
                str = '<PART';
                pos = theReply.indexOf(str, partend);
            }
        } else {
            return; // error
		}
        // parse route totals
        str = '<TOTALS';
        startpos = theReply.indexOf(str, routestart);
        if ( startpos == -1 )  return; // error
        str = '</TOTALS>';
        endpos = theReply.indexOf(str, startpos);
        if ( endpos == -1 ) return; // error
        
        RTTotals = new RouteTotals();
        
        // get totals distance and time
        str = '>';
        pos = theReply.indexOf(str, startpos);
        var strTag = theReply.substring(startpos, pos + str.length);
        var d = parseAttrib( strTag, 'distance' );
        var t = parseAttrib( strTag, 'time' );
        if ( d == null || t == null ) return; // error
        RTTotals.distance = parseFloat(d);
        RTTotals.time = parseFloat(t);

        // get totals descriptions
        RTTotals.desc = new Array();
        var nDesc = 0;
        
        str = '<DESCRIPTION>';
        pos = theReply.indexOf(str, startpos);
        while ( pos != -1 && pos < endpos ) {
            startpos = pos + str.length;
            str = '</DESCRIPTION>';
            pos = theReply.indexOf(str, startpos);

            if ( (pos == -1) || (pos >= endpos) ) return; // error
                
            RTTotals.desc[nDesc] = theReply.substring(startpos, pos);
            nDesc++;

            str = '<DESCRIPTION>';
            pos = theReply.indexOf(str, pos);
        }
        
        // success
        RouteResult = true;
        showRouting = true;
    }
}

// display results in table
function displayRoutingResults() {
    if ( showRouting ) {
		var url = appDir + "directions.htm";
		if ((useExternalWindow) || (!useTextFrame)) {
			Win1 = window.open(url,"GeocodeWindow","width=575,height=120,scrollbars=yes,resizable=yes");
		} else {
			parent.TextFrame.document.location = url;
		}
        zoomToRouteEnvelope( RTEnvelope.minx, RTEnvelope.miny, RTEnvelope.maxx, RTEnvelope.maxy );
    } else {
        // Route was not found
        alert("Unable to find route.");
    }
}

// add routing polyline and segment points to map XML
function addRouteToMapXML( mapXML ) {
    var xml = "";
    
    if ( RouteResult && showRouting ) {
        // test that we have some shape to show on map
        var bShow = false;
        var route = "";
        for ( var i = 0; i < RTSegmentsCount; i++ )
            if ( RTSegments[i].shape != null ) {
                bShow = true;
                
                // construct segment from its parts
                for ( var j = 0; j < RTSegments[i].shape.length; j++ ) {
                    route += '<OBJECT units="DATABASE">\n';
                    route += '<LINE coords="' + RTSegments[i].shape[j] + '">\n';
                    route += '<SIMPLELINESYMBOL transparency="0.5" type="solid" width="' + routeLineWidth + '" captype="round" jointype="round" color="' + routeLineColor  + '" />\n';
                    route += '</LINE>\n';
                    route += '</OBJECT>\n';
                }
            }
        
        if ( bShow ) {     
            xml += '<LAYER type="ACETATE" name="Route">\n';
            xml += route;
        
            // segment points
            var xy = null;
            for ( i = 1; i < RTSegmentsCount; i++ ) {
                xy = getSegStartPoint(i);
                if ( xy != null ) {
                    xml += '<OBJECT units="DATABASE">\n<POINT coord="' + xy[0] + coordsDelimiter + xy[1] + '">\n';
                    xml += '<SIMPLEMARKERSYMBOL type="Circle" color="' + routeStopColor + '" width="' + routeStopSize + '" />\n</POINT></OBJECT>\n';
                    xml += '<OBJECT units="DATABASE">\n<TEXT coord="' + xy[0] + coordsDelimiter + xy[1] + '" label="' + (i+1) + '">\n';
                    xml += '<TEXTMARKERSYMBOL fontcolor="' + routeStopLabelColor + '" fontsize="' + routeStopLabelWidth + '" outline="255,255,255" overlap="false" interval="4" /></TEXT></OBJECT>\n';
                }
            }

            // start location
            xy = getSegStartPoint(0);
            if ( xy != null ) {
                xml += '<OBJECT units="DATABASE">\n<POINT coord="' + xy[0] + coordsDelimiter + xy[1] + '">\n';
                xml += '<SIMPLEMARKERSYMBOL type="Circle" color="' + routeStartColor + '" width="' + routeStartSize + '" />\n</POINT></OBJECT>\n';
                xml += '<OBJECT units="DATABASE">\n<TEXT coord="' + xy[0] + coordsDelimiter + xy[1] + '" label="START">\n';
                xml += '<TEXTMARKERSYMBOL fontcolor="' + routeStartLabelColor + '" fontsize="' + routeStartLabelWidth + '" shadow="64,64,64" glowing="255,255,0" halignment="right" valignment="top" overlap="false" /></TEXT></OBJECT>\n';
            }

            // finish location
            xy = getSegFinishPoint(RTSegmentsCount-1);
            if ( xy != null ) {
                xml += '<OBJECT units="DATABASE">\n<POINT coord="' + xy[0] + coordsDelimiter + xy[1] + '">\n';
                xml += '<SIMPLEMARKERSYMBOL type="Circle" color="' + routeFinishColor + '" width="' + routeFinishSize + '"/>\n</POINT></OBJECT>\n';
                xml += '<OBJECT units="DATABASE">\n<TEXT coord="' + xy[0] + coordsDelimiter + xy[1] + '" label="FINISH">\n';
                xml += '<TEXTMARKERSYMBOL fontcolor="' + routeFinishLabelColor + '" fontsize="' + routeFinishLabelWidth + '" shadow="64,64,64" glowing="255,255,0" halignment="right" valignment="top" overlap="false" /></TEXT></OBJECT>\n';
            }
            
            xml += '</LAYER>\n';
        }
    }
    
    //alert(xml);
    
    return mapXML + xml;
}

// get coordinates of route segment start point
function getSegStartPoint(nSeg) {
    var coords = null;
    
    if ( RTSegments != null && RTSegments[nSeg].shape != null ) {
        var pairs = RTSegments[nSeg].shape[0].split(pairsDelimiter);
        if ( pairs != null && pairs.length > 0 ) {
            coords = pairs[0].split(coordsDelimiter);
        }
    }
    
    return coords;
}

// get coordinates of route segment finish point
function getSegFinishPoint(nSeg) {
    var coords = null;
    
    if ( RTSegments != null && RTSegments[nSeg].shape != null ) {
        var last = RTSegments[nSeg].shape.length - 1;
        var pairs = RTSegments[nSeg].shape[last].split(pairsDelimiter);
        if ( pairs != null && pairs.length > 0 ) {
            last = pairs.length - 1;
            coords = pairs[last].split(coordsDelimiter);
        }
    }
    
    return coords;
}


// add point to route points list
function addStop(x, y, name, desc) {
    //alert('Stop: ' + x + ',' + y + ',' + name + ',' + desc + '\nRTStopsCount: ' + RTStopsCount);
    
    if ( RTStopsCount > 0 ) {
        var last = RTStopsCount - 1;
        if ( (RTStopNames[last] == name) && (RTStopDesc[last] == desc) && (RTStopX[last] == x) && (RTStopY[last] == y) )
            return; // don't add the same stop
    }
    
    RTStopNames[RTStopsCount] = name;
    RTStopDesc[RTStopsCount] = desc;
    RTStopX[RTStopsCount] = x;
    RTStopY[RTStopsCount] = y;
    RTStopsCount++;

    RTStopsChanged = true;

    //RouteFrame.location = appDir + "findrouteframe.htm";
	//MapFrame.location = appDir + "findrouteframe.htm";
	var url = appDir + "routepage.htm";
	if ((useExternalWindow) || (!useTextFrame)) {
		Win1 = window.open(url,"GeocodeWindow","width=575,height=120,scrollbars=yes,resizable=yes");
	} else {
		parent.TextFrame.document.location = url;
	}
}

// swap stops
function moveStop( from, to ) {
    var tmpName = RTStopNames[to];
    var tmpDesc = RTStopDesc[to];
    var tmpX = RTStopX[to];
    var tmpY = RTStopY[to];

    RTStopNames[to] = RTStopNames[from];
    RTStopDesc[to] = RTStopDesc[from];
    RTStopX[to] = RTStopX[from];
    RTStopY[to] = RTStopY[from];

    RTStopNames[from] = tmpName;
    RTStopDesc[from] = tmpDesc;
    RTStopX[from] = tmpX;
    RTStopY[from] = tmpY;

    RTStopsChanged = true;
}

// route segment object constructor
function RouteSegment() {
    this.distance = 0.0; // segment distance
    this.time = 0.0; // segment time
    this.envelope = null; // segment envelope
    this.desc = null; // array of segment directions 
    this.shape = null; // array of segment parts
}

// route totals object constructor
function RouteTotals() {
    this.distance = 0.0;
    this.time = 0.0;
    this.desc = null; // array of totals descriptions
}

function writeRouteXML() {
    var theRequest = '<ARCXML version="1.1">\n<REQUEST>\n<GET_ROUTE name="">\n';

    // add stops to request
    theRequest += '<STOPSLIST>\n';
    var str = '';
    for ( var i = 0; i < RTStopsCount; i++ ){
        str = RTStopDesc[i];
        theRequest += '<ROUTE_STOP id="' + i + '" desc="' + makeXMLsafe(str) +'">\n';
        theRequest += '<POINT x="' + RTStopX[i] + '" y="' + RTStopY[i] + '"/>\n</ROUTE_STOP>\n';
    }
    theRequest += '</STOPSLIST>\n';

    // add clipping envelope
    var clip = calcClipEnvelope();
    var e = calcRouteClipEnvelope(clip);
    theRequest += '<ROUTEFILTER>\n';
    theRequest += '<ENVELOPE minx="' + e.minx + '" miny="' + e.miny + '" maxx="' + e.maxx + '" maxy="' + e.maxy + '"/>\n';
    theRequest += '</ROUTEFILTER>\n';

    // add route properties
    theRequest += '<ROUTE_PROPERTIES>\n';
    theRequest += '<ROUTETYPE>' + RTType + '</ROUTETYPE>\n';
    theRequest += '<HWYPREF>' + RTHwyPref + '</HWYPREF>\n';

    RTPrecision = calcScale(clip);
    theRequest += '<PRECISION>' + RTPrecision + '</PRECISION>\n';

    theRequest += '</ROUTE_PROPERTIES>\n';
    theRequest += '</GET_ROUTE>\n</REQUEST>\n</ARCXML>\n';

    //alert( theRequest );
    return theRequest;
}

// change envelope size
function inflateEnvelope( env, coef ) {
    var H = Math.abs(env.maxy - env.miny);
    var W = Math.abs(env.maxx - env.minx);
    var nDX = W * coef;
    var nDY = H * coef;
    env.maxx += nDX;
    env.maxy += nDY;
    env.minx -= nDX;
    env.miny -= nDY;
    return env;
}

// clear route results
function clearRouteResults(){
    if ( !RouteResult && !showRouting ) // nothing to clear
        return;
    RouteResult = false;
    showRouting = false;
}

// calculate clipping envelope
function calcClipEnvelope(){
    var env = new Envelope( eLeft, eBottom, eRight, eTop );
    var H = eTop - eBottom;
    var W = eRight - eLeft;
    var centerX = eRight - W / 2;
    var centerY = eTop - H / 2;
    var dH = H / iHeight;
    var dW = W / iWidth;

    if ( dH > dW ){
        W = H * iWidth / iHeight;
        env.minx = centerX - W / 2;
        env.maxx = centerX + W / 2;
    } else if ( dH < dW ) {
        H = W * iHeight / iWidth;
        env.miny = centerY - H / 2;
        env.maxy = centerY + H / 2;
    }

    return env;
}

// calculate clipping envelope for routing request
function calcRouteClipEnvelope(clip) {
    var iDelta = Math.max(routeLineWidth, routeStopSize);
    iDelta = Math.max(iDelta, routeStopLabelWidth);
    iDelta = Math.max(iDelta, routeStartSize);
    iDelta = Math.max(iDelta, routeStartLabelWidth);
    iDelta = Math.max(iDelta, routeFinishSize);
    iDelta = Math.max(iDelta, routeFinishLabelWidth);
    iDelta /= 2; // screen 
    var wDelta = iDelta * calcScale(clip); // world
    var env = clip;
    env.minx -= wDelta;
    env.maxx += wDelta;
    env.miny -= wDelta;
    env.maxy += wDelta;
    return env;
}

// point visibility test
function visiblePoint( x, y ) {
    if ( (x >= eLeft) && (x <= eRight) && (y >= eBottom) && (y <= eTop) )
        return true;
    return false;
}

// calculate scale for given extent and map view sizes
function calcScale( e ) {
    var dx = (e.maxx - e.minx) / iWidth;
    var dy = (e.maxy - e.miny) / iHeight;
    return Math.min( dx, dy );
}

// zoom to point on scale specified
function zoomToScale(x, y, scale) {
    var wWidth = scale*iWidth;
    var wHeight = scale*iHeight;
	//alert("Mode: " + mode + "\nModule: " + appModule);
    eLeft = x - wWidth/2;
    eRight = x + wWidth/2;
    eTop = y + wHeight/2;
    eBottom = y - wHeight/2;
    sendMapXML();
}

// zoom to point and place label
function zoomToPointScale(xIn, yIn, drawIt, theLabel, scale) {
    if (drawIt) {
        showGeocode = true;
        geocodeX = xIn;
        geocodeY = yIn;
        geocodeLabel = theLabel;
    }
    zoomToScale(xIn, yIn, scale);
}

function parseEnvelope( theReply, start ) {
    var str = '<ENVELOPE';
    var pos = theReply.indexOf(str, start);
    if ( pos != -1 ) {
        var startpos = pos + str.length;
        str = '/>';
        var endpos = theReply.indexOf(str, startpos);
        if ( endpos != -1 ) {
            endpos += str.length;
            var strTag = theReply.substring(pos, endpos); // get <ENVELOPE.../> tag
            strTag = strTag.toUpperCase();
            var minx = parseAttrib( strTag, 'MINX' );
            var miny = parseAttrib( strTag, 'MINY' );
            var maxx = parseAttrib( strTag, 'MAXX' );
            var maxy = parseAttrib( strTag, 'MAXY' );
            if ( (minx != null) && (miny != null) && (maxx != null) && (maxy != null) ) {
                var envelope = new Envelope(parseFloat(minx), parseFloat(miny), parseFloat(maxx), parseFloat(maxy));
                return envelope;
            }
        }
    }
    return null;
}

function parseAttrib( Tag, Attr ) {
    var Attr1 = Attr + '=';
    var pos = Tag.indexOf( Attr1, 0 );
    if ( pos != -1 ) {
        pos += Attr1.length;
        var endpos = Tag.indexOf( ' ', pos );
        if ( endpos == -1 )
            endpos = Tag.indexOf( '/>', pos );
        if ( endpos == -1 )
            endpos = Tag.indexOf( '>', pos );
            
        if ( endpos != -1 ) {
            var str = Tag.substring( pos, endpos );
            str = str.replace(/"/g, ''); // remove "
            str = clearLeadingSpace( str );

            return str;
        }
    }

    return null;
}

// envelope constructor
function Envelope( minx, miny, maxx, maxy ) {
    this.minx = minx;
    this.miny = miny;
    this.maxx = maxx;
    this.maxy = maxy;
}


function zoomToRouteEnvelope(minXin,minYin,maxXin,maxYin) {
    eLeft=minXin;
    eBottom=minYin;
    eRight=maxXin;
    eTop=maxYin;
	//alert("Envelope: " + minXin + ", " + minYin + ", " + maxXin + ", " + maxYin);
	if ((eLeft==eRight) || (eTop==eBottom)) {
	    var wWidth = zoomToStopScale*iWidth;
	    var wHeight = zoomToStopScale*iHeight;
	    eLeft = minXin - wWidth/2;
	    eRight = minXin + wWidth/2;
	    eTop = minYin + wHeight/2;
	    eBottom = minYin - wHeight/2;
	} 
	
    sendRouteMapXML();
    
}

function sendRouteMapXML() {
    if ( showRouting )
    {
        // send request to get routing data for current map extent
        var theText = writeRouteXML();
		showRetrieveMap();
        sendRouteRequest(theText, 9002 );
    }
    else
    {
        sendMapXML();
    }
}


function writeAddressXML() {
	var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_GEOCODE maxcandidates="10" minscore="80" >\n';
	theString += '<LAYER id="ReverseAddress" />\n<ADDRESS>\n';
	theString += '<GCTAG id="x" value="' + mapX + '" />\n';
	theString += '<GCTAG id="y" value="' + mapY + '" />\n';
	theString += '<GCTAG id="style" value="' + addressStyle + '" />\n';
	theString += '</ADDRESS>\n</GET_GEOCODE>\n</REQUEST>\n</ARCXML>\n';
	return theString;
}		
		
// get approximate address
function address(e) {
		highlightedOne="";
		var theX = mouseX;
		var theY = mouseY;
		getMapXY(theX,theY);
		showRetrieveData();
		var theRequest = writeAddressXML();
		sendToServer( imsRouteURL, theRequest, 27 );
}

function writeRGCresultPage(theReply) {
	if ((useExternalWindow) || (!useTextFrame)) {
		Win1 = window.open("","AddressWindow","width=575,height=120,scrollbars=yes,resizable=yes");
		theFrame = "opener";
		if (parent.MapFrame!=null) theFrame = "opener.parent.MapFrame";
	} else {
		Win1 = parent.TextFrame;
		Win1.document.open();
	}
	Win1.document.open();
	Win1.document.writeln('<meta http-equiv="Content-Type" content="text/html; charset=' + charSet + '"><html><head><title>Calculate Address Results</title></head>');
	Win1.document.writeln('<body bgcolor="' + tableBackColor + '" text="Black" link="Blue" vlink="Gray" LEFTMARGIN=0 onload="window.focus()">');
	Win1.document.writeln('<center><FONT FACE="Arial" SIZE="-1"><b>' + theReply + '</b>');
	Win1.document.writeln('</font></center></body></html>');
	Win1.document.close();

}

// write out the geocode XML request
function writeZipGeocodeXML() {
    var theString = '<ARCXML version="1.1">\n<REQUEST>\n<GET_GEOCODE  maxcandidates="' + maxGeocodeCandidates + '" minscore="' + minGeocodeScore + '">\n';
    theString += '<LAYER id="' + zipLayerId + '" />\n';
    theString += '<ADDRESS>\n';
    theString += '<GCTAG id="' + zipLayerInput + '" value="' + currZip + '"/>\n';
    theString += '</ADDRESS>\n</GET_GEOCODE>\n</REQUEST>\n</ARCXML>\n';
    //alert(theString);
    return theString;
    
}



// send custom XML request. . . set up custom response handler
function sendRouteRequest(XMLRequest, theType) {
	var theFunction = "parent.MapFrame.processRouteXML";
	var theForm = parent.PostFrame.document.forms[0];
	theForm.JavaScriptFunction.value = theFunction;
	sendToServer(imsRouteURL,XMLRequest,theType);
}

function sendRouteQuery(XMLRequest, theType) {
	var theFunction = "parent.MapFrame.processRouteXML";
	var theForm = parent.PostFrame.document.forms[0];
	theForm.JavaScriptFunction.value = theFunction;
	sendToServer(imsQueryURL,XMLRequest,theType);
}


function processRouteXML(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 9001:
			// routing response
			//alert("XMLMode: 9001");
			showRetrieveData();
	        clearRouteResults();
	        parseRoutingResults(theReply);
			hideRetrieveData();
	        displayRoutingResults();	
			break;
			
		case 9002:
			//alert("XMLMode: 9002");
			showRetrieveData();
	        clearRouteResults();
	        parseRoutingResults(theReply);
			hideRetrieveData();
			//showRetrieveMap();
	        sendMapXML();
			break;
		case 9003:
			// select product by polygon shape
			if (theReply.indexOf("minx=")!=-1) {
			
			
				getXYs(theReply);
				t.getBufferedData = true;
				t.drawTargetLayer=true;
				aimsBufferPresent=true;
				showGeocode=false;
				bufferIt();
				
				
			} else {
				alert("Unable to find location.");

            			
			}
			break;		
		case 9004:
			// zoom into feature envelope
			if (theReply.indexOf("minx=")!=-1) {
				getXYs(theReply);
				showGeocode=false;
				if(AddSearchMode=="city"){
					searchTolerance=0.05
					eLeft = eLeft - searchTolerance;
					eTop = eTop + searchTolerance;
					eRight = eRight + searchTolerance;
					eBottom = eBottom - searchTolerance;
				}
				t.zoomToEnvelope(eLeft,eBottom,eRight,eTop);
			
			} else {
				alert("Unable to find location.");
			}
			
			break;
		case 9005:
			// select product by point
			if (theReply.indexOf("minx=")!=-1) {
				getXYs(theReply);
				var activeindex = parent.productFrame.document.productform.products.options[parent.productFrame.document.productform.products.selectedIndex].value;
				searchTolerance=0.001
				var tempWest = eLeft - searchTolerance;
				var tempNorth = eTop + searchTolerance;
				var tempEast = eRight + searchTolerance;
				var tempSouth = eBottom - searchTolerance;
				queryStartRecord=1;
				showGeocode=false;
				var theString = writeGetFeatures2(tempWest,tempSouth,tempEast,tempNorth);
				selectEnvelope='maxy="' + forceComma(tempNorth) + '" maxx="' + forceComma(tempEast) + '" miny="' + forceComma(tempSouth) + '" minx="' + forceComma(tempWest) + '"';
				drawSelectBoundary=true;
				showBuffer=false;
				selectionMode=2;
					//if (useTextFrame) parent.TextFrame.document.location = "text.htm";
	sendToServer(imsQueryURL,theString,selectXMLMode);

			} else {
				//alert("Unable to find location.");
            			var theText = writeZipGeocodeXML();
				zoomToGCPoint=true;
				geocodeAppMode="address";
				showRetrieveData();
            			sendToServer(imsGeocodeURL, theText, 27);
            			
			}
			break;			
			
	}
}

function openAreaDialog() {
	var url = appDir + "areaWindow.htm";
	if (useTextFrame) {
		parent.TextFrame.document.location = url;
	} else {
		Win1 = open(url,"AreaWindow","width=375,height=350,scrollbars=yes,resizable=yes");
	}
}
