//////////////////////////////////////////////////////////////////////////////////////////////////////
// FORMAT FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////////////////////


// Format - formats text entered
TigerField.prototype.Format = function () {
	var cVal = this.GetValue();
	var cValStripPunc = RemovePunc(cVal);
	var cValOnlyAlpha = RemoveNumbers(cValStripPunc);
	var cValSig = cValStripPunc.toLowerCase();
	var cLastValSig = RemovePunc(this.LastVal.toLowerCase());

	if (this.IsAddressField) {
		if (this.parent.AddressDataTouched) {
			if (cVal == "" && this.parent.AllAddressDataIsBlank()) {
				this.parent.AddressDataTouched = false;
			}
		} else {
			if (cValSig != cLastValSig && cValSig != "") {
				this.parent.AddressDataTouched = true;
			}
		}
	}

	var lToFormat = true;



	if (this.FormatType == eFormatType.Titlecase) {
		// If signature before and after are the same, then do nothing
		if (cValSig == cLastValSig) {
			this.LastVal=cVal;
			return;
		}

		// Decide or set the format mode for titlecase data
		if (this.parent.FormatMode == eFormatMode.NotSet) {
			if (!this.parent.SmartTypingTest) {
				this.parent.FormatMode = eFormatMode.Never;
			} else {
				if (cValOnlyAlpha != "") {
					if (cVal == cVal.toLowerCase()) {
						this.parent.FormatMode = eFormatMode.OnlyIfLower;
					}
					else if (cVal == cVal.toUpperCase()) {
						this.parent.FormatMode = eFormatMode.OnlyIfSameCase;
					}
					else {
						this.parent.FormatMode = eFormatMode.Never;
					}			
				}
			}
		}
		
		// Decide if this string needs formatting
		if (this.parent.FormatMode == eFormatMode.NotSet || this.parent.FormatMode == eFormatMode.Never)  lToFormat = false;
		if (this.parent.FormatMode == eFormatMode.OnlyIfLower && cVal!=cVal.toLowerCase())  lToFormat = false;
		if (this.parent.FormatMode == eFormatMode.OnlyIfSameCase && (cVal!=cVal.toLowerCase() && cVal!=cVal.toUpperCase()))  lToFormat = false;
	
		if (!lToFormat) {
			this.LastVal=cVal;
			return
		}
	}

	// If so, format
	var RetVal=cVal
	switch (this.FormatType) {
		case eFormatType.None:
			RetVal=AllTrim(RetVal);
			break;
		case eFormatType.Uppercase:
			RetVal=AllTrim(RetVal);
			RetVal=RetVal.toUpperCase();
			break;
		case eFormatType.Lowercase:
			RetVal=AllTrim(RetVal);
			RetVal=RetVal.toLowerCase();
			break;
		case eFormatType.Titlecase:
			switch (this.FormatTitleType) {
				case eFormatTitleType.Standard:
					RetVal=titlecase(RetVal);
					break;
				case eFormatTitleType.Firstname:
					RetVal=firstnamecase(RetVal);
					break;
				case eFormatTitleType.Lastname:
					RetVal=titlecase(RetVal);
					break;
				case eFormatTitleType.Job:
					RetVal=jobcase(RetVal);
					break;
				case eFormatTitleType.Company:
					RetVal=companycase(RetVal);
					break;
				case eFormatTitleType.Address:
					RetVal=addresscase(RetVal);
					break;
			}
			break;
		case eFormatType.Phone:
			RetVal=phoneformat(RetVal, this.parent.CountryField.GetValue());
			break;
		case eFormatType.Email:
			RetVal=emailformat(RetVal);
			break;
		case eFormatType.Postcode:
			RetVal=pcodeformat(RetVal);
			break;
		case eFormatType.Number:
			RetVal=numberformat(RetVal);
			break;
		case eFormatType.Money:
			RetVal=currencyformat(RetVal);
			break;
		case eFormatType.Years:
			RetVal=yearsformat(RetVal);
			break;
	}
		
	this.LastVal=cVal;
	if (RetVal != cVal) {
		this.SetValue(RetVal);
	}


};

