//all functions for geocoding and verifying origin and destination here

/*************************side note************************************
 * Had to disable the image submit function by using return false. This
 * is because the form would submit in FF before the ASP came back with
 * the XML results, and it could be parsed. Therefore, variables were 
 * empty or undefined. Now, instead, after we grab all data and make
 * sure we get the XML back, we submit the form using the submitForm function.    
 * 
 * Also remember to protect against user entering :@@: in the startpoint
 * or end point. We will use :@@: as a string delimiter if there are 
 * ambiguous results returned. Store in a hidden var and split when the
 * page gets reloaded.
 *
 **********************************************************************/   
//globals

//set timeout period for geocoding - fails and sends message to user if geocoding fails
var geoTimeout; //value set in ini file
  
var xmlHttpFrom = createXmlHttpRequestObject();
var xmlHttpTo = createXmlHttpRequestObject();
var myCoords = "";
var googleFailed = false;
var fromGeocoded = false;
var toGeocoded = false;
var geocodeCheckInterval = "";
var geoRequestFailed = false;
  
// creates an XMLHttpRequest instance
//for error checking
function createXmlHttpRequestObject() {
    // will store the reference to the XMLHttpRequest object
    var xmlHttp;
    // this should work for all browsers except IE6 and older
    try {
        // try to create XMLHttpRequest object
        xmlHttp = new XMLHttpRequest();
    }
    catch(e) {
        // assume IE6 or older
        var XmlHttpVersions = new Array('MSXML2.XMLHTTP.6.0',
                                    'MSXML2.XMLHTTP.5.0',
                                    'MSXML2.XMLHTTP.4.0',
                                    'MSXML2.XMLHTTP.3.0',
                                    'MSXML2.XMLHTTP',
                                    'Microsoft.XMLHTTP');
        // try every prog id until one works
        for (var i=0; i<XmlHttpVersions.length && !xmlHttp; i++) {
            try { 
                // try to create XMLHttpRequest object
                xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
            } 
            catch (e) {}
        }
    }
    // return the created object or display an error message
    if (!xmlHttp) {
        var tmpString = "Error creating the XMLHttpRequest object.";
        submitForm(0, 'default.asp', tmpString);
    }
    else {
        return xmlHttp;
    }
}
  
function submitForm(formNumber, action, errorCode) {
	document.main.returnValue.value = errorCode;
	//alert("error code: " + errorCode);
	
    //submit form based on form number passed
    //this way this code can be reused to submit any form 
    //as long as the correct form number is passed.
    //action = "test.htm";
    
    if (document.main.showPNR.checked) {
        action = "pnr.asp";
    }
    document.forms[formNumber].action = action;
    document.forms[formNumber].submit();
}        
        
function getOandDInfo() {
    //hide input screen
    var mainTable = new getObj('TAInputScreen');
    mainTable.obj.style.visibility = "hidden";
        
    //show the please wait screen.
    showPleaseWaitScreen("Please wait while we retrieve your itinerary.");
   
    //grab startpoint and endpoint info and build string to send to 
	//DB, Google, or TranStar to geocode
	var startpoint = document.main.startpoint.value;
	var startcity = document.main.startcity.value;
	var startstate = document.main.startstate.value;
	var startzip = document.main.startzip.value;
	
	var endpoint = document.main.endpoint.value;
	var endcity = document.main.endcity.value;
	var endstate = document.main.endstate.value;
	var endzip = document.main.endzip.value;
	
    startpoint = replaceApos(startpoint);
    startcity = replaceApos(startcity);
    endpoint = replaceApos(endpoint);
    endcity = replaceApos(endcity);
    
    startpoint = replaceSpecialChars(startpoint);
    startcity = replaceSpecialChars(startcity);
    endpoint = replaceSpecialChars(endpoint);
    endcity = replaceSpecialChars(endcity);
    	
	//find out if we need to geocode the point again or if it was already stored	
	var geocodeStartPoint = checkStartAndEndValsToGeocode(startpoint, startcity, startstate, startzip, 'start');
	var geocodeEndPoint = checkStartAndEndValsToGeocode(endpoint, endcity, endstate, endzip, 'end');
		
	if(geocodeStartPoint) {
		//now create string to pass to Google
	    //coords have not been obtained yet. geocode startpoint
	    getXMLFrom(startpoint, startcity, startstate, startzip);	
	}
	else {
	    //startpoint already geocoded, either from map, passed back to page, or in cookie
	    //do not have to worry about geocoding again
	    fromGeocoded = true;
	}

	if(geocodeEndPoint) {
		//now create string to pass to Google
	    //coords have not been obtained yet. geocode endpoint
	    getXMLTo(endpoint, endcity, endstate, endzip);
	}
	else {
	    //startpoint already geocoded, either from map, passed back to page, or in cookie
	    //do not have to worry about geocoding again
	    toGeocoded = true;
	}
	
	//check for timeout of geocoding results - if it takes too long, we let user know
	//send back to homepage with error, global value is set up above
	setTimeout("submitForm("+0+",'default.asp','100')",geoTimeout);
	
	//check for results of geocoding every .001 seconds. 
	//when the results come back from both, we submit the form.
	geocodeCheckInterval = window.setInterval("checkForGeoResults()", 1);
	
}
	
