// Declaring required variables for the phone code
var digits = "0123456789";
// non-digit characters which are allowed in phone numbers
var phoneNumberDelimiters = "()- ";
// characters which are allowed in international phone numbers
// (a leading + is OK)
var validWorldPhoneChars = phoneNumberDelimiters + "+";
// Minimum no of digits in an international phone no.
var minDigitsInIPhoneNumber = 10;

function isInteger(s)
{   var i;
    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}

function trim(s)
{   var i;
    var returnString = "";
    // Search through string's characters one by one.
    // If character is not a whitespace, append to returnString.
    for (i = 0; i < s.length; i++)
    {   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);
        if (c != " ") returnString += c;
    }
    return returnString;
}

function stripCharsInBag(s, bag)
{   var i;
    var returnString = "";
    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++)
    {   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function checkInternationalPhone(strPhone){
var bracket=3
strPhone=trim(strPhone)
if(strPhone.indexOf("+")>1) return false
if(strPhone.indexOf("-")!=-1)bracket=bracket+1
if(strPhone.indexOf("(")!=-1 && strPhone.indexOf("(")>bracket)return false
var brchr=strPhone.indexOf("(")
if(strPhone.indexOf("(")!=-1 && strPhone.charAt(brchr+2)!=")")return false
if(strPhone.indexOf("(")==-1 && strPhone.indexOf(")")!=-1)return false
s=stripCharsInBag(strPhone,validWorldPhoneChars);
return (isInteger(s) && s.length >= minDigitsInIPhoneNumber);
}

// Is the email sytax good?
function goodSyntax(e1, iD) {
    // Valid email regex
    var regex = new RegExp("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*"+						"@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?");
    // Return match result
    if (!e1.match(regex)){
        writeText(iD,"Please provide a valid email address", true);
        alreadyChecked = false;
        return false;
    }
	return true;
}
		
// Is the spelling good?
function goodSpelling(e1, iD){ 
				
	var commonDomains = new Array();
	commonDomains = getCommonDomains();
    var name = e1.split("@")[0];
    var domain = e1.split("@")[1];
	// If the domain is in the list, spelling is ok so return true
	// IE indexOf workaround
	var n = commonDomains.length;
	while(n--) if(domain == commonDomains[n]) {return true;}
	// See if the domain has letters accidentally swapped
	var swaps = possibleSwaps(domain,commonDomains);
	if (swaps != ""){
		alreadyChecked = true;
		writeText(iD, "Incorrect spelling? " + name + "@" + swaps, true);
		return false;
	}
    // See if the domain was misspelled e.g. htmail.com (only looks for edit distance of 1)
	var misspell = possibleMispellings(domain, commonDomains);
	if (misspell != ""){
		var outstring = "Incorrect spelling?";
		for (var x = 0; x < misspell.length; x++){
		outstring = outstring + " " + name + "@" + misspell[x];
		}
		writeText(iD,outstring, true);
		alreadyChecked = true;
		return false;
	}
	// Final check is on the suffix
	var domainParts = new Array();
	domainParts = domain.split(".");
	if (domainParts.length <= 2){
		var suffixes = new Array();
		suffixes = getCommonSingleSuffix();
		var badSuffix = possibleSwaps(domainParts[1],suffixes);
		if (badSuffix != ""){
			writeText(iD,"Incorrect spelling? " + name + "@" + domainParts[0] + "." + badSuffix, true);
			alreadyChecked = true;
			return false;
		}
		badSuffix = possibleMispellings(domainParts[1],suffixes);
		if (badSuffix != ""){
			var outstring = "Incorrect spelling?";
			for (var x = 0; x < badSuffix.length; x++){
				outstring = outstring + " " + name + "@" + domainParts[0] + "." + badSuffix[x];
			}
			writeText(iD,outstring, true);
			alreadyChecked = true;
			return false;
		}
	} else {
		var suffixes = new Array();
		suffixes = getCommonDoubleSuffix();
		var len = domainParts.length;
		var badSuffix = possibleSwaps(domainParts[len-2]+"."+domainParts[len-1],suffixes);
		if (badSuffix != ""){
			writeText(iD,"Incorrect spelling? " + name + "@" + domainParts[0] + "." + badSuffix, true);
			alreadyChecked = true;
			return false;
		}
		badSuffix = possibleMispellings(domainParts[len-2]+"."+domainParts[len-1],suffixes);
		if (badSuffix != ""){
			var outstring = "Incorrect spelling?";
			for (var x = 0; x < badSuffix.length; x++){
				outstring = outstring + " " + name + "@" + domainParts[0] + "." + badSuffix[x];
			}
			writeText(iD,outstring, true);
			alreadyChecked = true;
			return false;
		}
	}
	// Else we're ok - return true
    return true;
}

// Check for a match with swapped letters
function possibleSwaps(strng,arry){

    // First part deals with swapped letters (e.g. htomail.com) - strings must be the same length
    var possibleMatch = false;
    var stringlength = strng.length;
    for ( var i=0, len=arry.length; i < len; ++i ){
        if (stringlength == arry[i].length) {
            var counter = 0;
            for (var k = 0; k < stringlength - 1; k++) {
                if (strng.charAt(k) != arry[i].charAt(k)) {
                    if (strng.charAt(k) == arry[i].charAt(k + 1) &&
                        strng.charAt(k + 1) == arry[i].charAt(k)) {
                        counter++;
                        k++;
                        possibleMatch = true;
                    } else {
                        possibleMatch = false;
                        break;
                    }
                }
            }
            if ((counter <= 2) && (possibleMatch == true)) {
				// If we've got up to two sets of swaps but an otherwise good match, return the correct string
				return arry[i];
            }
        }
    }
	// Return empty string if we didn't find a 'swap' match
	return "";
}

// Check for a mistyped letter, a missing letter or an added letter
function possibleMispellings(strng,arry){

    var actualDist = 0;
	var returnArray = [];
    for (var i = 0, len = arry.length; i < len; i++) {
        actualDist = getDistance(strng, arry[i]);
        if (actualDist == 1) {
			returnArray.push(arry[i]);
        }
    }
	return returnArray;
}


// Get the edit distance (Levenshtein distance) between the two strings
function getDistance(a, b){

    var min=Math.min, len1=0, len2=0, I=0, i=0, d=[], c='', j=0, J=0;
    var split = false;
    try{
        split=!('0')[0];
    } catch(i){
        split=true; 
    }
    if (a == b) {
        return 0;
    }
    if (!a.length || !b.length) {
        return b.length || a.length;
    }
    if (split){
        a = a.split('');
        b = b.split('');
    }
    len1 = a.length + 1;
    len2 = b.length + 1;
    d = [[0]];
    while (++i < len2) {
        d[0][i] = i;
    }
    i = 0;
    while (++i < len1) {
        J = j = 0;
        c = a[I];
        d[i] = [i];
        while (++j < len2) {
            d[i][j] = min(d[I][j] + 1, d[i][J] + 1, d[I][J] + (c != b[J]));
            ++J;
        }
        ++I;
    }  
    return d[len1 - 1][len2 - 1];
}

// Function to write out the text (and toggle visibility) to the field with the matching id
function writeText(id, text, visible){
	if (visible == true){
        document.getElementById(id).style.display="";
        document.getElementById(id).innerHTML= text;
    } else {
        document.getElementById(id).style.display="none";
    }
}

// Get the array containing our common domains
function getCommonDomains(){
    var commonDomains = new Array(
    "3mail.com",
    "aim.com",
    "aol.co.uk",
    "aol.com",
    "att.blackberry.net",
    "bloomberg.net",
    "blueyonder.co.uk",
    "bt.com",
    "btclick.com",
    "btconnect.com",
    "btinternet.com",
    "btopenworld.com",
    "clara.net",
    "dishmail.net",
    "earthlink.ca",
    "earthlink.net",
    "easy.com",
    "email.com",
    "emirates.net",
    "excite.com",
    "fastmail.co.uk",
    "fastmail.fm",
    "freenet.co.uk",
    "freeserve.co.uk",
    "fsmail.net",
    "gmail.com",
    "gmx.co.uk",
    "gmx.com",
    "gmx.de",
    "gmx.net",
    "googlemail.com",
    "gotadsl.co.uk",
    "hotmail.co.uk",
    "hotmail.com",
    "hotmail.de",
    "hotmail.es",
    "hotmail.fr",
    "iafrica.com",
    "juno.com",
    "libero.it",
    "lineone.co.uk",
    "lineone.net",
    "live.ca",
    "live.co.uk",
    "live.com",
    "live.com.au",
    "live.in",
    "live.it",
    "lycos.co.uk",
    "lycos.com",
    "mac.com",
    "macunlimited.net",
    "madasafish.com",
    "mail.bg",
    "mail.com",
    "mail.dk",
    "mail.gr",
    "mail.ru",
    "mindspring.com",
    "msn.com",
    "nildram.co.uk",
    "ntlworld.com",
    "o2.co.uk",
    "o2.pl",
    "onetel.com",
    "onetel.net",
    "online.be",
    "online.nl",
    "online.no",
    "online.ru",
    "op.pl",
    "orange.fr",
    "orange.net",
    "orange.nl",
    "rocketmail.com",
    "sky.com",
    "sprintpcs.com",
    "supanet.com",
    "talk21.co.uk",
    "talk21.com",
    "talktalk.com",
    "talktalk.net",
    "telefonica.net",
    "telia.com",
    "tesco.net",
    "tiscali.co.uk",
    "tiscali.fr",
    "tiscali.it",
    "ukonline.co.uk",
    "verizon.net",
    "versatel.nl",
    "virgin.net",
    "vodafone.ie",
    "vodafone.net",
    "wanadoo.es",
    "wanadoo.fr",
    "wanadoo.nl",
    "windowslive.com",
    "wp.pl",
    "yahoo.ca",
    "yahoo.cn",
    "yahoo.co.id",
    "yahoo.co.in",
    "yahoo.co.nz",
    "yahoo.co.uk",
    "yahoo.com",
    "yahoo.com.ar",
    "yahoo.com.au",
    "yahoo.com.br",
    "yahoo.com.cn",
    "yahoo.com.hk",
    "yahoo.com.ph",
    "yahoo.com.sg",
    "yahoo.com.tr",
    "yahoo.de",
    "yahoo.dk",
    "yahoo.es",
    "yahoo.fr",
    "yahoo.gr",
    "yahoo.ie",
    "yahoo.in",
    "yahoo.it",
    "yahoo.no",
    "yahoo.se",
    "ymail.com",
    "zoom.co.uk"
	);
	return commonDomains;
}

// Get the array containing our common domains
function getCommonSingleSuffix(){
    var singleSuffixes = new Array(
		"com",
		"net",
		"org",
		"edu",
		"biz",
		"gov",
		"mil",
		"info",
		"name",
		"mobi"
	);
	return singleSuffixes;
}

function getCommonDoubleSuffix(){
    var doubleSuffixes = new Array(
		"co.uk",
		"com.au",
		"co.za",
		"co.in",
		"ac.uk",
		"co.nz",
		"com.cy",
		"org.uk",
		"gov.uk",
		"com.br",
		"net.ae",
		"net.il",
		"net.au",
		"co.il",
		"me.uk",
		"com.hk",
		"uk.com",
		"co.jp",
		"sch.uk"
	);
	return doubleSuffixes;
}