function titlecase(s) {

	s=AllTrim(s);

	// If no alpha chars, leave as it is
	if ( !ContainsUpperChars(s) && !ContainsLowerChars(s)) {
		return s;
	}

	
	// Split word by word and deal with each, joining back together at the end
	
	var cResult="";
	var aWord=s.split(" ");
	for (var nWord=0; nWord < aWord.length; nWord++) {
		var cThisWord=aWord[nWord].toLowerCase()
		var cNewWord="";
		var cNextAction="";
		for (var nLetter=0; nLetter < cThisWord.length; nLetter++) {
		
		
			// Mc
			if (nLetter==0 && cThisWord.substr(0,2)=="mc") {
				cNewWord="Mc";
				nLetter++;
				cNextAction="U";
			} else
			
			// Mac
			if (nLetter==0 && cThisWord.substr(0,3)=="mac" && cThisWord.length > 5 && 
					!cThisWord.match(/macabr|macaron|macerat|machete|machiav|machin|machis|mackerel|mackint|macram|macro/)) {
				cNewWord="Mac";
				nLetter++;
				nLetter++;
				cNextAction="U";
			} else
			
			// O'
			if (nLetter==0 && cThisWord.substr(0,2)=="o'") {
				cNewWord="O'";
				nLetter++;
				cNextAction="U";
			} else

			// D'
			if (nLetter==0 && cThisWord.substr(0,2)=="d'") {
				cNewWord="d'";
				nLetter++;
				cNextAction="U";
			} else 

			// L'
			if (nLetter==0 && cThisWord.substr(0,2)=="d'") {
				cNewWord="l'";
				nLetter++;
				cNextAction="U";
			} else 


			// Small word exception


			if (nLetter==0 && cThisWord.match(/^de$|^la$|^le$|^du$|^des$|^van$|^von$|^der$|^den$|^vder$/) ) {
				cNewWord=Lower(cThisWord);
				nLetter=cThisWord.length;

			} else {




			// Otherwise
				cThisLetter=cThisWord.charAt(nLetter)
				if (cNextAction=="U" || nLetter==0) {
					cNewWord=cNewWord+cThisLetter.toUpperCase()
				} else {
					cNewWord=cNewWord+cThisLetter.toLowerCase()
				}
				if (cThisLetter.match(/[\.\-\,]/)) {
					cNextAction="U";
				} else {
					cNextAction="";
				}
			}
		}

		cResult=cResult+cNewWord+" "
	}
	cResult=AllTrim(cResult);
	
	return cResult;
}



// format a first name: If it is a short string with only consonants and 
// case is constant, then space out the letters. Otherwise titlecase as usual

function firstnamecase(s) {

	s=AllTrim(s);

	if (s.length<4 && ! (ContainsUpperChars(s) && ContainsLowerChars(s)) && ContainsOnlyConsonants(s) ) {
		var cNewString=""
		for (k=0; k<s.length; k++) {
			cNewString += s.charAt(k)+" ";
		}
		s=cNewString;
	}
	
	return AllTrim(titlecase(s));
	
}

// format a job title:
// ordinary title case, then expand standard abbreviations


function jobcase(s) {

	s=titlecase(s);

	s=s.replace(/\bMD\b/i,'Managing Director');
	s=s.replace(/\bFD\b/i,'Financial Director');
	s=s.replace(/\bSr\b/i,'Senior');
	s=s.replace(/\bJr\b/i,'Junior');
	s=s.replace(/\bAcct\b/i,'Account');
	s=s.replace(/\bMgr\b/i,'Manager');
	s=s.replace(/\bExec\b/i,'Executive');
	s=s.replace(/\bVP\b/i,'Vice President');
	s=s.replace(/\bCEO\b/i,'Chief Executive Officer');
	s=s.replace(/\bPA\b/i,'Personal Assistant');
	s=s.replace(/\bHR\b/i,'Human Resources');
	s=s.replace(/\bIT\b/i,'I T');
	s=s.replace(/\bAsst\b/i,'Assistant');
	return s;
}	