function checkForGeoResults() {
    //repeatedly fires waiting for XML to come back - when it does, submit the form
    if (fromGeocoded && toGeocoded) {
	    window.clearInterval(geocodeCheckInterval);
	    if (document.main.fromAmbig.value == "true" || document.main.toAmbig.value == "true") {
            //we have ambiguous results, need to submit back to main page and let user know.
            submitForm(0, "default.asp", null);
        }
        else {
			submitForm(0, "results.asp", null); 
        }
	}
}

function getXMLFrom(streetAddress, city, state, zip) {
    
	//now create string to pass to Google
	//var fromAddress = concatAddressString('from', startpoint, startcity, startstate, startzip);
	//coords have not been obtained yet. geocode startpoint
	
	//call local url to begin geocode process - now let ASP handle the xml requests
	var url = "xml/callGetGeo.asp?streetAddress="+streetAddress+"&city="+city+"&state="+state+"&zip="+zip;

	//GLog.write(url);
	
	//open callGetXML to try to get geocode results and handle failure otherwise
	// only continue if xmlHttp isn't void
	if (xmlHttpFrom) {
		// try to connect to the server
		try {
		    // initiate reading a file from the server
			xmlHttpFrom.open("GET", url, true);
			xmlHttpFrom.onreadystatechange = handleRequestStateChangeFrom;
			xmlHttpFrom.send(null);
		}
		// display the error in case of failure
		catch (e) {
			//failed to get xml 
			submitForm(0, 'default.asp', e.toString());
		}
	}
	 
     
}//end function getXML

function getXMLTo(streetAddress, city, state, zip) {

	//now create string to pass to Google
	//var fromAddress = concatAddressString('from', startpoint, startcity, startstate, startzip);
	//coords have not been obtained yet. geocode startpoint
	
	//call local url to begin geocode process - now let ASP handle the xml requests
	var url = "xml/callGetGeo.asp?streetAddress="+streetAddress+"&city="+city+"&state="+state+"&zip="+zip;

	//GLog.write(url);
	
	//open callGetXML to try to get geocode results and handle failure otherwise
	// only continue if xmlHttp isn't void
	if (xmlHttpTo) {
		// try to connect to the server
		try {
		    // initiate reading a file from the server
			xmlHttpTo.open("GET", url, true);
			xmlHttpTo.onreadystatechange = handleRequestStateChangeTo;
			xmlHttpTo.send(null);
		}
		// display the error in case of failure
		catch (e) {
		    //failed to get xml 
			submitForm(0, 'default.asp', e.toString());
		}
	}
}

// function called when the state of the HTTP request changes
function handleRequestStateChangeFrom() {
    var tmpErrorMsg = "";
	
	// when readyState is 4, we are ready to read the server response
    if (xmlHttpFrom.readyState == 4) {
		// continue only if HTTP status is "OK"
        if (xmlHttpFrom.status == 200) {
            try {
                // do something with the response from the server
                handleServerResponseFrom();
            }
            catch(e) {
			    //invalid xml structure
			    submitForm(0, 'default.asp', e.toString());
            }
        } 
        else {
            tmpErrorMsg = xmlHttpFrom.status;
            submitForm(0, 'default.asp', tmpErrorMsg);
        }
    }
}
  
