//----------------------------------------------------------------------------------------------------
// File: FBI_Field_Check.js
//
// Description:
//	This JavaScript library provides functions for FBI Data Entry Validations;
//
//	---------------------------------------------------------------------
//	Available Functions:
//	---------------------------------------------------------------------
//	* fbi_date_check(input_obj, nullable, min_year, max_year, title)
//	* fbi_name_check(input_obj, nullable, title)
//	* fbi_full_name_check(input_obj, nullable, title)
//	* fbi_last_name_check(input_obj, nullable)
//	* fbi_first_name_check(input_obj, nullable)
//	* fbi_middle_name_check(input_obj, nullable, default_val)
//	* fbi_alias_name_check(input_obj, nullable, default_val, min)
//	* fbi_dob_check(input_obj, nullable, min_year, max_year)
//	* fbi_ssn_check(input_obj, nullable)
//	* fbi_retype_check(input_obj, cmp_obj, title)
//	* fbi_weight_check(input_obj, nullable, min, max, zeroable)
//	* fbi_address_check(input_obj, nullable, address_title)
//	* fbi_city_check(input_obj, nullable, city_title)
//	* fbi_zip_check(input_obj, nullable, min_digit, max_digit, numeric_only)
//	* fbi_email_check(input_obj, nullable)
//	* fbi_phone_check(input_obj, nullable, min_digit, max_digit)
//	* fbi_dln_check(input_obj, nullable, dln_title)
//	*
//	* fbi_str_range_check(input_obj, nullable, range, title, msg)
/*	Example:
		if ( !fbi_str_range_check(form.elements["i_ssn"], true, DIGIT, "SSN", "SSN must contain only numberic characters.") )
			return false; 
*/
//	* fbi_str_format_check(input_obj, nullable, form, title, msg)
//	* fbi_null_check(input_obj, nullable, title)
//	* fbi_no_select_check(input_obj, nullable, title, nvl)
//	*
//	* fbi_string_alpha_only(_string)
//	* fbi_alpha_check(input_obj, nullable, title)
//	* fbi_string_alpha_upper_only(_string)
//	* fbi_alpha_upper_check(input_obj, nullable, title)
//	* fbi_string_alpha_lower_only(_string)
//	* fbi_alpha_lower_check(input_obj, nullable, title)
//	* fbi_string_numeric_only(_string)
//	* fbi_numeric_check(input_obj, nullable, title)
//	* fbi_string_alpha_numeric_only(_string)
//	* fbi_alpha_numeric_check(input_obj, nullable, title)
//	*
//	* CheckValidDate(year, month, day, title)
//	* DateCmpToday(year, month, day, nYearDiff, nMonthDiff, nDayDiff)
//	* isLeapYear(year)
//	*
//	* isFirstLetterAlpha(str)
//	* isLastLetterAlpha(str)
//	* isAlphaLetter(c)
//	* isWithinLetterSet(str,dictionary)
//	*
//	* fbi_trim(inputString)
//	* fbi_upper(inputString)
//	* fbi_lower(inputString)
//	* fbi_trim_input(input_obj)
//	* fbi_upper_input(input_obj)
//	* fbi_lower_input(input_obj)
//	* fbi_trim_upper_input(input_obj)
//	* fbi_trim_lower_input(input_obj)
//	* highlightInput(obj)
//	*
//	* validate_string(str, char_range, valid_flag, expression)
//	* CheckNameString(str, title)
//	* fbi_CharType(ch)
//	* highlightInputSection(obj, stt, edd, dir)
//	* setSelectionRange(input, selectionStart, selectionEnd)
//	---------------------------------------------------------------------
//
// Revisions:
//	10-09-2008	Lei Tang - Created
//	08-25-2009	Lei Tang - Modified
//	09-26-2011	Lei Tang - Modified
//
// Copyright (c)2008 Cogent Systems, Inc. All rights reserved.

/****************************************************************
 ****************************************************************/
// COMMON CHARACTER SET
var L_ALPHA = "a-z";
var U_ALPHA = "A-Z";
var ALPHA = "a-zA-Z";
var DIGIT = "\\d";
var ALPHA_NUMERIC = ALPHA + DIGIT;
var PUNCTUATION = "-!\"#$%&'()*+,./:;<=>?@[\\\]_`{|}^~";

// DEFINED CHARACTER SET
var SET_NUMERIC = DIGIT + "\.-";
var SET_LAST_NAME = ALPHA + "-";
var SET_FIRST_NAME = ALPHA + " ";
var SET_MIDDLE_NAME = ALPHA + " ";
var SET_FULL_NAME = ALPHA + "- ,";
var SET_ALIAS_NAME = ALPHA + "- ,";
var SET_ADDRESS = ALPHA_NUMERIC + " ";
//var SET_ADDRESS = ALPHA_NUMERIC + "#() ";
var SET_CITY = ALPHA + " ";
var SET_ZIP = DIGIT + "-";
var SET_DLN = ALPHA_NUMERIC;
var SET_PHONE_LETTERS = DIGIT + "() -";
var SET_EMAIL_INVALID = ",\\s#*&%!$\\\\";