// format a company name: 
// - if looks like a web name, and constant case, force lower
// - Otherwise, if all entered upper, keep upper
// - If any word is all cons, force upper, otherwise normal titlecase
// - Replace common exceptions: plc GmbH Ltd UK USA
function companycase(s) {

	if (LooksLikeWebAddress(s) && ! (ContainsUpperChars(s) && ContainsLowerChars(s)) ) {
		return s.toLowerCase();
	}

	// If already mixed case, leave it as it is
	if ( ContainsUpperChars(s) && ContainsLowerChars(s)) {
		return s;
	}
		
	s=titlecase(s);
	
	var cResult="";
	var aWord=s.split(" ");
	for (var nWord=0; nWord < aWord.length; nWord++) {
		var cThisWord=aWord[nWord]

		if (ContainsOnlyConsonants(cThisWord)) {
			cResult=cResult+cThisWord.toUpperCase()+" ";
		} else {
			cResult=cResult+cThisWord+" ";
		}
	}
	s=AllTrim(cResult);

	s=s.replace(/\bUK\b/i,'UK');
	s=s.replace(/\bUSA\b/i,'USA');
	s=s.replace(/\bplc\b/i,'plc');
	s=s.replace(/\bgmbh\b/i,'GmbH');
	s=s.replace(/\bltd\b/i,'Ltd');
	s=s.replace(/\bSA\b/i,'SA');
	s=s.replace(/\bBLDG\b/i,'Bldg');
	s=s.replace(/\bBLDGs\b/i,'Bldgs');
	
	return s;
}

// address: first word lowercase: ul ulica rue
function addresscase(s) {

	// If already mixed case, leave it as it is
	if ( ContainsUpperChars(s) && ContainsLowerChars(s)) {
		return s;
	}

	s=titlecase(s);

	s=s.replace(/^rue\b/i,'rue');
	s=s.replace(/^ul\b/i,'ul');
	s=s.replace(/^ulica\b/i,'ulica');

	return s;
}	


