/*
	LeftCorner.js
	randy anderson (randerson@leftcorner.com)
	Code is free to use for any purpose
	
	Description:
	 	JavaScript equivilants of useful ColdFusion functions. 
		Refer to ColdFusion documentation for more information!	
		
	Notes: 
		Not for older browsers (JavaScript 1.5 for some methods)
		
		Quite a few methods depend on other methods. Be careful if you 
		remove/rename a method!
		
		DateDiff modified from function written by Rob Eberhardt, 
		Slingshot Solutions - http://slingfive.com/
		
		IsDate modified from function written by Craig H. Rettig, 
		Bit Bucket Heaven - http://www.bitbucketheaven.com/
		
		DollarFormat was modified from function called FormatCurrency 
		listed by multiple authors, could not locate the true author
		
		Round works slightly different in my implementation verses ColdFusion.
		ColdFusion only rounds whole numbers. LeftCorner.Round() allows 
		an optional argument of number of places to round decimals. For 
		example LeftCorner.Round(3.143,2) would return "3.14". ColdFusion would 
		return "3".
	
	Methods: 	
		Abs(number)
		ArrayAppend(array, value)
		ArrayLen(array)
		ArraySort(array, sort_type [, sort_order ])
		ArrayToList(array [, delimiter ])
		Ceiling(number)
		Compare(string1, string2)
		CompareNoCase(string1, string2)		
		DateDiff(datepart, date1, date2)
		DecimalFormat(number)
		DollarFormat(number)
		Find(substring, string)
		FindNoCase(substring, string)
		Insert(substring, string, position)
		IsDate(date)
		IsNumeric(string)
		LCase(string)
		Left(string, count)
		Len(sting)
		ListAppend(list, value, [, delimiters])
		ListDeleteAt(list, position [, delimiters ])
		ListFind(list, value [, delimiters ]))
		ListFindNoCase(list, value [, delimiters ]))
		ListGetAt(list, position [, delimiters ]))
		ListLen(list [, delimiters])
		ListToArray(list [, delimiters])
		LTrim(string)
		Mid(string, start, count)
		Replace(string, substring1, substring2 [, scope ])
		ReplaceNoCase(string, substring1, substring2 [, scope ])
		Reverse(string)
		Right(string, count)
		Round(number [, number of decimal places])
		RTrim(string)
		Trim(string)
		UCase(string)
		URLDecode(string)
		URLEncodedFormat(string)		
		
	Usage:
		Methods belong to object LeftCorner.
		Thus, to determine a string length with the Len()
		function as an example one would invoke the method like so:
		
		LeftCorner.Len("how long is this string?");
		
		The methods are designed to behave their ColdFusion 
		counterparts with one notable exception, method names are 
		case sensitive! 
		
		LeftCorner.LEN("Why don't I work?") will fail 
		as an example.
	
	Code Variable Abbreviations:
		a 		= array
		c 		= count
		d 		= delimiters
		d1,d2 	= date one, date two
		dp 		= date part
		i 		= index
		l 		= list
		n 		= number
		p 		= position
		r 		= return value/string/etc 
		s 		= string
		s1,s2 	= string one, string two
		sb 		= substring
		sb1,sb2	= substring one, substring two
		so 		= sort order
		st 		= sort type
		sc 		= scope
		v 		= value
*/
var LeftCorner = {
	Abs: function(n){
		return Math.abs(n);
	},	
	ArrayAppend: function(a, v){
		a[a.length] = v;
		return a;
	},
	ArraySort: function(a,st,so){
		var _so;
		if (st.toUpperCase() == 'TEXTNOCASE'){ 
			if(!so || so.toUpperCase() != "DESC"){
				_so = function(a, b) {a = a.toUpperCase(); b = b.toUpperCase(); if (a < b){return -1;} else if(a > b){return 1;} else {return 0;}};
			} else {
				_so = function(a, b) {a = a.toUpperCase(); b = b.toUpperCase(); if (a > b){return -1;} else if(a < b){return 1;} else {return 0;}};
			}		
		} else if (st.toUpperCase() == 'TEXT'){ 
			if(!so || so.toUpperCase() != "DESC"){
				_so = function(a, b) {if (a < b){return -1;} else if(a > b){return 1;} else {return 0;}};
			} else {
				_so = function(a, b) {if (a > b){return -1;} else if(a < b){return 1;} else {return 0;}};
			}		
		} else if (st.toUpperCase() == 'NUMERIC'){
			if(!so || so.toUpperCase() != "DESC"){
				_so = function(a,b) {return a - b;};
			} else {
				_so = function(a,b) {return b - a;};
			}			
		}
		return a.sort(_so);
	},
	ArrayToList: function(a,d){
		if(!d){d = ",";}
		var re = /[,]/gi;
		return a.toString().replace(re, d);
	},
	ArrayLen: function(a){		
		return a.length;		
	},	
	Ceiling: function(n){
		return Math.ceil(n);
	},
	Compare: function(s1,s2){
		if (s1 == s2) {return 0;}
		if (s1 > s2) {return 1;}	
		else {return -1;}
	},
	CompareNoCase: function(s1,s2){
		return this.Compare(s1.toUpperCase(),s2.toUpperCase());
	},
	DateDiff: function(dp,d1,d2){
		var dt1 = new Date(d1);
		var dt2 = new Date(d2);
		var iDiffMS = dt2.valueOf() - dt1.valueOf();
		var dtDiff = new Date(iDiffMS);
		var nYears  = dt2.getUTCFullYear() - dt1.getUTCFullYear();
		var nMonths = dt2.getUTCMonth() - dt1.getUTCMonth() + (nYears!==0 ? nYears*12 : 0);
		var nQuarters = nMonths / 3;		
		var nMilliseconds = iDiffMS;
		var nSeconds = iDiffMS / 1000;
		var nMinutes = nSeconds / 60;
		var nHours = nMinutes / 60;
		var nDays  = nHours / 24;
		var nWeeks = nDays / 7;
		var iDiff = 0;		
		switch(dp.toLowerCase()){
			case "yyyy": return nYears;
			case "q": return nQuarters;
			case "m": return nMonths;
			case "y": return nDays;
			case "d": return nDays;
			case "w": return nDays;
			case "ww":return nWeeks;		
			case "h": return nHours;
			case "n": return nMinutes;
			case "s": return nSeconds;
			case "ms":return nMilliseconds;
			default: return "invalid interval: '" + dp + "'";
		}
	},
	DecimalFormat: function(n){
		var n = Number(n);
		return n.toFixed(2);	
	},
	DollarFormat: function(n) {
		var n = n.toString().replace(/\$|\,/g,'');
		n = n.toString().replace('(','-');
		n = n.toString().replace(')','');
		if(isNaN(n)){
			num = "0";
		}
		var	sign = (n == (n = Math.abs(n)));
			n = Math.floor(n*100+0.50000000001);
		var	cents = n%100;
			n = Math.floor(n/100).toString();
		
		if(cents < 10){
			cents = "0" + cents;
		}
		for (var i = 0; i < Math.floor((n.length-(1+i))/3); i++){
			n = n.substring(0,n.length-(4*i+3))+','+
			n.substring(n.length-(4*i+3));
		}
		return (((sign)?'':'(') + '$' + n + '.' + cents + ((sign)?'':')'));
	},
	Find: function(sb,s){
		 return s.toString().indexOf(sb) + 1;
	},
	FindNoCase: function(sb,s){		
		return this.Find(sb.toUpperCase(),s.toUpperCase());
	},
	Insert: function(sb,s,p){
		return s.slice(0, p) + sb + s.slice(p, s.length);
	},
	IsDate: function(d){
		var datePat 	= /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
		var matchArray 	= d.toString().match(datePat);	
		if (matchArray === null) {
			return false;
		}	
		var month 	= matchArray[1];
		var day 	= matchArray[3];
		var year 	= matchArray[5];	
		if (month < 1 || month > 12) { 
			return false;
		}	
		if (day < 1 || day > 31) {
			return false;
		}	
		if ((month==4 || month==6 || month==9 || month==11) && day==31) {
			return false;
		}	
		if (month == 2) { 
			var isleap = (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0));
				if (day > 29 || (day==29 && !isleap)) {
					return false;
				}
		}
		return true; 
	},
	IsNumeric: function(s){
		if (isNaN(s)){
			return false;
		} else {
			return true;
		}
	},
	LCase: function(s){		
		return s.toLowerCase();			
	},
	Left: function(s,c){
		return s.slice(0, c);
	},	
	Len: function(s){		
		return s.length;
	},
	ListAppend: function(l, v, d){
		if(!d){d = ",";}
		var r = ""; 
		if (this.ListLen(l)){
			r = l + d + v;
		} else {
			r = v;
		}
		return r;
	},
	ListDeleteAt: function(l, p, d){
		if(!d){d = ",";}
		var i,posInList;
		var posInArray = p - 1;
		var thisD 	= "";
		var r = ""; 
		for(i = 0; i < l.split(d).length; i++){
			if (i != posInArray){
				posInList = i + 1;
				if (r.length){
					thisD 	= d;
				}
				r += thisD + this.ListGetAt(l, posInList, d);
			}
		}
		return r;
	},
	ListFind: function (l,v,d){
		if(!d){d = ",";}
		var r = 0;
		var listToArray = l.split(d);
		for (var i=0; i < listToArray.length; i++){		
			if (listToArray[i] == v){
				r = i + 1;
				break;
			}
		}
		return r;
	},
	ListFindNoCase: function(l,v,d){
		if(!d){d = ",";}
		return this.ListFind(l.toUpperCase(), v.toUpperCase(), d);
	},
	ListGetAt: function (l, p, d){
		if(!d){d = ",";}
		return l.split(d)[p - 1];
	},	
	ListLen: function(l,d){			
		if(!d){d = ",";}		
		return l.split(d).length;
	},	
	ListToArray: function(l,d){		
		var r,a,i;			
		if(!d){d = ",";}		
		r = [];
		a = l.split(d);			
		for(i=1; i <= a.length; i++){
			r[i] = a[i - 1];
		}			
		return r;	
	},
	LTrim: function(s){
		return s.toString().replace(/^\s*/, '');
	},	
	Mid: function(s, start, c){
		start -= 1;
		return s.slice(start,start + c);
	},
	Replace: function(s,sb1,sb2,sc){
		if(!sc || sc.toUpperCase() != "ALL"){
			sc = "";
		} else {
			sc ="g";
		} 	
		var re = new RegExp(sb1,sc);
		return s.replace(re,sb2);
	},
	ReplaceNoCase: function(s,sb1,sb2,sc){
		if(!sc || sc.toUpperCase() != "ALL"){
			sc = "i";
		} else {
			sc ="gi";
		} 	
		var re = new RegExp(sb1,sc);
		return s.replace(re,sb2);
	},
	Reverse: function(s){
		var i = s.length;
		var r = "";	
		for (i; 0 <= i; i--){	
			r += s.charAt(i);	
		}	
		return r;
	},
	Right: function(s,c){
		return s.slice(s.length - c, s.length);
	},
	Round: function(n,p) {
		if (!isNaN(n.toFixed(p))){
			return n.toFixed(p);
		} else {
			return n;
		}
	},
	RTrim: function(s){
		return s.toString().replace(/\s*$/, '');
	},
	Trim: function(s){
		return s.replace(/^\s*|\s*$/g,'');
	},
	UCase: function(s){		
		return s.toUpperCase();			
	},
	URLDecode: function(s){
		return unescape(s);
	},	
	URLEncodedFormat: function(s){
		return encodeURI(s);
	}
};

