// form.js (Website Framework) || Version: 1.16 || Last Updated: 2010-06-29 8:30 || Updated by: Jelle Kingma || Created: 2008-04-16 by Hidde-Finne Peters
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------
//	1.04:	Added "required" condition (only ready for use input "radio" so far)
//	1.04:	Added comments
//	1.04:	Changed condition "emailFormat" to declare empty values as valid (in case email is not required)
//	1.05:	Added functionality that enables to add fields trough js (see below), and no longer requires adding event listeners in every field
//	1.06:	Added functionality that automatically adds fields to "check list" by reading out "conditions"
//	1.07:	Added auto insert tooltip-image script, so tooltip images do not have to be placed in contact view
//	1.08:	Changed insert tooltip-image script so image url can be set in contact view and thus easily changed per website
//	1.09:	Changed className management. Automatically changes last characters of className into _valid or _invalid. Now supports different classnames for for fields, no longer support _default. 
//	1.10:	Added className management for "support styling", for example a div that needs to change it's display based on valid or invalid value of a specific field
//	1.11:	Added initializeForm() function and added functionality for submitImage
//	1.12:	Adjusted script to work with imageButton.js (changed submitImage functionality)
//	1.13:	Added automatic "onload" handling (requires onLoad.js)
//	1.14:	Made changes to ensure script works without tooltips (might not function correctly anymore with presence of tooltips)
//	1.15:	Changed script to function correctly when added in head (main template)
//	1.16:	JQuery blur and keyup event
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------

var conditions = null;							//	1.15
var tooltipImageUrl = null;						//	1.14
var ToolTip = null;								//	1.14

//	----

function hasRequiredValue (condition) {
	var form = document.getElementById(condition[2]);
	var formField = eval('form.'+ condition[0]);
	for (i = 0; i < formField.length; i++) {
		if (formField[i].checked) {
			return true;
		}
	}
	return false;
}

function hasMinChars (value, chars) {
	if (value.length < chars) {
		return false;
	} else {
		return true;
	}
}

function numbersOnly (value) {
	if (!value.match(/^\d+$/))	{
		return false;
	} else {
		return true;
	}
}

function lettersOnly (value) {
	if (value.length > 0) {
		for (var i = 0; i < value.length; i++) {
			if (value[i]) {
				if (value[i].match(/^\d+$/)) {
					return false;	
				}
			}
		}
		return true;
	}
	return false;
}

function isEmailFormat (str) {
	//	Empty string is valid (ensures this condition can be applied to fields that do not require values)
	if (str.length < 1) {
		return true;	
	}
	//	If value has length the format needs to be valid
	if (str.length > 6) {
		//	Length is sufficient
		var atIndex = str.indexOf("@");
		if (atIndex > 0) {
			//	@ is valid
			var dotIndex = str.indexOf(".", atIndex);
			if (dotIndex - atIndex > 2) {
				//	Enough characters between @ and .
				if ((str.length - 2) > dotIndex) {
					//	Enough characters after .
					//	If it gets here the string must be good
					return true;
				}
			}
		}
	}
	return false;			
}

function conditionValid (condition) {
	var formField = document.getElementById(condition[0]);
	var value = formField.value;
	if (value != null) {
		var conditionType = condition[1];
		var conditionParam = condition[2];
		switch (conditionType) {
			case 'minChars':
				return hasMinChars(value, conditionParam);
				break;
			case 'emailFormat':
				return isEmailFormat(value);
				break;
			case 'numbersOnly':
				return numbersOnly(value);
				break;
			case 'lettersOnly':
				return lettersOnly(value);
				break;
			case 'isChecked':
				//	Specially designed for "checkfield".
				return formField.checked;
				break;
			case 'required':
				//	Specially designed for "radio".
				return hasRequiredValue(condition);
				break;
		}
	}
	//	Condition processing failed, return valid;
	return true;
}

//
//	1.09:	Changed className management. Automatically changes last characters of className into _valid or _invalid. Now supports different classnames for for fields, no longer support _default. 
//	1.10	Added className management for "support styling", for example a div that needs to change it's display based on valid or invalid value of a specific field