// COMMONE FORMS
var FORM_NUMERIC = /^[-]{0,1}[\d]+[\.]{0,1}[\d]+$/;
//var FORM_EMAIL = /^([^@]+)@([^@.]+\.)+([^@.]{2,3})$/;
var FORM_EMAIL = /^\s*[\w\-\+_]+(\.[\w\-\+_]+)*\@[\w\-\+_]+\.[\w\-\+_]+(\.[\w\-\+_]+)*\s*$/;
//var FORM_COMMON_NAME = /^([a-zA-Z]+[- ]{0,1})*[^ -]$/;
var FORM_COMMON_NAME = /^([a-zA-Z]+[- ]){0,1}([a-zA-Z]+)$/;
var FORM_ALIAS_NAME =  /^([a-zA-Z]+[- ]{0,1})*([a-zA-Z]+,[a-zA-Z]+)([- ]{0,1}[a-zA-Z]+)*$/;
// full name has same pattern with alias, but different meanings
var FORM_FULL_NAME =  /^([a-zA-Z]+[- ]{0,1})*([a-zA-Z]+,[a-zA-Z]+)([- ]{0,1}[a-zA-Z]+)*$/;

// VALIDATION FLAG
var CHECK_INVALID_RANGE = 0;
var CHECK_RANGE = 1;

// RETURN FLAG
var VALID_OK = 1;
var NULL_ERROR = 0;
var RANEG_ERROR = -1;
var FORM_ERROR = -2;
var LOWER_CASE_LETTER = 0;
var UPPER_CASE_LETTER = 1;
var NUMERIC_LETTER = 2;
var HYPHEN_LETTER = 3;
var SPACE_LETTER = 4;
var COMMA_LETTER = 5;
var SPECIAL_LETTER = 6;
var ALPHA_LETTER = 7;
var INVALID_MONTH = -1;
var INVALID_DAY = -2;
var INVALID_YEAR = -3;

// DEPRECATED
var LAST_LETTERS="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-";
var FIRST_LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ- ";
var MIDDLE_LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ- ";
var ALIAS_LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ- ,";
var ADDRESS_LETTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ#() ";
var PHONE_LETTERS = "0123456789()- ";
var ZIP_LETTERS = "0123456789-";
var NUMBER_LETTERS = "0123456789.-";
var NATRUAL_NUMBER_LETTERS = "0123456789";

// Browser Detection
var gbIsFirefox = navigator.userAgent.match( /Firefox/ );
var gbIsChrome = navigator.userAgent.match( /Chrome/ );
var gbIsSafari = navigator.userAgent.match( /Safari/ );



// ******************************************************************** //
//       FBI VALIDATION FUNCTIONS
// ******************************************************************** //

function fbi_date_check(input_obj, nullable, min_year, max_year, title)
{
	fbi_trim_input(input_obj);
	if (title == undefined)
		title = "Date";
	if (!fbi_null_check(input_obj, nullable, title))
		return false;
	var s_dob = input_obj.value;
	if (s_dob == "" && nullable) return true;
	if (validate_string(s_dob, DIGIT, 1) != VALID_OK)
	{
		alert( title + " must contain only numberic characters. Please enter it again." );
		highlightInput(input_obj);
		return false;
	}
	month = Number(s_dob.substring(0, 2));
	day = Number(s_dob.substring(2, 4));
	year = Number(s_dob.substring(4, 8));
	
	var today = new Date();
	if ( min_year == undefined )
		min_year = 1901;
	if ( max_year == undefined )
	{
		max_year = today.getYear();
		if ( gbIsFirefox || gbIsChrome || gbIsSafari || max_year < 200 )
			max_year += 1900;
	}
	
	if (year < min_year || year > max_year) {
		alert( title + " - Invalid date. Year must between " + min_year + " and " + max_year + ". Please re-enter it as MMDDYYYY.");
		highlightInputSection(input_obj, 4, 8, -4);
		return false;
	}
	// Check data format
	var error_code = CheckValidDate(year, month, day, title + " - ");
	if ( error_code ) {
		if ( error_code == INVALID_MONTH )
			setSelectionRange(input_obj, 0, 2);
		if ( error_code == INVALID_DAY )
			setSelectionRange(input_obj, 2, 4);
		if ( error_code == INVALID_YEAR )
			setSelectionRange(input_obj, 4, 8);
		return false;
	}
	return true;
}

// ----------------------------------------------------------------------------------
//        NAME
// ----------------------------------------------------------------------------------
function fbi_name_check(input_obj, nullable, title)
{
	fbi_trim_upper_input(input_obj);
	if (title == undefined)
		title = "Name"
	if (!fbi_null_check(input_obj, nullable, title))
		return false;
	var s_name = input_obj.value;
	if (s_name == "" && nullable)
		return true;
	var res = validate_string(s_name, SET_FULL_NAME, 1, FORM_COMMON_NAME);
	if (res != VALID_OK)
	{
		if (res == RANEG_ERROR)
			alert( title + " must contain only alphabetic characters. Blank, comma or hyphens are also allowed.");
		else
			CheckNameString(s_name, title);
		highlightInput(input_obj);
		return false;
	}
	return true;
}

