/*
(c) 2006.  Qcorps Residential, Inc. dba WhiteFence.  All Rights Reserved
Author: Ken Myers
Date: 09-09-2006

This script is the controller for the ajax calls in the main page.  This
includes separate functions for new and old addresses as well as other
dynamic validations.
*/

//instantiate the mybic HTTP object
var ajaxObj = new XMLHTTP("./php/mybic_server.php");
//instantiate the W3C DOM Parser
var parser = new DOMImplementation(); //;debug


// Remove extra spaces -> really single-space text
function SingleSpace( value ) {
	return value.replace("\s\s", " ");
}

// Removes leading whitespaces
function LTrim( value ) {
	var re = /\s*((\S+\s*)*)/;
	return value.replace(re, "$1");
}

// Removes ending whitespaces
function RTrim( value ) {
	var re = /((\s*\S+)*)\s*/;
	return value.replace(re, "$1");
}

// Removes leading and ending whitespaces
function trim( value ) {
	return LTrim(RTrim(value));
}

function show(ele,content) {
	var srcElement = document.getElementById(ele);
	if(srcElement != null) {
	srcElement.innerHTML=content;
	}
}

//ClearRequired
function clearRequired(ele,errele,content) {
	var srcElement = document.getElementById(ele);
	var errElement = document.getElementById(errele);
	if(srcElement.value != null && srcElement.value!="") {
	errElement.innerHTML=content;
	}
}