// format a phone number with spaces and brackets
function phoneformat(mystring, ctry) {
	var s = mystring;
	ctry = (ctry ? ctry : "GB" );
	var expectedDialcode = Country[ctry][1].replace(/[\s]/g,"");
	// Identify the international prefix + or 00, and strip it. Also strip other punctuation
	s = s.replace( /[\"\!\£\%\&\^\*\{\}\@\~\;\<\>\.,;!#\$\/:\?'\(\)\[\]_\-\\\s\n\t]/g, "");
	var hasPlus = false;
	if (Left(s,2) == "00") {
		s = s.substring(2)
		hasPlus = true;
	} 
	if (Left(s,1) == "+") {
		s = s.substring(1)
		hasPlus = true;
	} 
	s = s.replace( /[\+]/g,"");

	// Identify the country code. If there was an international prefix, then assume there was a code in the number
	// If not, see if the expected country prefix was present in the number
	// Otherwise, just assume to add the expected country prefix

	var MyDialCode = "";
	var MyLocalNumber = "";
	
	if (hasPlus) {
		MyDialCode = ExtractCountryCode(s);
		MyLocalNumber = s.substring(MyDialCode.length);
	} else {
		if (StartsWith(s,expectedDialcode)) {
			MyDialCode = expectedDialcode;
			MyLocalNumber = s.substring(MyDialCode.length);
		} else {
			MyDialCode = expectedDialcode;
			MyLocalNumber = s;
		}
	}

	// Remove trunk prefix, if found
	if (Dialcode[MyDialCode]) {
		if (StartsWith(MyLocalNumber,Dialcode[MyDialCode][0])) {
			MyLocalNumber = MyLocalNumber.substring(Dialcode[MyDialCode][0].length)
		}
	}

	// Loop through regex's to space as appropriate
	if (!PhonePatterns[MyDialCode]) {
		
		MyLocalNumber = MyLocalNumber.replace(/^(\d{1,4})(\d{0,4})(\d*)(\D+|$)(.*)/, "+$1 $2 $3 $4 $5");
	} else {
		var searchstring, replacestring
		for (var i = 0; i<PhonePatterns[MyDialCode].length; i++) {
			searchstring = PhonePatterns[MyDialCode][i][0];
			replacestring = PhonePatterns[MyDialCode][i][1];
			MyLocalNumber = MyLocalNumber.replace(searchstring, replacestring);
		}
		
	}
	
	// if no pattern matches, return the original unformatted string
	if (MyLocalNumber.substring(0,1) != "+") {
		return mystring;
	}
	if (MyDialCode.length>0) {
		MyDialCode = "+"+MyDialCode+" ";
	}
	// Join back together and return
	return AllTrim(MyDialCode+MyLocalNumber.substring(1));
}

function numberformat(s) {
	s = ChrTran(s,",","");
	var Ret = parseInt(s).toString();
	if (Ret == "undefined" || Ret == "NaN") Ret = "";
	return Ret;
}

function currencyformat(s) {
	s = ChrTran(s,",","");
	s = ChrTran(s,"£","");
	s = ChrTran(s,"$","");
	var Ret = s;
	if (Ret == "undefined" || Ret == "NaN") Ret = "";
	return Ret;
}


// format UK postcode with spaces. Correct O to 0.

function pcodeformat(s) {
	s=s.toUpperCase()
	var temp1=ChrTran(ChrTran(s,".","")," ","")
	var temp2=""
	if (temp1.substr((temp1.length)-3,1)=="O") {
		temp1=temp1.substr(0,(temp1.length)-3)+"0"+temp1.substr((temp1.length)-2,2)
	}
	for (var i=0; i<temp1.length; i++) {
		if (isAlpha(temp1.substr(i,1))) {
			temp2=temp2+"X"
		} else if (isDigit(temp1.substr(i,1))) {
			temp2=temp2+"9"
		} else {
			temp2=temp2+"?"
		}
	}
	switch (temp2) {
		case "XX99XX":
		case "X9X9XX":
		case "X999XX":
			s=temp1.substr(0,3)+" "+temp1.substr(3)
			break;
		case "XX999XX":
		case "XX9X9XX":
			s=temp1.substr(0,4)+" "+temp1.substr(4)
			break;
		case "X99XX":
			s=temp1.substr(0,2)+" "+temp1.substr(2)
			break;
		default:
			break;
	}
	return s
}

// format email address with capitalisation; remove spaces, etc.

function emailformat(s) {
	var cLeft="", cRight=""
	if (s.indexOf("@")>=0) {
		if (s.indexOf("@")>0) {
			cLeft=s.substr(0,s.indexOf("@"))
		}
		if (s.indexOf("@")<s.length-1) {
			cRight=s.substr(s.indexOf("@")+1)
		}
		if (cLeft == cLeft.toUpperCase()) {
			cLeft=cLeft.toLowerCase()
		}
		cRight=cRight.toLowerCase()
		s=cLeft+"@"+cRight
	}

	if (s.length > 0) {
		while (s.charAt(s.length-1) == "." || s.charAt(s.length-1) == ",") {
			s=s.substr(0,s.length-1)
		}
	}

	s=AllTrim(s)
	
	if (!validateemail(s) && validateemail(ChrTran(s," ",""))) {
		s=chrtran(s," ","")
	}

	if (!validateemail(s) && validateemail(ChrTran(s,",","."))) {
		s=ChrTran(s,",",".")
	}

	if (!validateemail(s) && validateemail(ChrTran(ChrTran(s," ",""),",","."))) {
		s=ChrTran(ChrTran(s," ",""),",",".")
	}
	return AllTrim(s)
}


// check that a country is correct/alternative. Return the correct version

function validcountry(s) {
	if (typeof(countrychange[s.toUpperCase()]) != "undefined") {
		return true
	}
	for (var i=0; i<document.qform.er_country.length; i++) {
		if (s.toUpperCase()==document.qform.er_country[i].value.toUpperCase()) {
			return true
		}
	}
	return false	
}


// Prompts the international dial code
TigerField.prototype.SetDialCode = function () {
	var cVal = this.GetValue();
	var Ctryfield=this.parent.CountryField
	var cCtry = Ctryfield.GetValue();
	if (Country[cCtry] != undefined ) {
		var cDial=Country[cCtry][1];
		if (cVal.length==0 && typeof(cDial) != "undefined")  {
				this.SetValue("+"+cDial+" ");
				this.SetCaretToEnd();
		}
	}
}

// Remove the international dial code if nothing has been added/altered
TigerField.prototype.ClearDialCode = function () {
	var cVal = this.GetValue();
	var Ctryfield=this.parent.CountryField
	var cCtry = Ctryfield.GetValue();
	if (Country[cCtry] != undefined ) {
		var cDial=Country[cCtry][1]
		if (typeof(cDial) != "undefined")  {
			if (AllTrim(cVal)=="+"+AllTrim(cDial)) {
				this.SetValue("");
			}
		}
	}
}

// Moves the cursor to the end of the field
TigerField.prototype.SetCaretToEnd = function () {
	Control=this.GetDataField();
    if (Control.createTextRange) {
        var range = Control.createTextRange();
        range.collapse(false);
        range.select();
    }
    else if (Control.setSelectionRange) {
        Control.focus();
        var length = Control.value.length;
        Control.setSelectionRange(length, length);
    }
}