// ----------------------------------------------------------------------------------
//        FULL NAME, Last,First Middle Suffix
// ----------------------------------------------------------------------------------
function fbi_full_name_check(input_obj, nullable, title)
{
	fbi_trim_upper_input(input_obj);
	if (title == undefined)
		title = "Name"
	if (!fbi_null_check(input_obj, nullable, title))
		return false;
	var s_full_name = input_obj.value;
	var res = validate_string(s_full_name, SET_FULL_NAME, 1, FORM_FULL_NAME);
	if (res != VALID_OK)
	{
		if (res == RANEG_ERROR)
			alert(title + " must contain only alphabetic characters. Comma, blanks or hyphens are also allowed.");
		else if (!CheckNameString(s_full_name, title)) {}
		else
		{
			alert("Please enter valid name format.\n\nThe format shall be [Last,First Middle Suffix]. \ne.g.: DOE,JOHN DAVID \n\n")
		}
		highlightInput(input_obj);
		return false;
	}
	return true;
}

// ----------------------------------------------------------------------------------
//        LAST NAME
// ----------------------------------------------------------------------------------
function fbi_last_name_check(input_obj, nullable)
{
	fbi_trim_upper_input(input_obj);
	if (!fbi_null_check(input_obj, nullable, "Last Name"))
		return false;
	var s_last_name = input_obj.value;
	if (s_last_name == "" && nullable)
		return true;
	var res = validate_string(s_last_name, SET_LAST_NAME, 1, FORM_COMMON_NAME);
	if (res != VALID_OK)
	{
		if (res == RANEG_ERROR)
			alert("Last Name must contain only alphabetic characters. Hyphens are also allowed.");
		else
			CheckNameString(s_last_name, "Last Name");
		highlightInput(input_obj);
		return false;
	}
	return true;
}
// ----------------------------------------------------------------------------------
//        FIRST NAME
// ----------------------------------------------------------------------------------
function fbi_first_name_check(input_obj, nullable)
{
	fbi_trim_upper_input(input_obj);
	if (!fbi_null_check(input_obj, nullable, "First Name")) return false;
	var s_first_name = input_obj.value;
	if (s_first_name == "" && nullable)
		return true;
	var res = validate_string(s_first_name, SET_FIRST_NAME, 1, FORM_COMMON_NAME);
	if (res != VALID_OK)
	{
		if (res == RANEG_ERROR)
			alert("First Name must contain only alphabetic characters. Blanks are also allowed.");
		else
			CheckNameString(s_first_name, "First Name");
		highlightInput(input_obj);
		return false;
	}
	return true;
}
// ----------------------------------------------------------------------------------
//        MIDDLE NAME
// ----------------------------------------------------------------------------------
function fbi_middle_name_check(input_obj, nullable, default_val)
{
	fbi_trim_upper_input(input_obj);
	if (!fbi_null_check(input_obj, nullable, "Middle Name"))
		return false;
	var s_middle_name = input_obj.value;
	if (default_val == undefined)
		default_val = "";
//	if (fbi_trim(default_val) != "")
//	{
	if (s_middle_name == default_val)
		return true;
	if (s_middle_name == "")
	{
		input_obj.value = default_val;
		return true;
	}
//	}
	var res = validate_string(s_middle_name, SET_MIDDLE_NAME, 1, FORM_COMMON_NAME);
	if (res != VALID_OK)
	{
		if (res == RANEG_ERROR)
			alert("Middle Name must contain only alphabetic characters. Blanks are also allowed.");
		else
			CheckNameString(s_middle_name, "Middle Name");
		highlightInput(input_obj);
		return false;
	}
	return true;
}
// ----------------------------------------------------------------------------------
//        ALIAS NAME
// ----------------------------------------------------------------------------------
function fbi_alias_name_check(input_obj, nullable, default_val, min)
{
	fbi_trim_upper_input(input_obj);
	if (!fbi_null_check(input_obj, nullable, "Alias Name"))
		return false;
	var s_aka = input_obj.value;
	if (default_val == undefined)
		default_val = "";
//	if (fbi_trim(default_val) != "")
//	{
	if (s_aka == default_val)
		return true;
	if (s_aka == "")
	{
		input_obj.value = default_val;
		return true;
	}
//	}
	if ( min == undefined ) min = 3;
	if (s_aka.length < min) {
		alert("Alias name must contain at least " + min + " character(s)!")
		highlightInput(input_obj);
		return false;
	}
	var res = validate_string(s_aka, SET_ALIAS_NAME, 1, FORM_ALIAS_NAME);
	if (res != VALID_OK)
	{
		if (res == RANEG_ERROR)
			alert("Alias Name must contain only alphabetic characters. Comma, blanks or hyphens are also allowed.");
		else if (!CheckNameString(s_aka, "Alias Name")) {}
		else
		{
			alert("Please enter valid alias name.\n\nThe format shall be the surname followed by a comma (,), followed by the given name(s) separated by blank or hyphen. \ne.g.: DOE,JOHN DAVID \n\nUse 'X' if surname or given name does not exist \ne.g.: X,Yun-Yang")
		}
		highlightInput(input_obj);
		return false;
	}
	return true;
}
// ----------------------------------------------------------------------------------
//        DOB
// ----------------------------------------------------------------------------------
function fbi_dob_check(input_obj, nullable, min_year, max_year, format)
{
	
	if (format == undefined || format != "YYYYMMDD")
		format = "MMDDYYYY";
	
	fbi_trim_input(input_obj);
	if (!fbi_null_check(input_obj, nullable, "Date of Birth"))
		return false;
	var s_dob = input_obj.value;
	if (s_dob == "" && nullable) return true;
	if (s_dob.length < 8) {
		alert("Date of Birth has to be 8 digit, in format " + format);
		highlightInput(input_obj);
		return false;
	}
	if (validate_string(s_dob, DIGIT, 1) != VALID_OK)
	{
		alert("Date of Birth must contain only numberic characters. Please enter it again.");
		highlightInput(input_obj);
		return false;
	}
	
	if (format == "MMDDYYYY")
	{ 
		month = Number(s_dob.substring(0, 2));
		day = Number(s_dob.substring(2, 4));
		year = Number(s_dob.substring(4, 8));
	}
	else
	{
		month = Number(s_dob.substring(4, 6));
		day = Number(s_dob.substring(6, 8));
		year = Number(s_dob.substring(0, 4));
	}
	
	var today = new Date();
	
	var CurrentYear = today.getYear();
	if ( gbIsFirefox || gbIsChrome || gbIsSafari || CurrentYear < 200 )
		CurrentYear += 1900;
	
	if ( min_year == undefined )
		min_year = CurrentYear - 100;
	if ( max_year == undefined )
	{
		max_year = CurrentYear - 7;
	}
	
	if (year < min_year || year > max_year) {
		alert("Date of Birth - Invalid date. Year must between " + min_year + " and " + max_year + ". Please re-enter it as " + format);
		highlightInputSection(input_obj, 4, 8, -4);
		return false;
	}
	if ( DateCmpToday(year, month, day, -1) > 0) {
		alert("Date of Birth - " + "Invalid date. Date must be one year prior to today!");
		highlightInput(input_obj);
		return false;
	}
	// Check data format
	var error_code = CheckValidDate(year, month, day, "Date of Birth - ", format);
	if ( error_code ) {
		if ( error_code == INVALID_MONTH )
			setSelectionRange(input_obj, 0, 2);
//			highlightInputSection(input_obj, 0, 2, 2);
		if ( error_code == INVALID_DAY )
			setSelectionRange(input_obj, 2, 4);
//			highlightInputSection(input_obj, 2, 4);
		if ( error_code == INVALID_YEAR )
			setSelectionRange(input_obj, 4, 8);
//			highlightInputSection(input_obj, 4, 8, -4);
		return false;
	}
	return true;
}
// ----------------------------------------------------------------------------------
//        SSN
// ----------------------------------------------------------------------------------
function fbi_ssn_check(input_obj, nullable)
{
	fbi_trim_input(input_obj);
	if (!fbi_null_check(input_obj, nullable, "Social Security Number"))
		return false;
	var s_ssn = input_obj.value;
	if (s_ssn == "" && nullable) return true;
	if (validate_string(s_ssn, DIGIT, 1) != VALID_OK)
	{
		alert("Social Security Number must contain only numberic characters. Please enter it again.");
		highlightInput(input_obj);
		return false;
	}
	if (s_ssn.length < 9) {
		alert("Social Security Number is 9 digits. Please verify the number.");
		highlightInput(input_obj);
		return false;
	}
	if ( s_ssn == "123456789" ||
		 s_ssn == "111111111" ||
		 parseInt(s_ssn, 10) <= 1010001 || 
		 s_ssn.substring(3,5) == "00" ||
		// s_ssn.substring(0,1) == "8" ||
		 s_ssn.substring(0,1) == "9"
		)
	{
		alert("Social Security Number is invalid. Please verify the number.");
		highlightInput(input_obj);
		return false;
	}
	
	return true;
}
// ----------------------------------------------------------------------------------
//        RETYPE VALUE (SSN, PSWD)
// ----------------------------------------------------------------------------------
function fbi_retype_check(input_obj, cmp_obj, title)
{
	if ( title == undefined ) title = "Retype value";
	if ( input_obj.value != cmp_obj.value ) {
		alert( title + " must match. Please enter it again." );
		highlightInput(input_obj);
		return false;
	}
	return true;
}
// ----------------------------------------------------------------------------------
//        WEIGHT
// ----------------------------------------------------------------------------------
function fbi_weight_check(input_obj, nullable, min, max, zeroable)
{
	fbi_trim_input(input_obj);
	if (!fbi_null_check(input_obj, nullable, "Weight"))
		return false;
	var s_weight = input_obj.value;
	if (s_weight == "" && nullable) return true;
	if (validate_string(s_weight, DIGIT, 1) != VALID_OK)
	{
		alert("Weight must contain only numberic characters. Please enter it again.");
		highlightInput(input_obj);
		return false;
	}
	if ( min == undefined ) min = 0;
	if ( max == undefined ) max = 499;
	if ( zeroable == undefined ) zeroable = true;
	var n_weight = Number(s_weight);
	// FBI: Weight "000" represents "Unknown"
	if ( !n_weight ) {
		if ( zeroable ) {
			input_obj.value = "000";
			return true;
		} else {
			alert("Weight cannot be 0.");
			highlightInput(input_obj);
			return false
		}
	}
	if ( n_weight < min || n_weight> max ) {
		alert("Weight must be between " + min + " and " + max + ".");
		highlightInput(input_obj);
		return false;
	}
	// Fill '0' at head to "000" format
	if (Number(s_weight) <100) {
		while(s_weight.length < 3)
			s_weight = "0" + s_weight;
		input_obj.value = s_weight;
	}
	return true;
}