function updateDisplayValid (condition, valid) {
	//	----------------------------------------------------------------
	//	General preperation
	//	----------------------------------------------------------------
	var inputId = condition[0];
	var formField = document.getElementById(inputId);
	//	----------------------------------------------------------------
	//	Valid
	//	----------------------------------------------------------------
	if (valid) {
		//	----------------------------------------------------------------
		//	ClassName
		//	----------------------------------------------------------------
		var oldClassName = formField.className;
		if (oldClassName.substr(oldClassName.length - 8, 8) == '_invalid') {
			formField.className = oldClassName.substr(0, oldClassName.length - 8) +'_valid';
		}
		//	----------------------------------------------------------------
		//	Support ClassName
		//	----------------------------------------------------------------
		var supportElement = document.getElementById(inputId +'_support');
		if (supportElement) {
			var oldSupportClassName = supportElement.className;
			if (oldSupportClassName.substr(oldSupportClassName.length - 8, 8) == '_invalid') {
				supportElement.className = oldSupportClassName.substr(0, oldSupportClassName.length - 8) +'_valid';
			}
		}
		//	----------------------------------------------------------------
		//	Tooltip
		//	----------------------------------------------------------------
		var tooltipBox = document.getElementById(inputId +'_tooltipBox');
		if (tooltipBox) {
			tooltipBox.style.display = 'none';
		}
		//	----------------------------------------------------------------
	//	----------------------------------------------------------------
	//	Invalid
	//	----------------------------------------------------------------
	} else {
		//	----------------------------------------------------------------
		//	ClassName
		//	----------------------------------------------------------------
		var oldClassName = formField.className;
		if (oldClassName.substr(oldClassName.length - 6, 6) == '_valid') {
			formField.className = oldClassName.substr(0, oldClassName.length - 6) +'_invalid';
		}
		//	----------------------------------------------------------------
		//	Support ClassName
		//	----------------------------------------------------------------
		var supportElement = document.getElementById(inputId +'_support');
		if (supportElement) {
			var oldSupportClassName = supportElement.className;
			if (oldSupportClassName.substr(oldSupportClassName.length - 6, 6) == '_valid') {
				supportElement.className = oldSupportClassName.substr(0, oldSupportClassName.length - 6) +'_invalid';
			}
		}
		//	----------------------------------------------------------------
		//	Tooltip
		//	----------------------------------------------------------------
		var tooltip = document.getElementById(inputId +'_tooltip');
		var feedback = condition[3];
		if (tooltip) {
			tooltip.setAttribute('tip', feedback);
		}
		var tooltipBox = document.getElementById(inputId +'_tooltipBox');
		if (tooltipBox) {
			tooltipBox.style.display = 'block';
		}
		//	----------------------------------------------------------------
	}
}

function hasInvalidField (invalidFields, condition) {
	for (var i = 0; i < invalidFields.length; i++) {
		if (invalidFields[i] == condition[0]) {
			return true;	
		}
	}
	return false
}

//	Accessed directly on focusIn or focusOut to check a specific field. Will also check entire form to update the "submit button".
function checkField (conditions, fieldName, handleInvalid) {
	//	Only proceed if conditions and fieldName are set
	if (conditions && fieldName) {
		//	Walk trough conditions
		for (var i = 0; i < conditions.length; i++) {
			//	Find every condition relating to field
			if (conditions[i][0] == fieldName) {
				//	Found a relating condition
				var condition = conditions[i];
				//	Check the condition
				if (!conditionValid(condition)) {
					//	Field value does not meet condition.
					//	If handleInvalid is set as true, update the view (show tooltip etc.). If handleInvalid is false or not set, the false condition result is not automaticcaly shown.
					if (handleInvalid) {
						updateDisplayValid(condition, false);
					}
					//	Check all conditions on all fields to update general status (submit button enabled / disabled)
					checkForm(conditions);
					//	Field value is invalid, no need to check more conditions, return false.
					return false;
				}
			}
		}
		//	Check if at least one condition was processed (if none, not need to update anything)
		if (condition) {
			//	At least one condition has been processed and not given a false result (if multiple conditions are set on one field "condition" is the last processed condition.
			//	Update the view (hide tooltip etc.)
			updateDisplayValid(condition, true);
			//	Check all conditions on all fields to update general status (submit button enabled / disabled)
			checkForm(conditions);
			//	Field is valid, nothing left to do, return true;
			return true;
		}
	}
}

function checkForm (conditions) {
	var invalidFields = new Array();
	for (var i = 0; i < conditions.length; i++) {
		var condition = conditions[i];
		if (!hasInvalidField(invalidFields, condition)) {
			var valid = conditionValid(condition);
			if (!valid) {
				//	Condition is not valid
				invalidFields.push(conditions[i][0]);
			}
		}
	}
	//	spam check
	var spam_check_field = document.getElementById('spam_check_passed');
	if (spam_check_field) {
		spam_check_field.value = 'true';	
	}
	//	submitButton
	var submitButton = document.getElementById('submitButton');
	var submitImage = document.getElementById('submitImage_button');
	if (invalidFields.length == 0) {
		//	Enable form button
		if (submitButton) {
			submitButton.disabled = false;
		}
		if (submitImage) {
			//submitImage.src = 'site_images/send_default.gif';
			submitImage.src = submitImage.src.replace(new RegExp('_disabled\\b'), '_default');
			submitImage.style['cursor'] = 'pointer';
		}
	} else {
		//	Disable form button
		if (submitButton) {
			submitButton.disabled = true;
		}
		if (submitImage) {
			submitImage.src = submitImage.src.replace(new RegExp('_default\\b'), '_disabled');
			submitImage.src = submitImage.src.replace(new RegExp('_over\\b'), '_disabled');
			//submitImage.src = 'site_images/send_disabled.gif';
			submitImage.style['cursor'] = 'auto';
		}
	}
}

