 /**************************************************************************/
 /* Health Plan Survey Site  (c) 2007 United Benefit Advisors, LLC         */
 /*                                                                        */
 /* file: www/validation.js                                       */
 /*                                                                        */
 /* developer: James Hartman                                               */
 /*                                                                        */
 /* Provides the engine to enforce validation rules in the survey
 /**************************************************************************/
 
////////////////////////////////////////////////////////////////////////////////
// Validates all severe validation rules for this page, returns true if all passed
//	dispalys error message if one or more fail
//
// Returns boolean, true if all validation rules passed
function validateSevere(plan_num) {
	if( document.getElementById('userDialog').style.display != 'none') {
		return false;
	}
	var returnValue = validateAll(plan_num, true, false, false, false);
	if ( !returnValue ) {
		alert( 'Please correct the errors on this page before moving on.');
	}
	return returnValue;
}

////////////////////////////////////////////////////////////////////////////////
// Validates all validation rules exculing activation rules for this page, returns true if all passed
//
//		checkSevere: boolean, validate severe errors
//		checkError: boolean, validate normal errors
//		checkRequired: boolean, validate required answers
//		checkWarning: boolean, validate warnings
// Returns boolean, true if all validation rules passed
function validateAll(plan_num, checkSevere, checkError, checkRequired, checkWarning) {
	var returnValue = true;

	for (var question_id in validation) {
		if (!validateQuestion(question_id, plan_num, checkSevere, checkError, checkRequired, checkWarning)) {
			returnValue = false;
		}
	}

	return returnValue;
}

////////////////////////////////////////////////////////////////////////////////
// Validates all validation rules exculing activation rules for given question, returns true if all passed
//
//		question_id: question id to validate
//		plan_num: plan number to validate
//		checkSevere: boolean, validate severe errors
//		checkError: boolean, validate normal errors
//		checkRequired: boolean, validate required answers
//		checkWarning: boolean, validate warnings
// Returns boolean, true if all validation rules passed
function validateQuestion(question_id, plan_num, checkSevere, checkError, checkRequired, checkWarning) {
	returnValue = true;
	setQuestionError(question_id, '');
	for (var field in validation[question_id]) {
		if (!validateAnswer(question_id, field, plan_num, checkSevere, checkError, checkRequired, checkWarning) ) {
			returnValue = false;
		}
	}
	return returnValue;
}