// ----------------------------------------------------------------------------------
//        ADDRESS
// ----------------------------------------------------------------------------------
function fbi_address_check(input_obj, nullable, address_title)
{
	fbi_trim_upper_input(input_obj);
	if ( address_title == undefined )
		address_title = "Address";
	if (!fbi_null_check(input_obj, nullable, address_title))
		return false;
	var s_address = input_obj.value;
	if (s_address == "" && nullable) return true;
	if (validate_string(s_address, SET_ADDRESS, 1) != VALID_OK)
	{
		alert( address_title + " must contain only alpha-numeric characters. Blanks are also allowed." );
		highlightInput(input_obj);
		return false;
	}
	return true;
}

// ----------------------------------------------------------------------------------
//        CITY
// ----------------------------------------------------------------------------------
function fbi_city_check(input_obj, nullable, city_title)
{
	fbi_trim_upper_input(input_obj);
	if ( city_title == undefined )
		city_title = "City";
	if (!fbi_null_check(input_obj, nullable, city_title))
		return false;
	var s_address = input_obj.value;
	if (s_address == "" && nullable) return true;
	if (validate_string(s_address, SET_CITY, 1) != VALID_OK)
	{
		alert( city_title + " must contain only alphabetic characters or blanks." );
		highlightInput(input_obj);
		return false;
	}
	return true;
}