//----------------------------------------------------------------------
//--- 1.05 -------------------------------------------------------------
//----------------------------------------------------------------------

//	Checks field and changes view accordingly to conditions result
function handleChange (evt) {
	if (evt) {
		//	Firefox a.o.
		var fieldName = evt.target.name;
	} else {
		//	IE
		var fieldName = window.event.srcElement.name;
	}
	checkField(conditions, fieldName, true);
}

//	Does check field and changes view if it changes from invalid to valid but does not change view to invalid.
function handleKeyUp (evt) {
	if (evt) {
		//	Firefox a.o.
		var fieldName = evt.target.name;
	} else {
		//	IE
		var fieldName = window.event.srcElement.name;
	}
	checkField(conditions, fieldName, false);
}

//	Adds listeners to field so that it validates itself and the whole form (requires jquery)
function addField (fieldName) {
	var field = document.getElementById(fieldName);
	if (field) {
		$(field).keyup(handleChange);								//	1.16:	Requires JQuery
		$(field).blur(handleChange);								//	1.16:	Requires JQuery
	}
}

//----------------------------------------------------------------------
//------------------------------------------------------------- 1.05 ---
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//--- 1.06 -------------------------------------------------------------
//----------------------------------------------------------------------
//	1.07:	Added auto insert image script, so tooltip images do not have to be placed in contact view
//	1.08:	Changed insert tooltip-image script so image url can be set in contact view and thus easily changed per website

function containsValue (array, value) {
	for (var i = 0; i < array.length; i++) {
		if (array[i] == value) {
			return true;
		}
	}
	return false;
}


function addFields () {
	var fieldNames = new Array();
	for (var i = 0; i < conditions.length; i++) {
		var fieldName = conditions[i][0];
		if (!containsValue(fieldNames, fieldName)) {
			fieldNames.push(fieldName);
			//	Execute init
			addField(fieldName);
			//
			if (tooltipImageUrl) {
				var tooltipContainer = document.getElementById(fieldName +'_tooltipBox');
				if (tooltipContainer) {
					tooltipContainer.innerHTML = '<img id="'+ fieldName +'_tooltip" src="'+ tooltipImageUrl +'" title="'+ conditions[i][3] +'" />';
				}
			}
			//
		}
	}
}

//----------------------------------------------------------------------
//------------------------------------------------------------- 1.06 ---
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//--- 1.11 -------------------------------------------------------------
//----------------------------------------------------------------------
//	1.11:	Added functionality for submitImage.

function allValid () {
	for (var i = 0; i < conditions.length; i++) {
		if (!conditionValid(conditions[i])) {
			return false;
		}
	}
	return true;
}

function handleSubmitImageMouseOver (evt) {
	if (allValid()) {
		if (evt) {
			//	Firefox a.o.
			var target = evt.target;
		} else {
			//	IE
			var target = window.event.srcElement;
		}
		target.src = 'site_images/send_over.gif';
	}
}

function handleSubmitImageMouseOut (evt) {
	if (allValid()) {
		if (evt) {
			//	Firefox a.o.
			var target = evt.target;
		} else {
			//	IE
			var target = window.event.srcElement;
		}
		target.src = 'site_images/send_default.gif';
	}
}

function handleSubmitImageClick (evt) {
	if (allValid()) {
		var form = document.getElementById('form');
		form.submit();
	}
}

function prepareSubmitImage () {
	var submitImage = document.getElementById('submitImage_button');
	if (submitImage) {
		//submitImage.onmouseover = handleSubmitImageMouseOver;
		//submitImage.onmouseout = handleSubmitImageMouseOut;
		submitImage.onclick = handleSubmitImageClick;
		checkForm(conditions);
		//"this.src = 'site_images/send_over.gif';" onmouseout="this.src = 'site_images/send_default.gif';" 
	}
}

//	1.11:	Added initializeForm() function

function initializeForm (evt) {
	if (conditions) {							//	1.15:	Only initialize if conditions is array (are set)
		addFields();
		prepareSubmitImage();
		if (ToolTip) {
			ToolTip.init();
		}
	}
}

//----------------------------------------------------------------------
//------------------------------------------------------------- 1.11 ---
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//--- 1.13 -------------------------------------------------------------
//----------------------------------------------------------------------
//	initialize the script after load

addLoadEvent(initializeForm);

//----------------------------------------------------------------------
//------------------------------------------------------------- 1.15 ---
//----------------------------------------------------------------------