// handles the response received from the server for the origin request
function handleServerResponseFrom() {
    // read the message from the server
    //var xmlResponse = xmlHttp.responseXML;
    var xmlDoc = xmlHttpFrom.responseXML;
  
    // catching potential errors with IE and Opera
    //invalid xml structure
    if (!xmlDoc || !xmlDoc.documentElement)
        throw("Invalid XML Structure");
    // catching potential errors with Firefox
    var rootNodeName = xmlDoc.documentElement.nodeName;
    //invalid xml structure
    if (rootNodeName == "parsererror") 
        throw("Invalid XML Structure");
  
    //alert("from: " + xmlHttpFrom.responseText);
    
    var geoResponseStatus;
    
    var elem = xmlDoc.documentElement.getElementsByTagName("Status");
			
    if (elem.length > 0) {
        var code = xmlDoc.getElementsByTagName("Status")[0].firstChild.nodeValue;
	
		if (code == '0') {
		    //successful geocode
			//get geocoded coords - tag is coordinates
			var yCoord = xmlDoc.getElementsByTagName("Latitude")[0].firstChild.nodeValue;
		    var xCoord = xmlDoc.getElementsByTagName("Longitude")[0].firstChild.nodeValue;
		    
		    //check zip
		    var tmpZip = xmlDoc.getElementsByTagName("Zip")[0].firstChild.nodeValue;
		    
		    if (tmpZip == "NULL") {
		      tmpZip = "";
		    }
		    
		    document.main.startzip.value = tmpZip;
		     
			storeCoordinates('from', xCoord, yCoord);
		}//end if code = 0
		else if (code == '1' || code == '2') {
	        //geostatus is 1 or 2, ambiguous or spell check, return empty coords and store error code 
			//4-3-07 - also pass lat/longs to ambig results
			grabAmbigResults('from', code, xmlHttpFrom);
		}
		//else - if code fails, now we need to try something else so put code here
		else {
		    //no result for origin, set error code to 3
		    document.main.elements['fromAmbig'].value = "true";
		    document.main.elements['fromErrorCode'].value = '3';
		    fromGeocoded = true;
		    //GLog.write("fromGeocoded is: " + fromGeocoded);
		}//else if code != 0
    }//end if elem.length > 0
   
}//end function handleServerResponseFrom

// function called when the state of the HTTP request changes
function handleRequestStateChangeTo() {
    var tmpErrorMsg = "";
    // when readyState is 4, we are ready to read the server response
    if (xmlHttpTo.readyState == 4) {
		// continue only if HTTP status is "OK"
        if (xmlHttpTo.status == 200) {
            try {
                // do something with the response from the server
                handleServerResponseTo();
            }
            catch(e) {
			    //return error to default.asp
			    submitForm(0, 'default.asp', e.toString());
            }
        } 
        else {
		    tmpErrorMsg = xmlHttpTo.status;
            //return error to default.asp
            submitForm(0, 'default.asp', tmpErrorMsg);
        }
    }
}
  
// handles the response received from the server for the dest request
function handleServerResponseTo() {
    // read the message from the server
    //var xmlResponse = xmlHttp.responseXML;
    var xmlDoc = xmlHttpTo.responseXML;
  
    // catching potential errors with IE and Opera
    //invalid xml structure
    if (!xmlDoc || !xmlDoc.documentElement)
        throw("Invalid XML Structure");
    // catching potential errors with Firefox
    var rootNodeName = xmlDoc.documentElement.nodeName;
    //invalid xml structure
    if (rootNodeName == "parsererror") 
        throw("Invalid XML Structure");
 
    //alert("to: " + xmlHttpTo.responseText);
    
    var geoResponseStatus;
    
    var elem = xmlDoc.documentElement.getElementsByTagName("Status");
			
    if (elem.length > 0) {
        var code = xmlDoc.getElementsByTagName("Status")[0].firstChild.nodeValue;
	
		if (code == '0') {
		    //successful geocode
			//get geocoded coords - tag is coordinates
			var yCoord = xmlDoc.getElementsByTagName("Latitude")[0].firstChild.nodeValue;
		    var xCoord = xmlDoc.getElementsByTagName("Longitude")[0].firstChild.nodeValue;
		    
		    //check zip
		    var tmpZip = xmlDoc.getElementsByTagName("Zip")[0].firstChild.nodeValue;
		    
		    if (tmpZip == "NULL") {
		      tmpZip = "";
		    }
		    
		    document.main.endzip.value = tmpZip;
		    
			storeCoordinates('to', xCoord, yCoord);
		}//end if code = 0
		else if (code == '1' || code == '2') {
	        //geostatus is 1 or 2, ambiguous or spell check, return empty coords and store error code 
			//4-3-07 - also pass lat/longs to ambig results
			grabAmbigResults('to', code, xmlHttpTo);
		}
		//else - if code fails, now we need to try something else so put code here
		else {
		    //no result for destination, set error code to 3
		    document.main.elements['toAmbig'].value = "true";
		    document.main.elements['toErrorCode'].value = code;
		    toGeocoded = true;
		    //GLog.write("toGeocoded: " + toGeocoded);
		}//else if code != 0
    }//end if elem.length > 0
   
}//end function getXML