// ----------------------------------------------------------------------------------
//        ZIP
// ----------------------------------------------------------------------------------
function fbi_zip_check(input_obj, nullable, min_digit, max_digit, numeric_only)
{
	fbi_trim_input(input_obj);
	if (!fbi_null_check(input_obj, nullable, "Zip"))
		return false;
	if ( min_digit == undefined )
		min_digit = 5;
	if ( max_digit == undefined )
		max_digit = 5;
	if ( numeric_only == undefined )
		numeric_only = true;
	var s_zip = input_obj.value;
	if (s_zip == "" && nullable) return true;
	if ( s_zip.length < min_digit || s_zip.length > max_digit  )
	{
		if ( min_digit == max_digit )
			alert("The length of Zip Code must be " + min_digit + "." );
		else
			alert("The length of Zip Code is between " + min_digit + " and " + max_digit + ".");
		highlightInput(input_obj);
		return false;
	}
	if (numeric_only)
	{
		if (validate_string(s_zip, DIGIT, 1) != VALID_OK)
		{
			alert( "Zip Code must contain only numbers." );
			highlightInput(input_obj);
			return false;
		}
	}
	else
	{
		if (validate_string(s_zip, SET_ZIP, 1) != VALID_OK)
		{
			alert( "Zip Code must contain only numbers or -." );
			highlightInput(input_obj);
			return false;
		}
	}
	return true;
}

// ----------------------------------------------------------------------------------
//        EMAIL
// ----------------------------------------------------------------------------------
function fbi_email_check(input_obj, nullable)
{
	fbi_trim_input(input_obj);
	if (!fbi_null_check(input_obj, nullable, "Email Address"))
		return false;
	var s_email = input_obj.value;
	if (s_email == "" && nullable)
		return true;
	var res = validate_string(s_email, SET_EMAIL_INVALID, 0, FORM_EMAIL);
	if (res != VALID_OK)
	{
		if (res == RANEG_ERROR)
			alert("Email Address contains invalid character(s), please verify and try again.");
		else
			alert("Format of Email Address is invalid, please verify and try again.");
		highlightInput(input_obj);
		return false;
	}
	return true;
}

// ----------------------------------------------------------------------------------
//        PHONE
// ----------------------------------------------------------------------------------
function fbi_phone_check(input_obj, nullable, min_digit, max_digit)
{
	fbi_trim_input(input_obj);
	if (!fbi_null_check(input_obj, nullable, "Phone"))
		return false;
	if ( min_digit == undefined )
		min_digit = 7;
	if ( max_digit == undefined )
		max_digit = 10;
	var s_phone = input_obj.value;
	if (s_phone == "" && nullable) return true;
	if ( s_phone.length < min_digit || s_phone.length > max_digit  )
	{
		if ( min_digit == max_digit )
			alert("The length of Phone Number must be " + min_digit + "." );
		else
			alert("The length of Phone Number is between " + min_digit + " and " + max_digit + ".");
		highlightInput(input_obj);
		return false;
	}
	if (validate_string(s_phone, SET_PHONE_LETTERS, 1) != VALID_OK)
	{
		alert( "Phone number must contain only numbers, blanks or ()- ." );
		highlightInput(input_obj);
		return false;
	}
	return true;
}