// Just extract a value from an xml document
// Uses regex due to eliminate cross-browser SAX problems
function getXpathValue(axml,axpath,tag) {

	var attArr;
	var dq = String.fromCharCode(34);
	var spc = String.fromCharCode(20);

	//load the XML into the parser and get the DOMDocument
	var domDoc = parser.loadXML(axml);

	//get the document root
	var docRoot = domDoc.getDocumentElement();

	//start by calling selectNodeSet
	var result = domDoc.selectNodeSet(axpath);

	//this will contain the rtf fragment
	var myvalue = result.toString();
	var tmprepl = myvalue;

	//remove CDATA tags using regex
	tmprepl = myvalue.replace(/<!\[CDATA\[/img, "");
	myvalue = tmprepl;
	tmprepl = myvalue.replace(/]]>/img, "");
	myvalue = tmprepl;
	tmprepl = myvalue.replace(/"/img, "");
	myvalue = tmprepl;

	//now we are going to remove the tags from any RTF
	//done this way due to cross-browser parsing issues
	var tmpTag = "<" + tag + ">";
	if (tag.length>=1)
	{
		tmprepl = myvalue.replace(tmpTag," ");
		myvalue = tmprepl;
		tmpTag = "</" + tag + ">";
		tmprepl = myvalue.replace(tmpTag," ");
		myvalue = tmprepl;
	}
	else
	{
		attArr = myvalue.split("=");
		myvalue = attArr[1];
	}

	return trim(myvalue);

}// end function

//Construct the post params for a new address check
function createpoststringnew(){
	var addy=document.form1.newAddress.value;
	var apt=document.form1.newApt.value;
	var city=document.form1.newCity.value;
	var state=document.form1.newState.value;
	var zip=document.form1.newZip.value;
	var poststr = "";
	if (apt.length=0)
	{
		poststr = "streetAddress=" + addy + "&city=" + city + "&state=" + state + "&zip=" +zip +"&decomposed=true&ReturnXML=true&requestSource=formrequest";
	}else
	{
		poststr = "streetAddress=" + addy + " " + apt + "&city=" + city + "&state=" + state + "&zip=" +zip +"&decomposed=true&ReturnXML=true&requestSource=formrequest";
	}
	return poststr;
}

//Construct the post params for a new address check
function getNewAddy(){
	var addy=document.form1.newAddress.value;
	var apt=document.form1.newApt.value;
	var city=document.form1.newCity.value;
	var state=document.form1.newState.value;
	var zip=document.form1.newZip.value;
	var poststr = "";
	if (apt.length=0)
	{
		poststr = addy + "<br>" + city + " " + state + " " +zip ;
	}else
	{
		poststr = addy + " #" + apt + "<br>" + city + " " + state + " " +zip ;
	}
	return poststr;
}

//Construct the post params for a new address check
function getOldAddy(){
	var addy=document.form1.oldAddress.value;
	var apt=document.form1.oldApt.value;
	var city=document.form1.oldCity.value;
	var state=document.form1.oldState.value;
	var zip=document.form1.oldZip.value;
	var poststr = "";
	if (apt.length=0)
	{
		poststr = addy + "<br>" + city + " " + state + " " +zip ;
	}else
	{
		poststr = addy + " #" + apt + "<br>" + city + " " + state + " " +zip ;
	}
	return poststr;
}

//Construct the post params for an old address check
function createpoststringold(){
	var addy=document.form1.oldAddress.value;
	var apt=document.form1.oldApt.value;
	var city=document.form1.oldCity.value;
	var state=document.form1.oldState.value;
	var zip=document.form1.oldZip.value;
	var poststr = "";
	if (apt.length=0)
	{
		poststr = "streetAddress=" + addy + "&city=" + city + "&state=" + state + "&zip=" +zip +"&decomposed=true&ReturnXML=true&requestSource=formrequest";
	}else
	{
		poststr = "streetAddress=" + addy + " " + apt + "&city=" + city + "&state=" + state + "&zip=" +zip +"&decomposed=true&ReturnXML=true&requestSource=formrequest";
	}
	return poststr;
}

//This will use mybic to execute the skinner address check
function makeEmailRequest() {
	var email=document.form1.emailaddr.value;
	var qstring = "action=mxlookup&email=" + email;
	show("err_emailaddr","");
	ajaxObj.call(qstring, respAddyCheckEmail);
}

//This will use mybic to execute the skinner address check
function makeAddyNewRequest() {
	var qstring = "action=postaddy&" + createpoststringnew();
	ajaxObj.call(qstring, respAddyCheckNew);
}

//This will use mybic to execute the skinner address check
function makeAddyOldRequest() {
	var qstring = "action=postaddy&" + createpoststringold();
	ajaxObj.call(qstring, respAddyCheckOld);
}

//This is used if the user chooses to ignore the email check
function clearEmail(){
show("err_emailaddr","");
}

//This is used if the user chooses to ignore the address check
function clearOld(){
show("OldResponseInfo","");
}

//This is used if the user chooses to ignore the address check
function clearNew(){
show("NewResponseInfo","");
}


//Executes when the user selects to take the suggested address
function correctOld(){
	document.form1.oldAddress.value = document.form1.tmpOldAddress.value;
	document.form1.oldApt.value = document.form1.tmpOldApt.value;
	document.form1.oldCity.value = document.form1.tmpOldCity.value;
	document.form1.oldState.value = document.form1.tmpOldState.value;
	document.form1.oldZip.value = document.form1.tmpOldZip.value;
	show("OldResponseInfo","");
}

//Executes when the user selects to take the suggested address
function correctNew(){
	document.form1.newAddress.value = document.form1.tmpNewAddress.value;
	document.form1.newApt.value = document.form1.tmpNewApt.value;
	document.form1.newCity.value = document.form1.tmpNewCity.value;
	document.form1.newState.value = document.form1.tmpNewState.value;
	document.form1.newZip.value = document.form1.tmpNewZip.value;
	show("NewResponseInfo","");
}

function respAddyCheckEmail(resp) {
	//check for a validation error
	var ehtml;

	if (resp==0)
	{
		ehtml = "<table border='0' cellspacing='0' cellpadding='0' class='formtextsmall'><tr><td width=''>";
		ehtml = ehtml + "<tr><td colspan='2'>&nbsp;</td></tr><tr><td colspan='2'><font color='#CC0000'>We&rsquo;re sorry - we ";
		ehtml = ehtml + "cannot verify your email address. </td></tr>";
		ehtml = ehtml + "<tr><td><input name='email_address_validation'";
		ehtml = ehtml + " type='radio' value='un_corrected' onclick='javascript:clearEmail();'></td><td> Use the email address I entered </td>";
		ehtml = ehtml + "</tr></table>";
		show("err_emailaddr",ehtml);
	}
	else{
	show("err_emailaddr","");
	}
}

// return the smallest of the three values passed in
function minimator (x,y,z) {
	if (x < y && x < z) return x;
	if (y < x && y < z) return y;
	return z;
}

// calculate the Levenshtein distance between a and b, passed to the function
function levenshtein (a,b) {
	var cost;
	var m = a.length;
	var n = b.length;

	// make sure a.length >= b.length to use O(min(n,m)) space, whatever that is
	if (m < n) {
		var c=a;a=b;b=c;
		var o=m;m=n;n=o;
	}

	var r = new Array();
	r[0] = new Array();
	for (var c = 0; c < n+1; c++) {
		r[0][c] = c;
	}

	for (var i = 1; i < m+1; i++) {
		r[i] = new Array();
		r[i][0] = i;
		for (var j = 1; j < n+1; j++) {
			cost = (a.charAt(i-1) == b.charAt(j-1))? 0: 1;
			r[i][j] = minimator(r[i-1][j]+1,r[i][j-1]+1,r[i-1][j-1]+cost);
		}
	}

	return r[m][n];
}

//This will process the new address response
function respAddyCheckNew(resp) {

	var tmpval;
	var tmpxml;
	var houseNumber;
	var predirection;
	var streetName;
	var streetSuffix;
	var postdirection;
	var buf;
	var ehtml;

	if (resp.length=0)
	{
		//document.form1.newResponse.value = "No data returned.";

	}else
	{
		tmpxml=resp;
		tmpval = getXpathValue(resp,"//responses/response/guess/status/errorLevel/@code","");
		if (tmpval==0)
		{
			//document.form1.newResponse.value = "Address not found!";
			//show("NewResponseInfo","");
			ehtml = "<table border='0' cellspacing='0' cellpadding='0' class='formtextsmall'><tr><td width=''>";
			ehtml = ehtml + "<tr><td colspan='2'>&nbsp;</td></tr><tr><td colspan='2'><font color='#CC0000'>We&rsquo;re sorry - the ";
			ehtml = ehtml + "address you entered does not match postal records. </td></tr>";
			ehtml = ehtml + "<tr><td><input name='new_address_validation'";
			ehtml = ehtml + " type='radio' value='un_corrected' onclick='javascript:clearNew();'></td><td> Use the address I entered </td>";
			ehtml = ehtml + "</tr></table>";
			show("NewResponseInfo",ehtml);

		}
		else
		{
			if (tmpval==100)
			{
				//document.form1.newResponse.value = "Perfect match!";
				show("NewResponseInfo","");
				resp=tmpxml;
				houseNumber = getXpathValue(resp,"//responses/response/guess/decomposedAddress/houseNumber","houseNumber");
				resp=tmpxml;
				predirection = getXpathValue(resp, "//responses/response/guess/decomposedAddress/predirection","predirection");
				resp=tmpxml;
				streetName = getXpathValue(resp, "//responses/response/guess/decomposedAddress/streetName","streetName");
				resp=tmpxml;
				streetSuffix = getXpathValue(resp, "//responses/response/guess/decomposedAddress/streetSuffix","streetSuffix");
				resp=tmpxml;
				postdirection = getXpathValue(resp, "//responses/response/guess/decomposedAddress/postdirection","postdirection");
				tmpval = houseNumber;
				if(trim(predirection)!=""){
					tmpval = tmpval + " " + trim(predirection);
				}
				if(trim(streetName)!=""){
					tmpval = tmpval + " " + trim(streetName);
				}
				if(trim(streetSuffix)!=""){
					tmpval = tmpval + " " + trim(streetSuffix);
				}
				if(trim(postdirection)!=""){
					tmpval = tmpval + " " + trim(postdirection);
				}
				//set field value
				document.form1.tmpNewAddress.value=tmpval;
				buf = tmpval;
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/aptNumber","aptNumber");
				document.form1.tmpNewApt.value=tmpval;
                if (tmpval!=""){
                   buf = buf + " #" + tmpval + "<br>";
                }
                else{
                   buf = buf + "<br>";
                }
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/city","city");
				document.form1.tmpNewCity.value=tmpval;
				buf = buf + " " + tmpval;
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/state","state");
				document.form1.tmpNewState.value=tmpval;
				buf = buf + " " + tmpval;
                resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/county","county");
				document.form1.tmpNewCounty.value=tmpval;
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/zip5","zip5");
				document.form1.tmpNewZip.value=tmpval;
				buf = buf + " " + tmpval;
				correctNew();
			}
			else
			{
				//start parsing the xml
				resp=tmpxml;
				houseNumber = getXpathValue(resp,"//responses/response/guess/decomposedAddress/houseNumber","houseNumber");
				resp=tmpxml;
				predirection = getXpathValue(resp, "//responses/response/guess/decomposedAddress/predirection","predirection");
				resp=tmpxml;
				streetName = getXpathValue(resp, "//responses/response/guess/decomposedAddress/streetName","streetName");
				resp=tmpxml;
				streetSuffix = getXpathValue(resp, "//responses/response/guess/decomposedAddress/streetSuffix","streetSuffix");
				resp=tmpxml;
				postdirection = getXpathValue(resp, "//responses/response/guess/decomposedAddress/postdirection","postdirection");
				tmpval = houseNumber;
				if(trim(predirection)!=""){
					tmpval = tmpval + " " + trim(predirection);
				}
				if(trim(streetName)!=""){
					tmpval = tmpval + " " + trim(streetName);
				}
				if(trim(streetSuffix)!=""){
					tmpval = tmpval + " " + trim(streetSuffix);
				}
				if(trim(postdirection)!=""){
					tmpval = tmpval + " " + trim(postdirection);
				}
				//set field value
				document.form1.tmpNewAddress.value=tmpval;
				buf = tmpval;
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/aptNumber","aptNumber");
				document.form1.tmpNewApt.value=tmpval;
                if (tmpval!=""){
                   buf = buf + " #" + tmpval + "<br>";
                }
                else{
                   buf = buf + "<br>";
                }
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/city","city");
				document.form1.tmpNewCity.value=tmpval;
				buf = buf + " " + tmpval;
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/state","state");
				document.form1.tmpNewState.value=tmpval;
				buf = buf + " " + tmpval;
                resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/county","county");
				document.form1.tmpNewCounty.value=tmpval;
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/zip5","zip5");
				document.form1.tmpNewZip.value=tmpval;
				buf = buf + " " + tmpval;
				ehtml = "<table border='0' cellspacing='0' cellpadding='0' class='formtextsmall'><tr><td width=''>";
				ehtml = ehtml + "<tr><td colspan='2'>&nbsp;</td></tr><tr><td colspan='2'><font color='#CC0000'>We&rsquo;re sorry - the ";
				ehtml = ehtml + "address you entered does not match postal records. </td></tr>";
				ehtml = ehtml + "<tr><td><input name='newer_address_validation'";
				ehtml = ehtml + " type='radio' value='un_corrected' onclick='javascript:clearNew();'></td><td> Use the address I entered </td>";
				ehtml = ehtml + "</tr><tr><td><input name='fixnew_address_validation' type='radio' value='corrected'";
				ehtml = ehtml + " onclick='javascript:correctNew();'></td><td> Use the corrected address:<br> ";
				ehtml = ehtml + "</td></tr><tr><td>&nbsp;</td><td>"+buf+"</td></tr></table>";
				//alert(getNewAddy() + " vs. " + buf);
				if (levenshtein(getNewAddy(),buf)>1)
				{
					show("NewResponseInfo",ehtml);
				}
				//document.form1.newResponse.value = buf;
			}
		}

	}
}

//This will process the old address response
function respAddyCheckOld(resp) {

	var tmpval;
	var houseNumber;
	var predirection;
	var streetName;
	var streetSuffix;
	var postdirection;
	var buf;
	var tmpxml=resp;
	var ehtml;

	if (resp.length=0)
	{
		//document.form1.oldResponse.value = "No data returned.";

	}else
	{
		tmpval = getXpathValue(resp,"//responses/response/guess/status/errorLevel/@code","");
		if (tmpval==0)
		{
			//document.form1.oldResponse.value = "Address not found!";
			ehtml = "<table border='0' cellspacing='0' cellpadding='0' class='formtextsmall'><tr><td width=''>";
			ehtml = ehtml + "<tr><td colspan='2'>&nbsp;</td></tr><tr><td colspan='2'><font color='#CC0000'>We&rsquo;re sorry - the ";
			ehtml = ehtml + "address you entered does not match postal records. </td></tr>";
			ehtml = ehtml + "<tr><td><input name='old_address_validation'";
			ehtml = ehtml + " type='radio' value='un_corrected' onclick='javascript:clearOld();'></td><td> Use the address I entered </td>";
			ehtml = ehtml + "</tr></table>";
			show("OldResponseInfo",ehtml);
		}
		else
		{
			if (tmpval==100)
			{
				show("OldResponseInfo","");
				resp=tmpxml;
				houseNumber = getXpathValue(resp,"//responses/response/guess/decomposedAddress/houseNumber","houseNumber");
				resp=tmpxml;
				predirection = getXpathValue(resp, "//responses/response/guess/decomposedAddress/predirection","predirection");
				resp=tmpxml;
				streetName = getXpathValue(resp, "//responses/response/guess/decomposedAddress/streetName","streetName");
				resp=tmpxml;
				streetSuffix = getXpathValue(resp, "//responses/response/guess/decomposedAddress/streetSuffix","streetSuffix");
				resp=tmpxml;
				postdirection = getXpathValue(resp, "//responses/response/guess/decomposedAddress/postdirection","postdirection");
				tmpval = houseNumber;
				if(trim(predirection)!=""){
					tmpval = tmpval + " " + trim(predirection);
				}
				if(trim(streetName)!=""){
					tmpval = tmpval + " " + trim(streetName);
				}
				if(trim(streetSuffix)!=""){
					tmpval = tmpval + " " + trim(streetSuffix);
				}
				if(trim(postdirection)!=""){
					tmpval = tmpval + " " + trim(postdirection);
				}
				//set field value
				document.form1.tmpOldAddress.value=tmpval;
				buf = tmpval;
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/aptNumber","aptNumber");
				document.form1.tmpOldApt.value=tmpval;
                if (tmpval!=""){
                   buf = buf + " #" + tmpval + "<br>";
                }
                else{
                   buf = buf + "<br>";
                }
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/city","city");
				document.form1.tmpOldCity.value=tmpval;
				buf = buf + " " + tmpval;
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/state","state");
				document.form1.tmpOldState.value=tmpval;
				buf = buf + " " + tmpval;
                resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/county","county");
				document.form1.tmpOldCounty.value=tmpval;
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/zip5","zip5");
				document.form1.tmpOldZip.value=tmpval;
				buf = buf + " " + tmpval;
				correctOld();
			}
			else
			{
				//start parsing the xml
				resp=tmpxml;
				houseNumber = getXpathValue(resp,"//responses/response/guess/decomposedAddress/houseNumber","houseNumber");
				resp=tmpxml;
				predirection = getXpathValue(resp, "//responses/response/guess/decomposedAddress/predirection","predirection");
				resp=tmpxml;
				streetName = getXpathValue(resp, "//responses/response/guess/decomposedAddress/streetName","streetName");
				resp=tmpxml;
				streetSuffix = getXpathValue(resp, "//responses/response/guess/decomposedAddress/streetSuffix","streetSuffix");
				resp=tmpxml;
				postdirection = getXpathValue(resp, "//responses/response/guess/decomposedAddress/postdirection","postdirection");
				tmpval = houseNumber;
				if(trim(predirection)!=""){
					tmpval = tmpval + " " + trim(predirection);
				}
				if(trim(streetName)!=""){
					tmpval = tmpval + " " + trim(streetName);
				}
				if(trim(streetSuffix)!=""){
					tmpval = tmpval + " " + trim(streetSuffix);
				}
				if(trim(postdirection)!=""){
					tmpval = tmpval + " " + trim(postdirection);
				}
				//set field value
				document.form1.tmpOldAddress.value=tmpval;
				buf = tmpval;
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/aptNumber","aptNumber");
				document.form1.tmpOldApt.value=tmpval;
                if (tmpval!=""){
                   buf = buf + " #" + tmpval + "<br>";
                }
                else{
                   buf = buf + "<br>";
                }
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/city","city");
				document.form1.tmpOldCity.value=tmpval;
				buf = buf + " " + tmpval;
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/state","state");
				document.form1.tmpOldState.value=tmpval;
				buf = buf + " " + tmpval;
                resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/county","county");
				document.form1.tmpOldCounty.value=tmpval;
				resp=tmpxml;
				tmpval = getXpathValue(resp,"//responses/response/guess/decomposedAddress/zip5","zip5");
				document.form1.tmpOldZip.value=tmpval;
				buf = buf + " " + tmpval;
				//document.form1.oldResponse.value = buf;
				ehtml = "<table border='0' cellspacing='0' cellpadding='0' class='formtextsmall'><tr><td width=''>";
				ehtml = ehtml + "<tr><td colspan='2'>&nbsp;</td></tr><tr><td colspan='2'><font color='#CC0000'>We&rsquo;re sorry - the ";
				ehtml = ehtml + "address you entered does not match postal records. </td></tr>";
				ehtml = ehtml + "<tr><td><input name='older_address_validation'";
				ehtml = ehtml + " type='radio' value='un_corrected' onclick='javascript:clearOld();'></td><td> Use the address I entered </td>";
				ehtml = ehtml + "</tr><tr><td><input name='fixold_address_validation' type='radio' value='corrected'";
				ehtml = ehtml + " onclick='javascript:correctOld();'></td><td> Use the corrected address:<br> ";
				ehtml = ehtml + "</td></tr><tr><td>&nbsp;</td><td>"+buf+"</td></tr></table>";
				if (levenshtein(getOldAddy(),buf)>1)
				{
					show("OldResponseInfo",ehtml);
				}
			}
		}

	}
}