////////////////////////////////////////////////////////////////////////////////
// Validates all validation rules exculing activation rules for given answer, returns true if all passed
//
//		question_id: question id to validate
//		field: field name to validate
//		plan_num: plan number to validate
//		checkSevere: boolean, validate severe errors
//		checkError: boolean, validate normal errors
//		checkRequired: boolean, validate required answers
//		checkWarning: boolean, validate warnings
// Returns boolean, true if all validation rules passed
function validateAnswer(question_id, field, plan_num, checkSevere, checkError, checkRequired, checkWarning) {
	var returnValue = true;
	var ctl_error = false;
	setControlError(field,'');
	var values = getControlErrorIDs(question_id, field, plan_num, checkSevere, checkError, checkRequired, checkWarning);

	if (values.error_ids.length > 0) {
		setControlError(field, values.ErrorType);
		setQuestionError(question_id, values.ErrorType);
	}
	if (values.ErrorType == 'Severe' ) {
		return false;
	}
	return true;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// Validates one validation rule for a survey session, returns array of errors
//
//		rule:  array that defines a validation rule
//		plan_num:  plan number to check rule for
// Returns true if validation rule passes, false otherwise
function validateRule(rule, plan_num) {
	var validation_id = rule.FieldValidationID;
	var target_table = rule.TargetTable;
	var target_field = rule.TargetField;
	var validation_type = rule.ValidationType;
	var equation = rule.Equation;
	var parameter_list = rule.ParameterList;
	var error_on_pass = rule.ErrorOnPass;
	var response = trim(responses[target_table][plan_num][target_field]);

	switch (validation_type) {
		// activate
		case 'active if':
		case 'active if compare field is value':
		case 'active if custom':
		case 'active if custom support':
			// do nothing, handled elsewhere
			break;

		// required
		case 'required if':
			result = validateRequiredIf(equation);
			break;
		case 'required':
			result = validateRequired(response);
			break;
		case 'all or none required':
			result = validateAllOrNoneRequired(response, target_table, plan_num, parameter_list );
			break;
		case 'one required':
			result = validateOneRequired(response, target_table, parameter_list );
			break;
		case 'custom':
			result = validateCustom(response, target_table, target_field, validation_id);
			break;

		default:

			// check if response is blank

			if( String(response).length === 0) {
				if(error_on_pass == '1') {
					result = false;
				} else {
					result = true;
				}
			} else {

				switch (validation_type) {
					case 'assert':
						result = validateAssert(equation);
						break;
					case 'value range':
						result = validateValueRange(response, parameter_list);
						break;

					// text box only validation
					case 'number only':
						result = validateNumberOnly(response );
						break;
					case 'integer only':
						result = validateIntegerOnly(response );
						break;
					case 'text only':
						result = validateTextOnly(response );
						break;
					case 'email only':
						result = validateEmailOnly(response );
						break;
					case 'phone only':
						result = validatePhoneOnly(response );
						break;
					case 'max length':
						result = validateMaxLength(response, parameter_list );
						break;
					case 'min length':
						result = validateMinLength(response, parameter_list );
						break;
					case 'starts with field':
						result = validateStartsWithField(response, parameter_list, target_table, page_plan_num);
						break;

					default:
						alert('Validation Type: ' + validation_type + ' not denfined');
						break;
				}
			}
			break;
	}

	if (error_on_pass == '1'  ) {
		result = !result;
	}

	return result;
}


////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that all responses in a set contains a value or none do
//
//		response: value of the response that is being validated
//		compare_fields: array of fields to compare to
// Returns boolean, true if it passes
function validateAllOrNoneRequired(response, tbl, plan_num, parameter_list) {

	if (String(response).length === 0) {
		non_null_count = 0;
		null_count = 1;

		fields = splitString(parameter_list, ',');

		for(idx = 0; idx < fields.length; idx++ ) {
			f = getCompareField(fields[idx], tbl, plan_num);
			value = trim(String(responses[f.table][f.plan][f.field]));
			if( value.length > 0 ) {
				non_null_count++;
			} else {
				null_count++;
			}
		}

		if( null_count !== 0 && non_null_count !== 0 ) {
			return false;
		}
	}
	return true;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, response is active if equation is true
//
//		equations: string, full equation for this validation rule
// Returns boolean, true if it passes
function validateActiveIf(equations) {
	return evaluateEquations(equations);
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, response is active if certain conditions are met
//		question_id: question id to validate
//		tbl: table name of response
//		field: field name of response
// Returns boolean, true if it passes
function validateActiveIfCustom(question_id, tbl, field) {
	// find support
	for (var rule = 0; rule < validation[question_id][field].length; rule++) {
		if (validation[question_id][field][rule].ValidationType == 'active if custom support') {
			var equation = validation[question_id][field][rule].Equation;
			if (!validateActiveIf(equation)) {
				return false;
			}
		}
	}

	return false;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that the equation is true
//
//		equation: string, full equation of this validation rule
// Returns boolean, true if it passes
function validateAssert(equation) {
	return evaluateEquations(equation);
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys custom complex validation rules
//
//		tbl: table name of response
//		field: field name of response
//		validation_id: validation id from the fieldvalidation table
// Returns boolean, true if it passes
function validateCustom(response, tbl, field, validation_id) {
	//alert('Field: ' + field);
	if (field == 'NAICSMaster')
		return lookupNAICS(response);
		
	return true;
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that response is an email address, if answered
//
//		response: value of the response that is being validated
// Returns boolean, true if it passes
function validateEmailOnly(response) {
	if( String(response).length === 0) {
		return true;
	}
	var eml = /^([a-zA-Z0-9])+([a-zA-Z0-9_\-\.\+])*@([a-zA-Z0-9])+([a-zA-Z0-9_\-\.]+)*(\.)([a-zA-Z0-9_\-\.])([a-zA-Z0-9_\-])+$/;
	return response.match(eml);
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that response is numeric, if answered
//
//		$response: value of the response that is being validated
// Returns boolean, true if it passes
function validateIntegerOnly(response) {
	if ( String(response).length === 0) {
		return true;
	}
	return isInt(response);
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that response has less than or equal to maximum length, if answered
//
//		response: value of the response that is being validated
//		max_length: array of values to compare to
// Returns boolean, true if it passes
function validateMaxLength(response, max_length) {
	if ( String(response).length > max_length ) {
		return false;
	}
	return true;
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that response has minimum length, if answered
//
//		$response: value of the response that is being validated
//		$compare_values: array of values to compare to
// Returns boolean, true if it passes
function validateMinLength(response, min_length) {
	if ( String(response).length > 0 && response.length < min_length ) {
		return false;
	}
	return true;
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that response is numeric, if answered
//
//		response: value of the response that is being validated
// Returns boolean, true if it passes
function validateNumberOnly(response) {
	if ( String(response).length === 0 ) {
		return true;
	}
	return is_numeric(response);
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that at least one response out of set of required responses contains a value
//
//		response: value of the response that is being validated
//		parameter_list: array of fields to compare to
// Returns boolean, true if it passes
function validateOneRequired(response, tbl, parameter_list) {
	if( String(response).length === 0) {
		var fields = splitString(parameter_list, ',');
		var non_null_count = 0;
		for( var idx = 0; idx < fields.length; idx++ ) {
			f = getCompareField(fields[idx], tbl, page_plan_num);
			value = trim(responses[f.table][f.plan][f.field]);
			if( value.length > 0 ) {
				non_null_count++;
				break;
			}
		}

		if (non_null_count === 0) {
			return false;
		}
	}
	return true;
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that response is a 10 digit phone number, if answered
//
//		response: value of the response that is being validated
// Returns boolean, true if it passes
function validatePhoneOnly(response) {
	if( String(response).length === 0) {
		return true;
	}
	var regex = '^[(]{0,1}[2-9][0-9]{2}[) -.]{0,2}[0-9]{3}[- .]{0,1}[0-9]{4}$';
	return response.match(regex);
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that a required response contains a value
//
//		response: value of the response that is being validated
// Returns boolean, true if it passes
function validateRequired(response) {
	if (String(response).length === 0) {
		return false;
	}
	return true;
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that a required response contains a value if certain conditions are met
//
//		response: value of the response that is being validated
//		equation: array of equations in the form '[fieldname] == 1; [filedname2] == null, 0'
// Returns boolean, true if it passes
function validateRequiredIf(response, equations) {
	// check if required
	if (!evaluateEquations(equations) ) {
		return true;
	}
	// check if blank
	return validateRequired(response);
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that response starts with another response, if answered
//
//		response: value of the response that is being validated
//		compare_fields: array of fields to compare to
// Returns boolean, true if it passes
function validateStartsWithField(response, parameter_list, tbl, plan_num) {
	if (String(response).length === 0) {
		return true;
	}

	var f = getCompareField(parameter_list, tbl, plan_num );
	var compare_value = trim(String(responses[f.table][f.plan][f.field]));

	return String(response).match(new RegExp('^' + compare_value ));
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that response has no numbers
//
//		response: value of the response that is being validated
// Returns boolean, true if it passes
function validateTextOnly(response) {
	if( String(response).length === 0) {
		return true;
	}

	var regex = /([0-9])/;
	return !response.match(regex);
}

////////////////////////////////////////////////////////////////////////////////
// Checks validation rule, verifys that response is in value range(s), if answered
//
//		response: value of the response that is being validated
//		parameter_list: array of values to compare to of the form '1, 10; 20, 30'
// Returns boolean, true if it passes
function validateValueRange(response, parameter_list) {
	if( String(response).length > 0 && is_numeric(response) ) {
		var groups = splitString(parameter_list, ';');
		var match_count = 0;
		for( var idx = 0; idx < groups.length; idx++) {
			var values = splitString(groups[idx], ',');
			var low = values[0];
			var high = values[1];
			if (parseFloat(String(response).replace(',', '') ) >= parseFloat(low) && (high == '?' || parseFloat(String(response).replace(',', '')) <= parseFloat(high)) ) {
				match_count++;
				break;
			}
		}

		if( match_count === 0 ) {
			return false;
		}
	}
return true;
}

////////////////////////////////////////////////////////////////////////////////
// Returns the numeric value of a response and properly negates certain values
//
//		tbl: table name of response
//		field: field name of response
//		plan_num: plan number of response
// Returns field value of negitive of field value
function getFieldValue( tbl, field, plan_num ) {
	if (tbl.charAt(0) == '-') {
		return -1 * getFieldValue( tbl.substr(1), field, plan_num );
	}
	if(responses[tbl]) {
		if (responses[tbl][plan_num]) {
			return 0.0 + parseFloat(String(responses[tbl][plan_num][field]).replace(',', ''));
		} else {
			alert('Response not defined for plan: ' + tbl + '; ' + plan_num + '; ' + field );
		}
	} else {
		alert('Response not defined for table: ' + tbl + '; ' + plan_num + '; ' + field );
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////////
//  Given a string of the form table.field:plan where table and plan are optional, returns an array of table field plan
//
//	fieldStr:  string in the form table.field:plan where table and plan are optional
//	target_table:  optional, default table if no table is given in fieldstr
//	plan_num:  optional, default plan number if no plan number is given in fieldstr 
//
// returns array of table, field, and plan
function getCompareField(fieldStr, target_table, plan_num) {
	var temp_field;
	var table;
	
	fieldStr = fieldStr.replace(']','').replace('[','');
	if (fieldStr.indexOf('.') > 0) {
		temp_field = splitString(fieldStr, '.');
		table = temp_field[0];
		temp_field = temp_field[1] ;
	} else {
		table = target_table;
		temp_field = fieldStr;
	}
	temp_field = splitString(temp_field, ':');
	var field = temp_field[0];
	var plan = temp_field[1];
	if( !plan || plan.length === 0) {
		plan = plan_num;
	}
	return {'table' : trim(table), 'field' : trim(field), 'plan' : trim(plan) };
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// Evaluates an equation to true or false
//
//	equations:  full equation from a validation rule
//	responses:  array of response data
//
// returns true if equation evaluates to true, false otherwise
function evaluateEquations(equations) {
	var euqationArray = splitString(equations, '||');
	for ( var idx = 0; idx < euqationArray.length; idx++ ) {
		if( evaluateEquationGroup(euqationArray[idx]) ) {
			return true;
		}
	}
	return false;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
//  Evaluates a part of a validation rule equation, full equation has already been split into groups by ||
//
//	equations:	partial equation from a validation rule
//
//	returns true if this piece of the equation is true, false otherwise
function evaluateEquationGroup(equations) {
	var equationArray = splitString(equations, ';');
	for( var idx = 0; idx < equationArray.length; idx++ ) {
		var equation = equationArray[idx];
		if( !evaluateEquation(equation) ) {
			return false;
		}
	}
	return true;
}


//////////////////////////////////////////////////////////////////////////////////////////////////
// Evaluates a part of a validation rule equation, full equation has already been split into groups by || and ;
//
//	equation: partial equation from a validation rule, does not handle AND or OR logic
//
//	returns true if this piece of the equation is true, false otherwise
function evaluateEquation(equation) {
	if(!equation) {return true;}

	var arr = extractEquationElements(equation);
	var leftSide = extractValue(arr.left);
	var comparer = arr.comparer;
	var rightSide = extractValue(arr.right);

	switch (comparer) {
		case '==':
			return evaluateEquationAdvanced(leftSide, rightSide);
		case '!==':
			return !evaluateEquationAdvanced(leftSide, rightSide);
	}

	return evaluateEquationNumber(leftSide, comparer, rightSide);
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// Evaluates a number based part of an equation
//
//	leftSide:  number or field on left side of comparer
//	comparer: =, <, >, !=, <=, or >=
//	rightSide:  number or field on right side of comparer
//
// returns true if piece of equation evalutes to true, false otherwise
function evaluateEquationNumber(leftSide, comparer, rightSide) {
	leftSide = parseFloat(ifNullOrBlank(extractValue(leftSide),0));
	rightSide = parseFloat(ifNullOrBlank(extractValue(rightSide),0));

	switch(comparer) {
		case '=':
			if ( leftSide != rightSide ) { return false; }
			break;
		case '!=':
			if ( leftSide == rightSide ) { return false; }
			break;
		case '>':
			if ( leftSide <= rightSide ) { return false; }
			break;
		case '<':
			if ( leftSide >= rightSide ) { return false; }
			break;
		case '<=':
			if ( leftSide > rightSide ) { return false; }
			break;
		case '>=':
			if ( leftSide < rightSide ) { return false; }
			break;
		default:
			return false;
	}
	return true;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
//  Evaluates a string based comparison of part of a validation rule equation
//
//	leftSide:  number or field on left side of comparer
//	rightSide:  number or field on right side of comparer
//
// returns true if piece of equation evalutes to true, false otherwise
function evaluateEquationAdvanced(leftSide, rightSide) {
	var leftSideValue = extractValue(leftSide);
	if (!leftSideValue) {
		leftSideValue = '';
	}
	leftSideValue = trim(String(leftSideValue));

	// split right side
	var rightSideElements = splitString(rightSide, ',');

	// compare each value
	for( var idx = 0; idx < rightSideElements.length; idx++ ) {
		var rightSideValue = extractValue(rightSideElements[idx]);
		if( leftSideValue == trim(rightSideValue)	|| (trim(rightSideValue) == 'null' && leftSideValue.length === 0) || (trim(rightSideValue) == '!null' && leftSideValue.length !== 0)  ) {
			return true;
		}
	}
	return false;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// splits an equation into what is before the first comparer, the comparer, and what is after the comparer
//
//	equation:  part of a validation equation
//
// returns array of left, right, and comparer
function extractEquationElements(equation) {
	var arr = [];

	arr.comparer = extractComparer(equation);
	var comparerIdx = equation.indexOf(arr.comparer);

	arr.left = trim(equation.substr(0, comparerIdx));
	arr.right = trim(equation.substr(comparerIdx + 2).replace('=', '' ));

	return arr;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
//  Finds the first comparer in the equation
//
//	equation:  part of a validation rule equation
//
// returns =, <, >, !=, <=, >=, ==, or !==
function extractComparer(equation) {
	idx = String(equation).indexOf('!==');
	if (idx >= 0) {return '!==';}
	idx = String(equation).indexOf('==');
	if (idx >= 0) {return '==';}
	idx = String(equation).indexOf('>=');
	if (idx >= 0) {return '>=';}
	idx = String(equation).indexOf('<=');
	if (idx >= 0) {return '<=';}
	idx = String(equation).indexOf('!=');
	if (idx >= 0) {return '!=';}
	idx = String(equation).indexOf('>');
	if (idx >= 0) {return '>';}
	idx = String(equation).indexOf('<');
	if (idx >= 0) {return '<';}
	idx = String(equation).indexOf('=');
	if (idx >= 0) {return '=';}
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// Gets the value of part of an equation, including simple math
//
//	equationElement:  part of a validation rule equation, including field names, numbers, and operators
//
//  Returns the value (string or number) of 
function extractValue(equationElement) {
	if(!equationElement) { return; }
	// is there math?
	var operator_idx = findOperator(equationElement);
	var operator = String(equationElement).charAt(operator_idx);	
	
	if (operator_idx >= 0) {
		// do math
		var leftSide = trim(equationElement.substr(0, operator_idx));
		var rightSide = trim(equationElement.substr(operator_idx + 2));
		if (operator == '+') {
			return parseFloat(ifNullOrBlank(extractValue(leftSide),0)) + parseFloat(ifNullOrBlank(extractValue(rightSide),0));
		} else {
			return parseFloat(ifNullOrBlank(extractValue(leftSide),0)) * parseFloat(ifNullOrBlank(extractValue(rightSide),0));
		}
	}

	// is there a field name?
	if (String(equationElement).indexOf('[') >= 0 ) {
		// get field value

		return extractFieldValue(equationElement);
	}
	return equationElement;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// Gets the value of a response, adds together all plans if * is used
//
//	fieldname:  string of the form table.field:plan
//
// returns the value of the field
function extractFieldValue(fieldname) {
	var field = getCompareField(fieldname);
	if (field.plan == '*') {
		var total = 0;
		for ( var plan_num in responses[field.table] ) {
			temp = getFieldValue(field.table, field.field, plan_num );
			total += ifNullOrBlank(temp,0);
		}
		return total;
	}
	if (responses[field.table] && responses[field.table][field.plan] && responses[field.table][field.plan][field.field]) {
		return responses[field.table][field.plan][field.field];
	} else {
		return '';
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// Finds the index of + or * that are not in brackets
//
//  equation:  full of partial validation rule equation
//
// returns index of + or * that are not in brackets or -1 if not found
function findOperator(equation) {
	var operator_idx = 0;
	var open_brace_idx = String(equation).indexOf('[');
	var close_brace_idx = String(equation).indexOf(']');
	var equationStr = String(equation);

	for( var idx = 0; idx < equationStr.length; idx++ ) {
		var ch = equationStr.charAt(idx);
		if (ch == '+') {
			return idx;
		}
		if (ch == '*' && (idx < open_brace_idx || idx > close_brace_idx)) {
			return idx;
		}
	}

}


//////////////////////////////////////////////////////////////////////////////////////////////////
// Adds table and plan information to an equation of a validation rule.  
// This information is optional when defining a rule but needs to be present to evalute the equation
//
//		plan_num:  plan number of this page
//
// Returns nothing
function prepareValidationRules(plan_num) {
	for (var question_id in validation) {
		for (var target_fieldname in validation[question_id]) {
			for (var idx in validation[question_id][target_fieldname]) {
				prepareValidationRule(question_id, target_fieldname, idx, plan_num);
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// Adds table and plan information to an equation of a validation rule.  
// This information is optional when defining a rule but needs to be present to evalute the equation
//
//		question_id: id of question
//		target_fieldname:  target field name of rule
//		rule_idx:  which rule in this rule array
//		plan_num:  plan number of this page
//
// Returns nothing
function prepareValidationRule(question_id, target_fieldname, rule_idx, plan_num) {
	// add target field to validate rule, this is done so that rule can be used apart from array
	validation[question_id][target_fieldname][rule_idx].TargetField = target_fieldname;

	var rule = validation[question_id][target_fieldname][rule_idx];
	var equation = rule.Equation;

	if (equation ) {
		idx = equation.indexOf('[', 0);
		while( idx >= 0 && idx < equation.length ) {
			compare_fieldname = equation.substr(idx, equation.indexOf(']', idx)- idx + 1);
			field = getCompareField(compare_fieldname, rule.TargetTable, plan_num);
			equation = equation.replace(compare_fieldname, '[' + field.table + '.' + field.field + ':' + field.plan + ']');
			idx = equation.indexOf('[', idx + 1);
		}
		validation[question_id][target_fieldname][rule_idx].Equation = equation;
	}
}

////////////////////////////////////////////////////////////////////////////////
// Returns compare value as float
//		compare_value: value to convert
//		tbl: not used
//		plan: not used
// Returns compare value as float
function getCompareValue(compare_value, tbl, plan) {
	return parseFloat(trim(String(compare_value)).replace(',', ''));
}

//////////////////////////////////////
//Compatibility functions

//////////////////////////////////////////////////////////////////////////////////////////////////
// Returns the given value unless it is null or blank, then it returns valueIfNull
//
//	value: value to return if not null and not blank
//	valueIfNull:  value to return if first value is null or blank
//
// Returns $value or $valueIfNull
function ifNullOrBlank(val, valueIfNull) {
	if (!val || val === '' || isNaN(val) ) {
		return valueIfNull;
	}
	return val;
}

////////////////////////////////////////////////////////////////////////////////
// Trims spaces at the begining and end of the input string
//
//		s: string to trim
// Returns trimmed input string
function trim(s){
	if (!s) {
		return '';
	}
	if( typeof s == 'string' ) {
		s = s.replace(/\s+$/, '');
		s = s.replace(/^\s+/, '');
	}
	return s;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// Splits a string into a array using the given delimiter
//
//	str:  string to split
//	delimiter:  character to split string at
//
// returns array
function splitString(str, delimiter) {
	if (!str) {
		return [];
	}
	return String(str).split(delimiter);
}

////////////////////////////////////////////////////////////////////////////////
// Checks if input string is numeric
//
//		str: string to check
// Returns boolean, true if input is numeric
function is_numeric(str) {
   var ValidChars = '0123456789.,';
   var IsNumber = true;
   var Char;

   for (var i = 0; i < str.length; i++) {
      Char = str.charAt(i);
      if (ValidChars.indexOf(Char) == -1) {
      	if(i === 0 && Char == '-') {
      		continue;
      	} else {
         	IsNumber = false;
         	break;
         }
		}
	}
	return IsNumber;
}

////////////////////////////////////////////////////////////////////////////////////
function lookupNAICS(response) {
	var client = false;

	if (response == undefined)
		return true;
		
	var naics_code = response.toString().replace(/^\s+|\s+$/g,"");
	
	if(naics_code.length != 6) {
		var dv = document.getElementById("naicsLookup");
		if (dv) {
			dv.innerHTML = "";
			dv.style.color = "black";
		}
		return true;
	}

	var webAddress = "/validate_naics.php?naics_code=" + URLEncode(naics_code) + "&format=text";
  if(window.XMLHttpRequest /*&& !(window.ActiveXObject)*/) {
  	try {
			client = new XMLHttpRequest();
    } catch(e) {
			client = false;
    }
  // branch for IE/Windows ActiveX version
  } else if(window.ActiveXObject) {
   	try {
    	client = new ActiveXObject("Msxml2.XMLHTTP");
  	} catch(e) {
    	try {
    		client = new ActiveXObject("Microsoft.XMLHTTP");
    	} catch(e) {
    		client = false;
    	}
		}
  }
//alert('after creating the XMLHttpRequest object');  
	if(client) {
		client.open("GET", webAddress, false);
		client.send(null);

		var dv = document.getElementById("naicsLookup");
		
		if(client.status == 200 && client.responseText != null) {

			if(client.responseText.substr(0,2) == "??") {
				if (dv)
					dv.innerHTML = '';
				return false;
			}
			else if(client.responseText == 0) {
				if (dv)
					dv.innerHTML = '';
				return false;
			} else {
				if (dv) {
					dv.style.color = 'black';
					dv.innerHTML = client.responseText;
				}
				return true;
			}
		}
	}
	else
		return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////
function URLEncode (clearString) {
  var output = '';
  var x = 0;
  clearString = clearString.toString();
  var regex = /(^[a-zA-Z0-9_.]*)/;
  while (x < clearString.length) {
    var match = regex.exec(clearString.substr(x));
    if (match != null && match.length > 1 && match[1] != '') {
    	output += match[1];
      x += match[1].length;
    } else {
      if (clearString[x] == ' ')
        output += '+';
      else {
        var charCode = clearString.charCodeAt(x);
        var hexVal = charCode.toString(16);
        output += '%' + ( hexVal.length < 2 ? '0' : '' ) + hexVal.toUpperCase();
      }
      x++;
    }
  }
  return output;
}