// ----------------------------------------------------------------------------------
//        DLN
// ----------------------------------------------------------------------------------
function fbi_dln_check(input_obj, nullable, dln_title)
{
	fbi_trim_input(input_obj);
	if ( dln_title == undefined )
		dln_title = "Driver License";
	if (!fbi_null_check(input_obj, nullable, dln_title))
		return false;
	var s_address = input_obj.value;
	if (s_address == "" && nullable) return true;
	if (validate_string(s_address, SET_DLN, 1) != VALID_OK)
	{
		alert( dln_title + " must contain only alpha-numeric characters." );
		highlightInput(input_obj);
		return false;
	}
	return true;
}


// ******************************************************************** //
//       ACCESSORIAL FUNCTIONS
// ******************************************************************** //

// ----------------------------------------------------------------------------------
//        String Range Check
// ----------------------------------------------------------------------------------
function fbi_str_range_check(input_obj, nullable, range, title, msg)
{
	fbi_trim_input(input_obj);
	if (title == undefined)
		title = "Field";
	if (msg == undefined)
		msg = title + " contains invalid characters!";
	if (!fbi_null_check(input_obj, nullable, title))
		return false;
	var str = input_obj.value;
	var res = validate_string(str, range, CHECK_RANGE);
	if (res != VALID_OK)
	{
		alert(msg);
		highlightInput(input_obj);
		return false;
	}
	return true;
}

function fbi_str_invalid_range_check(input_obj, nullable, invalid_range, title, msg)
{
	fbi_trim_input(input_obj);
	if (title == undefined)
		title = "Field";
	if (msg == undefined)
		msg = title + " contains invalid characters!";
	if (!fbi_null_check(input_obj, nullable, title))
		return false;
	var str = input_obj.value;
	var res = validate_string(str, invalid_range, CHECK_INVALID_RANGE);
	if (res != VALID_OK)
	{
		alert(msg);
		highlightInput(input_obj);
		return false;
	}
	return true;
}
// ----------------------------------------------------------------------------------
//        String Format Check
// ----------------------------------------------------------------------------------
function fbi_str_format_check(input_obj, nullable, form, title, msg)
{
	fbi_trim_input(input_obj);
	if (title == undefined)
		title = "Name"
	if (!fbi_null_check(input_obj, nullable, title))
		return false;
	var s_full_name = input_obj.value;
	var res = validate_string(s_full_name, undefined, CHECK_RANGE, form);
	if (res != VALID_OK)
	{
		alert(msg);
		highlightInput(input_obj);
		return false;
	}
	return true;
}

function fbi_null_check(input_obj, nullable, title)
{
	if ( nullable == undefined ) nullable = false;
	if ( nullable ) return true;
	else if ( input_obj.value == "" )
	{
		if (title == undefined)
			alert("Please fill all the required fields.");
		else
			alert(title + " is a required field. Please provide a value.");
		highlightInput(input_obj);
		return false;
	}
	return true;
}
function fbi_no_select_check(input_obj, nullable, title, nvl)
{
	if ( nullable == undefined ) nullable = false;
	if ( nvl == undefined ) nvl = "";
	if ( input_obj.value == "" || input_obj.value == nvl ) {
		if (nullable) return true;
		else {
			alert( title + " is a required field. Please provide a value." );
			input_obj.focus();
			return false;
		}
	}
	return true;
}

// ----------------------------------------------------------------------------------
//        String Range Checking
// ----------------------------------------------------------------------------------
// ALPHA CHECKING
function fbi_string_alpha_only(_string)
{
	return (validate_string(_string, ALPHA, CHECK_RANGE) == VALID_OK);
}
function fbi_alpha_check(input_obj, nullable, title)
{
	fbi_trim_input(input_obj);
	if ( title == undefined )
		title = "Field";
	if (!fbi_null_check(input_obj, nullable, title))
		return false;
	var _str = input_obj.value;
	if (_str == "" && nullable) return true;
	if (!fbi_string_alpha_only(_str))
	{
		alert( title + " must contain only alphabetic characters." );
		highlightInput(input_obj);
		return false;
	}
	return true;
}
// ALPHA UPPERCASE CHECKING
function fbi_string_alpha_upper_only(_string)
{
	return (validate_string(_string, U_ALPHA, CHECK_RANGE) == VALID_OK);
}
function fbi_alpha_upper_check(input_obj, nullable, title)
{
	fbi_trim_input(input_obj);
	if ( title == undefined )
		title = "Field";
	if (!fbi_null_check(input_obj, nullable, title))
		return false;
	var _str = input_obj.value;
	if (_str == "" && nullable) return true;
	if (!fbi_string_alpha_upper_only(_str))
	{
		alert( title + " must contain only uppercase alphabetic characters." );
		highlightInput(input_obj);
		return false;
	}
	return true;
}
// ALPHA LOWERCASE CHECKING
function fbi_string_alpha_lower_only(_string)
{
	return (validate_string(_string, L_ALPHA, CHECK_RANGE) == VALID_OK);
}
function fbi_alpha_lower_check(input_obj, nullable, title)
{
	fbi_trim_input(input_obj);
	if ( title == undefined )
		title = "Field";
	if (!fbi_null_check(input_obj, nullable, title))
		return false;
	var _str = input_obj.value;
	if (_str == "" && nullable) return true;
	if (!fbi_string_alpha_lower_only(_str))
	{
		alert( title + " must contain only lowercase alphabetic characters." );
		highlightInput(input_obj);
		return false;
	}
	return true;
}
// NUMERIC CHECKING
function fbi_string_numeric_only(_string)
{
	return (validate_string(_string, DIGIT, CHECK_RANGE) == VALID_OK);
}
function fbi_numeric_check(input_obj, nullable, title)
{
	fbi_trim_input(input_obj);
	if ( title == undefined )
		title = "Field";
	if (!fbi_null_check(input_obj, nullable, title))
		return false;
	var _str = input_obj.value;
	if (_str == "" && nullable) return true;
	if (!fbi_string_numeric_only(_str))
	{
		alert( title + " must contain only digits." );
		highlightInput(input_obj);
		return false;
	}
	return true;
}
// ALPHA NUMERIC CHECKING
function fbi_string_alpha_numeric_only(_string)
{
	return (validate_string(_string, ALPHA_NUMERIC, CHECK_RANGE) == VALID_OK);
}
function fbi_alpha_numeric_check(input_obj, nullable, title)
{
	fbi_trim_input(input_obj);
	if ( title == undefined )
		title = "Field";
	if (!fbi_null_check(input_obj, nullable, title))
		return false;
	var _str = input_obj.value;
	if (_str == "" && nullable) return true;
	if (!fbi_string_alpha_numeric_only(_str))
	{
		alert( title + " must contain only alpha-numeric characters." );
		highlightInput(input_obj);
		return false;
	}
	return true;
}

