/*
* Collection of Javascript String functions for evaluating and verifying input.
*
* @author       Seisan Consulting   2-14-2007
*/
function StringFunct(){
	/*
	* Function to take a string and capitalize the first character of each word in the string.
	* Pre-Condtion: The string must exist and not be blank.
	* Post-Condition: The string is returned with each first character of every word capitalized.
	*
	* @param        str - the string to be capitalized.
	* @return		newVal - A new string with the firts letter of each word capitalized.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.capitalize = function(str) {
        var newVal = '';
        var val = str.split(' ');
        for(var c=0; c < val.length; c++) {
            newVal += val[c].substring(0,1).toUpperCase() +
			val[c].substring(1,val[c].length) + ' ';
        }
        return newVal;
	}

	/*
	* Function to take a string and remove all blank spaces from the string.
	* Pre-Condtion: The string must exist and not be blank.
	* Post-Condition: The string has all blank spaces removed.
	*
	* @param        st - the string to have blank spaces removed
	* @return		A new string with the blank spaces removed
	* @author       Seisan Consulting   2-16-2006
	*/
	this.trim = function(st) {
		var len = st.length;
		var begin = 0, end = len - 1;
		while (st.charAt(begin) == " " && begin < len) {
			begin++;
		};
		while (st.charAt(end) == " " && begin < end) {
			end--;
		};
		return st.substring(begin, end+1);
	};

	/*
	* Function to evaluate whether a string is empty.
	* Pre-Condtion: The string must exist.
	* Post-Condition: A boolean value that contains the evaluation of whether the string is empty or not is returned.
	*
	* @param        str - the string to be evaluated
	* @return		Boolean value containing the evaluation of the string.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.isBlank = function(str){
		str = this.trim(str);
		if(str == ''){
			return true;
		};
		return false;
	};

	/*
	* Function to evaluate whether an object contains any <script> tags.
	* Pre-Condtion: The object must exist.
	* Post-Condition: A boolean value that contains the evaluation of whether the object contains any <script> tags is returned.
	*				  If the object contains script tags return false, else true.
	*
	* @param        obj - the object to be evaluated
	* @return		Boolean value containing the evaluation of the object.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkScript = function(obj){
		if(obj.toUpperCase().indexOf("<SCRIPT") >= 0){
			return false
		}
		else {
			return true;
		};
	};

	/*
	* Function to evaluate whether an object is undefined.
	* Pre-Condtion: The object must exist.
	* Post-Condition: A boolean value contains the evaluation of whether the object is undefined is returned.
	*				  If the object is undefined return false, else true.
	*
	* @param        obj - the object to be evaluated
	* @return		Boolean value containing the evaluation of the object.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkObj = function(obj){
		if(obj){
			return true;
		}
		else{
			return false;
		};
	};

	/*
	* Function to evaluate whether a string is undefined.
	* Pre-Condtion: The string must not be null.
	* Post-Condition: A boolean value contains the evaluation of whether the string is undefined is returned.
	*				  If the string is undefined return false, else true.
	*
	* @param        str - the string to be evaluated
	* @return		Boolean value containing the evaluation of the string.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkObjString = function(str){
		var start = 0;
		var sStr = "";
		while(str.indexOf(".",start+1)!= -1){
			start = str.indexOf(".",start+1);
			sStr = str.substring(0,start);
			if(!this.checkObj(eval(sStr))){
				return false;
			};
		};
		if(!this.checkObj(eval(str))){
			return false;
		};
		return true;
	};

	/*
	* Function to evaluate whether an email address in the form of a string is correctly formatted.
	* Pre-Condtion: The string must not be null.
	* Post-Condition: A boolean value contains the evaluation of whether the string is undefined is returned.
	*				  If the email string is incorrectly formatted return false, else true.
	*
	* @param        str - the string to be evaluated
	* @return		Boolean value containing the evaluation of the email address.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkEmail = function(str) {
		if (str.indexOf("@")<3){
			return false;
		};

		if ((str.lastIndexOf(".")<5)){
			return false;
		};

		if(str.lastIndexOf(".") != 4){
			return false;
		};

		return true;
	};

	/*
	* Function to evaluate whether string contains an integer.
	* Pre-Condtion: The string must not be null.
	* Post-Condition: A boolean value contains the evaluation of whether the string contains an integer and is returned.
	*				  If the string is an integer return false, else return true.
	*
	* @param        str - the string to be evaluated
	* @return		Boolean value containing the evaluation of the string.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkInteger = function(str){

		if(!this.checkNumeric(str)){
			return false;
		};

		if(str.indexOf(".") > -1){
			return false;
		};

		return true;
	};

	/*
	* Function to evaluate whether string contains an integer and the integer is > 0.
	* Pre-Condtion: The string must not be null.
	* Post-Condition: A boolean value contains the evaluation of whether the string contains an integer and is > 0 and is returned.
	*				  If the string is an integer and is > 0 return false, else return true.
	*
	* @param        str - the string to be evaluated
	* @return		Boolean value containing the evaluation of the string.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkPositiveInteger = function(str){
		if(!this.checkInteger(str)){
			return false;
		};
		var val = parseInt(str);
		return (val>=0);
	};

	/*
	* Function to evaluate whether string contains a monetary number and the number is > 0.
	* Pre-Condtion: The string must not be null.
	* Post-Condition: A boolean value contains the evaluation of whether the string contains a monetary number and the number is >= 0 and is returned.
	*				  If the string contains a number and the number is >= 0 return false, else return true.
	*
	* @param        str - the string to be evaluated
	* @return		Boolean value containing the evaluation of the string.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkMoney = function(str){
		if(str.lastIndexOf(".")  < str.length && (str.lastIndexOf(".") >= str.length-3)){
			if(!this.checkNumeric(str)){
				return false;
			};
			var val = parseFloat(str);
			return (val>=0)
		};
		return false;
	};

	/*
	* Function to evaluate whether string contains a number and the number is > 0.
	* Pre-Condtion: The string must not be null.
	* Post-Condition: A boolean value contains the evaluation of whether the string contains a number and the number is >= 0 and is returned.
	*				  If the string contains a number and the number is >= 0 return false, else return true.
	*
	* @param        str - the string to be evaluated
	* @return		Boolean value containing the evaluation of the string.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkPositiveNumeric = function(str){
		//Pre: str != null
		//Post: If str is a Number and a greater or equal to zero
		//		 return true, else false
		if(!this.checkNumeric(str)){
			return false;
		};
		var val = parseFloat(str);
		return (val>=0)
	};


	/*
	* Function to evaluate whether string contains a number.
	* Pre-Condtion: The string must not be null.
	* Post-Condition: A boolean value contains the evaluation of whether the string contains a number and is returned.
	*				  If the string contains a number return false, else return true.
	*
	* @param        str - the string to be evaluated
	* @return		Boolean value containing the evaluation of the string.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkNumeric = function(str){
		//Pre: str != null
		//Post: If str is a Number return true, else false
		var strLength = str.length;
		var isFloat = false;

		var error = false;
		var i = 0;
		for (i; i < strLength; i++){
			if ( (str.charAt(i) < '0') || (str.charAt(i) > '9') ){
				if(!isFloat && (str.charAt(i) == '.')){
					isFloat = true;
				}
				else if ( i == 0){
					if ((str.charAt(i) != '-')){
						error = true;
						break;
					};
				}
				else{
					error = true;
					break;
				};
			};
		};
		return !error;
	};

	/*
	* Function to evaluate whether string contains a phone number.
	* Pre-Condtion: The string must not be null.
	* Post-Condition: A boolean value contains the evaluation of whether the string contains a phone number and the number is properly formatted and is returned.
	*				  If the string contains a phone number and the phone number is properly formatted return true, else return false.
	*
	* @param        str - the string to be evaluated
	* @return		Boolean value containing the evaluation of the string.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkPhone = function(str){
		if(this.checkPositiveNumeric(str)){
			if(str.length == 10 || str.length == 7){
				return true;
			}
			else {
				return false;
			};
		}
		else{
			if(this.isBlank(str)){
				return false;
			};
			var x = 0;
			if ((this.checkNumeric(str.charAt(0))) && ((str.charAt(1) == '-') || (str.charAt(1) == '.'))){
				x=2;
			};
			if (!((str.charAt(x+3) == '-')&&(str.charAt(x+3) == '.')) && !((str.charAt(x+7) == '-')||(str.charAt(x+7) == '.'))){
				return false;
			};
			var strLength = str.length;
			var error = false;
			if (strLength < 12){
				return false;
			};
			for (i=x; i < strLength; i++){
				if ( (str.charAt(i) < '0') || (str.charAt(i) > '9') ){
					if (!((i  == (x + 3)) || (i  == (x + 7)))){
						error = true;
						break;
					};
				};
			};
			return !error;
		};
	};

	/*
	* Function to evaluate whether string is a valid postal code.
	* Pre-Condtion: The string must not be null.
	* Post-Condition: A boolean value contains the evaluation of whether the string is a valid postal code and is returned.
	*				  If the string is a valid postal code return true, else return false.
	*
	* @param        str - the string to be evaluated
	* @return		Boolean value containing the evaluation of the string.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkPostalCode = function(str){
		if(str.length == 5 || str.length == 10){
			return true;
		}
		else {
			return false;
		}
	}

	/*
	* Function to evaluate whether string is a valid Zipcode.
	* Pre-Condtion: The string must not be null.
	* Post-Condition: A boolean value contains the evaluation of whether the string is a valid ZipCode and is returned.
	*				  If the string is a valid ZipCode return true, else return false.
	*
	* @param        str - the string to be evaluated
	* @return		Boolean value containing the evaluation of the string.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkZip = function(str){
		if (str.length < 5){
			return false;
		};
		if(!this.checkNumeric(str.charAt(0) + str.charAt(1) + str.charAt(2) + str.charAt(3) + str.charAt(4))){
			return false;
		};
		if(str.length == 5){
			return true;
		};
		if((str.charAt(5) != '-') || (str.length != 10)){
			return false;
		};
		if(!this.checkNumeric(str.charAt(6) + str.charAt(7) + str.charAt(8) + str.charAt(9))){
			return false;
		};
		return true;
	};

	/*
	* Function to evaluate whether string is a valid Time.
	* Pre-Condtion: The string must not be null.
	* Post-Condition: A boolean value contains the evaluation of whether the string is a valid time and is returned.
	*				  If the string is a valid time return true, else return false.
	*
	* @param        str - the string to be evaluated
	* @return		Boolean value containing the evaluation of the string.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkTime = function(str){
		var i=0;
		if (!this.checkNumeric(str.charAt(0))){
			return false;
		};
		if (str.charAt(1) == ":"){
			i=1;
		}
		else if (!this.checkNumeric(str.charAt(1))){
			return false;
		}
		else if ((i!=1) && (str.charAt(2) == ":")){
			i=2;
		}
		else if(!this.checkNumeric(str.charAt(2))){
			return false;
		};
		if ((i==2) && (str.charAt(0) != "1")){
			return false;
		};
		if (!this.checkNumeric(str.charAt(i+1))){
			return false;
		};
		if (!this.checkNumeric(str.charAt(i+2))){
			return false;
		};
		if (str.charAt(i+3) != " "){
			return false;
		};
		if ((str.charAt(i+4).toUpperCase() != "A") && (str.charAt(i+4) != "P")){
			return false;
		};
		if(str.charAt(i+5).toUpperCase() != "M"){
			return false;
		};
		return true;
	};

	/*
	* Function to evaluate whether the integer passed is a leap year.
	* Pre-Condtion: The integer must not be zero.
	* Post-Condition: A boolean value contains the evaluation of whether the integer is a valid leap year and is returned.
	*				  If the integer is a valid leap year return true, else false.
	*
	* @param        intYear - the integer to be evaluated
	* @return		Boolean value containing the evaluation of the integer.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.isLeapYear = function(intYear){
		if ((((intYear % 4) == 0) && ((intYear % 100) != 0)) || (((intYear % 100) == 0) && ((intYear % 400) == 0))){
			return true;
		}
		else {
			return false;
	   };
	};

	/*
	* Function to correct a year with only two digits to be year 2000 compliant.
	* Pre-Condtion: The integer must not be zero.
	* Post-Condition: If the year is a two digit year the correct value is returned to be year 2000 compliant.
	*
	* @param        number - the integer to be evaluated
	* @return		The corrected year 2000 compliant year number.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.y2k = function(number) {
		return (number < 1000) ? number + 1900 : number;
	};

	/*
	* Function to evaluate whether string is a valid Date.
	* Pre-Condtion: The string must not be null.
	* Post-Condition: A boolean value contains the evaluation of whether the string is a valid Date and is returned.
	*				  If the string is a valid Date return true, else return false.
	*
	* @param        str - the string to be evaluated
	* @return		Boolean value containing the evaluation of the string.
	* @author       Seisan Consulting   2-16-2006
	*/
	this.checkDate = function(str){
		var firstSlash = str.indexOf("/");
		var secondSlash = str.indexOf("/",str.indexOf("/")+1);
		var month = str.substring(0,firstSlash);
		var day = str.substring(firstSlash+1,secondSlash);
		var year = str.substring(secondSlash+1,str.length);
		if(!this.checkPositiveNumeric(month) || !this.checkPositiveNumeric(day) || !this.checkPositiveNumeric(year)){
			return false;
		};
		var today = new Date();
		year = ((!year) ? this.y2k(today.getYear()):year);
		month = ((!month) ? today.getMonth():month-1);
		if (!day){
			return false;
		};
		var test = new Date(year,month,day);
		if ( (this.y2k(test.getYear()) == year) &&
			 (month == test.getMonth()) &&
			 (day == test.getDate()) ){
			return true;
		}
		else {
			return false;
		};
	};

};

var StringFunctions = new StringFunct();