//store ambig results in hidden variables
function grabAmbigResults(pointType, code, xmlObject) {
   var xmlDoc = xmlObject.responseXML;
 
   var numAmbig = xmlDoc.getElementsByTagName("NumAmbiguous")[0].firstChild.nodeValue;
   
   var delimiterString = ":@@:";
        
   //clear hidden variable data because FireFox caches     
   document.main.elements[pointType+'Ambig'].value = "true";
   document.main.elements[pointType+'AmbigAddress'].value = "";
   document.main.elements[pointType+'AmbigCity'].value = "";
   document.main.elements[pointType+'AmbigZip'].value = "";
   document.main.elements[pointType+'AmbigLon'].value = "";
   document.main.elements[pointType+'AmbigLat'].value = "";
        
   //store ambiguous results in hidden variables to pass back to main page
   //using :@@: as delimiter to split array later.    
   //04-03-07 - add lat/longs to pass through in ambiguous results
   for (var i=0; i<numAmbig; i++) {
       if (i == numAmbig-1) {
           //don't need delimiter at end of string
           delimiterString = "";
       }
       
       var tmpCity = xmlDoc.getElementsByTagName("City")[i].firstChild.nodeValue;
       var tmpZip = xmlDoc.getElementsByTagName("Zip")[i].firstChild.nodeValue;
       //handle NULLs
       //5-16-07 -pass null and let default.asp deal with it
       /*
       if (tmpCity == "NULL") {
           tmpCity = "";
       }
       if (tmpZip == "NULL") {
           tmpZip = "";
       }
       */
       //5-16-07 - replace bad lat/longs in returned data
       
       document.main.elements[pointType+'AmbigAddress'].value += xmlDoc.getElementsByTagName("Address")[i].firstChild.nodeValue + delimiterString;
       document.main.elements[pointType+'AmbigCity'].value += tmpCity + delimiterString;
       document.main.elements[pointType+'AmbigZip'].value += tmpZip + delimiterString;
       document.main.elements[pointType+'AmbigLon'].value += xmlDoc.getElementsByTagName("Longitude")[i].firstChild.nodeValue + delimiterString;
       document.main.elements[pointType+'AmbigLat'].value += xmlDoc.getElementsByTagName("Latitude")[i].firstChild.nodeValue + delimiterString;
   }
   
   //if (numAmbig == 0) {
       //transtar was unable to find any matches - return error code
       //code = 3;
   //}       
   
    //store code,whether ambig, spellcheck, or no match
   document.main.elements[pointType+'ErrorCode'].value = code;
   
   if (pointType == 'to'){
       toGeocoded = true;
   }
   else {
       fromGeocoded = true;
   }
}

function storeCoordinates(passedType, xCoord, yCoord) {
    //store origin or destination points in hidden variables
    document.main.elements[passedType+'LongCoord'].value = xCoord;
    document.main.elements[passedType+'LatCoord'].value = yCoord;
    
    if (passedType == 'to'){
        toGeocoded = true;
        //GLog.write("toGeocoded is: " + toGeocoded);
    }
    else {
        fromGeocoded = true;
        //GLog.write("fromGeocoded is: " + fromGeocoded);
    }
}
	
function checkStartAndEndValsToGeocode(point, city, state, zip, pointType) {
    //check existing stored values of point information against what is being submitted
    //if it has changed, we need to regeocode, otherwise, don't.

	//check if anything has changed
	var needToGeocode = false;
	
	if (pointType == "start") {
		if ((storedStartPoint == point) && (storedStartCity == city) && (storedStartState == state) && (storedStartZip == zip)){ 
	        needToGeocode = false;
	    }
	    if((document.main.fromLatCoord.value == "") && (document.main.fromLongCoord.value == "")) {
	        //if coordinates are blank, we need to geocode anyway
	        needToGeocode = true;
	    }
	}
	else {
	    if ((storedEndPoint == point) && (storedEndCity == city) && (storedEndState == state) && (storedEndZip == zip)){ 
	        needToGeocode = false;
	    }
	    if((document.main.toLatCoord.value == "") && (document.main.toLongCoord.value == "")) {
	        //if coordinates are blank, we need to geocode anyway
		    needToGeocode = true;
		}
	}
	
	//otherwise, stuff has changed, need to geocode again
	return needToGeocode;

}

function replaceApos(tmpString) {
    //globally replace apostrophes in strings
    var tmpString1 = tmpString.replace(/'/g, '');
	return tmpString1;
}

function replaceSpecialChars(tmpString) {
    //globally replace &'s and @'s in strings
    var tmpString1 = tmpString.replace(/&/g, ' and ');
    tmpString1 = tmpString1.replace(/@/g, ' at ');
	return tmpString1;
}