// ----------------------------------------------------------------------------------
//        Date Operations
// ----------------------------------------------------------------------------------
function CheckValidDate(year, month, day, title, format)
{
	if (format == undefined || format != "YYYYMMDD")
		format = "MMDDYYYY";

	
	if ( title == undefined )
		title == "";
	if (month < 1 || month > 12) {
		alert( title + "Incorrect date format. Month must between 1 and 12. Please re-enter it as " + format );
		return INVALID_MONTH;
	}
	if (day < 1 || day > 31) {
		alert( title + "Incorrect date format. Day must between 1 and 31. Please re-enter it as " + format );
		return INVALID_DAY;
	}
	if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day > 31) {
		alert( title + "Incorrect date format. Date is not correct for the month. Please re-enter it as " + format );
		return INVALID_DAY;
	}
	else if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) {
		alert( title + "Incorrect date format. Date is not correct for the month. Please re-enter it as " + format );
		return INVALID_DAY;
	}
	else if (month == 2 && day > 29) {
		alert( title + "Incorrect date format. Date is not correct for month. Please re-enter it as " + format);
		return INVALID_DAY;
	}
	else if ( month == 2 && !isLeapYear(year) && day > 28 ) {
		alert( title + "Incorrect date format. " + year + " is not Leap Year, Feb 29 is invalid." );
		return INVALID_DAY;
	}
	return 0;
}
function DateCmpToday(year, month, day, nYearDiff, nMonthDiff, nDayDiff) {
	if ( nYearDiff == undefined )
		nYearDiff = 0;
	if ( nMonthDiff == undefined )
		nMonthDiff = 0;
	if ( nDayDiff == undefined )
		nDayDiff = 0;
	var bday = new Date();
	var today = new Date();
	bday.setFullYear(year - nYearDiff, month - 1 - nMonthDiff, day - nDayDiff);
	return ( bday > today );
}
function isLeapYear(year) {
	if ( year == undefined ) return false;
	if ( year % 400 == 0 ) return true;
	else if ( year % 100 == 0 ) return false;
	else if ( year % 4 == 0 ) return true;
	else return false
}

// ----------------------------------------------------------------------------------
//        Character Checking
// ----------------------------------------------------------------------------------
function isFirstLetterAlpha(str)
{
	return ( isAlphaLetter ( str.substr(0,1) ) );
}
function isLastLetterAlpha(str)
{
	return ( isAlphaLetter( str.substr(str.length-1,1) ) ); 
}
function isAlphaLetter(c)
{
	return ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) );
}
function isWithinLetterSet(str,dictionary)
{
	var alpha = "";
	if(str.length>1)
	{
		for(var j=0; j<str.length; j++)
		{
			alpha = isWithinLetterSet(str.substring(j, j+1), dictionary);
			if(!alpha) return alpha;
		}
		return alpha;
	}
	else
	{
		if(dictionary.indexOf(str) >= 0) return true;
		return false;
	}
}

// ----------------------------------------------------------------------------------
//        String Trim, Upper and Lower case
// ----------------------------------------------------------------------------------
function fbi_trim(inputString) {
	return inputString.replace(/^\s+|\s+$/g, '');
}
function fbi_upper(inputString) {
	return inputString.toUpperCase();
}
function fbi_lower(inputString) {
	return inputString.toLowerCase();
}
function fbi_trim_input(input_obj) {
	input_obj.value = fbi_trim(input_obj.value);
}
function fbi_upper_input(input_obj) {
	input_obj.value = fbi_upper(input_obj.value);
}
function fbi_lower_input(input_obj) {
	input_obj.value = fbi_lower(input_obj.value);
}
function fbi_trim_upper_input(input_obj) {
	input_obj.value = fbi_trim(input_obj.value);
	input_obj.value = fbi_upper(input_obj.value);
}
function fbi_trim_lower_input(input_obj) {
	input_obj.value = fbi_trim(input_obj.value);
	input_obj.value = fbi_lower(input_obj.value);
}