function SingleSelectRequired(Form, Field) {
	var itemSelected =	eval("document." + Form + "." + Field + ".selectedIndex");
	if (itemSelected == 0) {
		return false;
	} 
	else {
		return true;
	}
}

function ExtendJS(FormName) {
	var errorMessage = "";
	
	// check to make sure a country was selected
	if (!SingleSelectRequired(FormName,'Country')) {
		errorMessage = errorMessage + "You must select a valid contact country.\n\n";
	} 
	
	// check to see which country was selected
	// if the customer selected USA, check the state field
	// if the customer selected CAN, check the province field
	
	if (document.contact.Country.value == "USA") {
		if (!SingleSelectRequired(FormName,'state')) {
			errorMessage = errorMessage + "You must select a valid contact state.\n\n";
		}
		
		if (document.contact.Zip.value == "") {
			errorMessage = errorMessage + "You must enter a valid contact zip/postal code.\n\n";
		}
	}
	else 
	{
		if (document.contact.Country.value == "CAN") {		
			if (!SingleSelectRequired(FormName,'canProvince')) {
				errorMessage = errorMessage + "You must select a valid contact province.\n\n";
			}
		}
	}
	
	// check to make sure the email address they entered matches the validated email address
	if (document.contact.APAEmail.value != document.contact.APAEmail2.value){
		errorMessage = errorMessage + "The two email addresses that you entered do not match.\n\n";
	}
	
	// check the length of the phone number.  It should be at least 10 digits.
	if (document.contact.HomePhone.value.length < 10 && document.contact.workPhone.value.length < 10){
		errorMessage = errorMessage + "You must enter a valid telephone number including the country code or area code.\n\n";
		
		// set focus to home phone number if no phone number has been entered
		document.contact.HomePhone.focus();
	}
	
	// check to make sure the degree date is within 50 years ago
	var dt = new Date();
	var date_degree = document.getElementById('date_degree').value;
	var yearDiff = LeftCorner.DateDiff('yyyy', date_degree, dt); 
	
	if (yearDiff > 50) {
		errorMessage = errorMessage = "You must enter a valid degree date.\n\n";
		
		// set focus to Degree Date if an invalid date was entered
		document.contact.date_degree.focus();
	}
			
	if (errorMessage != ""){
		alert(errorMessage);
		return false;
	}
}