// ----------------------------------------------------------------------------------
//        Input event
// ----------------------------------------------------------------------------------
function highlightInput(obj)
{
	try
	{
		if ( obj == undefined ||
			 obj.disabled ||
			 obj.value == undefined )
			return;
		var o_TextRange = obj.createTextRange();
		o_TextRange.select();
	}
	catch(e){}
	try
	{
		obj.focus();
	}
	catch (e) {}
	return;
}


// ******************************************************************** //
//       BASIC FUNCTIONS
// ******************************************************************** //
function string_within_set(_str, _set)
{
	_set = "^" + _set;
	var _invalid_set = eval( "/[" + _set + "]/" );
	var b_contain_invalid_char = _str.match(_invalid_set);
	return !b_contain_invalid_char;
}
function string_contain_set(_str, _set)
{
	var _range = eval( "/[" + _set + "]/" );
	var b_contain_char = _str.match(_range);
	return b_contain_char;
}
function validate_string_range(str, char_range, valid_flag)
{
	var res = true;
	if ( valid_flag == undefined )
		valid_flag = CHECK_RANGE;
	if ( char_range != undefined )
	{
		if ( valid_flag == CHECK_RANGE )
			res = string_within_set(str, char_range);
		else
			res = !string_contain_set(str, char_range);
	}
	return res;
}
function validate_string_format(str, expression)
{
	if ( expression == undefined )
		return true;
	return str.match(expression);
}
function validate_string(str, char_range, valid_flag, expression)
{
	var res = true;
	res = validate_string_range(str, char_range, valid_flag);
	if ( !res || expression == undefined )
		return (res ? VALID_OK : RANEG_ERROR);
	res = validate_string_format(str, expression)
	return (res ? VALID_OK : FORM_ERROR);
}
function CheckNameString(str, title)
{
	if ( title == undefined || title == "" )
		title = "Name"
	if ( str.match("--") != null ) {
		alert( title + " can NOT contain consecutive hyphens." );
		return false;
	}
	if ( str.match("  ") != null ) {
		alert( title + " can NOT contain consecutive blanks." );
		return false;
	}
	if ( str.match("- ") != null || str.match(" -") != null ) {
		alert( title + " can NOT contain consecutive hyphens or blanks.");
		return false;
	}
	if ( str.match("-,") != null || str.match(",-") != null ) {
		alert( title + " can NOT contain consecutive comma or hyphens.");
		return false;
	}
	if ( !isFirstLetterAlpha(str) ) {
		alert( title + " must start with alpha character ('a'-'z' or 'A'-'Z').");
		return false;
	}
	if ( !isLastLetterAlpha(str) ) {
		alert( title + " must end with alpha character ('a'-'z' or 'A'-'Z').");
		return false;
	}
	if ( str.split("-").length - 1 > 1 ) {
		alert( title + " can NOT contain more than one hyphen.");
		return false;
	}
	if ( str.split(" ").length - 1 > 1 ) {
		alert( title + " can NOT contain more than one blank.");
		return false;
	}
	return true;
}
function fbi_CharType(ch)
{
	if ( ch >= 'a' && ch <= 'z' ) 
		return LOWER_CASE_LETTER;
	else if ( ch >= 'A' && ch <= 'Z' )
		return UPPER_CASE_LETTER;
	else if ( ch >= '0' && ch <= '9' )
		return NUMERIC_LETTER;
	else if ( ch == ',' )
		return COMMA_LETTER;
	else if ( ch == ' ' )
		return SPACE_LETTER;
	else if ( ch == '-' )
		return HYPHEN_LETTER;
	else 
		return SPECIAL_LETTER;
}
function highlightInputSection(obj, stt, edd, dir)
{
	var str_input = "";
	try
	{
		if ( obj == undefined ||
			 obj.disabled ||
			 obj.value == undefined )
			return;
		str_input = obj.value;
		if ( !str_input.length || stt >= edd ) {
			obj.focus();
			return;
		}
		if (stt == undefined || stt < 0 )
			stt = 0;
		if (edd == undefined || edd > str_input.length )
			edd = str_input.length;
		if (dir == undefined)
			dir = str_input.length;
		var o_TextRange = obj.createTextRange();
		var s_TextRange = str_input.substring(stt, edd);
		o_TextRange.findText(s_TextRange, dir);
		o_TextRange.select();
	} catch (e) {}
	try
	{
		obj.focus();
	}
	catch (e) {}
	
	return;
}
function setSelectionRange(input, selectionStart, selectionEnd)
{
	if (input.setSelectionRange) {
		input.focus();
		input.setSelectionRange(selectionStart, selectionEnd);
	}
	else if (input.createTextRange) {
		var range = input.createTextRange();
		range.collapse(true);
		range.moveEnd('character', selectionEnd);
		range.moveStart('character', selectionStart);
		range.select();
	}
}

